1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.event;
21  
22  
23  import org.apache.directory.server.core.DirectoryService;
24  import org.apache.directory.server.core.integ.CiRunner;
25  import static org.apache.directory.server.core.integ.IntegrationUtils.getSystemContext;
26  import static org.junit.Assert.assertEquals;
27  import org.junit.Test;
28  import org.junit.runner.RunWith;
29  
30  import javax.naming.NamingException;
31  import javax.naming.directory.Attribute;
32  import javax.naming.directory.Attributes;
33  import javax.naming.directory.BasicAttribute;
34  import javax.naming.directory.BasicAttributes;
35  import javax.naming.directory.SearchControls;
36  import javax.naming.event.EventDirContext;
37  import javax.naming.event.NamespaceChangeListener;
38  import javax.naming.event.NamingEvent;
39  import javax.naming.event.NamingExceptionEvent;
40  import javax.naming.event.ObjectChangeListener;
41  
42  import java.util.ArrayList;
43  import java.util.EventObject;
44  import java.util.List;
45  
46  
47  /**
48   * Test cases for the event service.
49   *
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   * @version $Rev: 691024 $
52   */
53  @RunWith ( CiRunner.class )
54  public class EventServiceIT
55  {
56      public static DirectoryService service;
57  
58  
59      /**
60       * Test to make sure NamingListener's are no longer registered
61       * after they are removed via the EventContex.removeNamingListener method.
62       *
63       * @throws NamingException on failures
64       */
65      @Test
66      public void testRemoveNamingListener() throws Exception
67      {
68          TestListener listener = new TestListener();
69          EventDirContext ctx = ( EventDirContext ) getSystemContext( service ).lookup( "" );
70          ctx.addNamingListener( "", SearchControls.SUBTREE_SCOPE, listener );
71          Attributes testEntry = new BasicAttributes( "ou", "testentry", true );
72          Attribute objectClass = new BasicAttribute( "objectClass", "top" );
73          objectClass.add( "organizationalUnit" );
74          testEntry.put( objectClass );
75          ctx.createSubcontext( "ou=testentry", testEntry );
76  
77          //  Wait 1 second, as the process is asynchronous
78          Thread.sleep( 1000 );
79  
80          assertEquals( 1, listener.getEventRecords().size() );
81          EventRecord rec = ( EventRecord ) listener.getEventRecords().get( 0 );
82          assertEquals( "objectAdded", rec.method );
83          assertEquals( ctx, rec.event.getSource() );
84  
85          ctx.removeNamingListener( listener );
86          ctx.destroySubcontext( "ou=testentry" );
87  
88          //  Wait 1 second, as the process is asynchronous
89          Thread.sleep( 1000 );
90  
91          assertEquals( 1, listener.getEventRecords().size() );
92          rec = ( EventRecord ) listener.getEventRecords().get( 0 );
93          assertEquals( "objectAdded", rec.method );
94          assertEquals( ctx, rec.event.getSource() );
95  
96          // read the entry once again just to make sure
97          ctx.createSubcontext( "ou=testentry", testEntry );
98          
99          //  Wait 1 second, as the process is asynchronous
100         Thread.sleep( 1000 );
101 
102         assertEquals( 1, listener.getEventRecords().size() );
103         rec = ( EventRecord ) listener.getEventRecords().get( 0 );
104         assertEquals( "objectAdded", rec.method );
105         assertEquals( ctx, rec.event.getSource() );
106     }
107 
108 
109     /**
110      * Test to make sure NamingListener's are no longer registered
111      * after the context used for registration is closed.
112      *
113      * @throws NamingException on failures
114      */
115     @Test
116     public void testContextClose() throws Exception
117     {
118         TestListener listener = new TestListener();
119         EventDirContext ctx = ( EventDirContext ) getSystemContext( service ).lookup( "" );
120         ctx.addNamingListener( "", SearchControls.SUBTREE_SCOPE, listener );
121         Attributes testEntry = new BasicAttributes( "ou", "testentry", true );
122         Attribute objectClass = new BasicAttribute( "objectClass", "top" );
123         objectClass.add( "organizationalUnit" );
124         testEntry.put( objectClass );
125         ctx.createSubcontext( "ou=testentry", testEntry );
126 
127         //  Wait 1 second, as the process is asynchronous
128         Thread.sleep( 1000 );
129 
130         assertEquals( 1, listener.getEventRecords().size() );
131         EventRecord rec = ( EventRecord ) listener.getEventRecords().get( 0 );
132         assertEquals( "objectAdded", rec.method );
133         assertEquals( ctx, rec.event.getSource() );
134 
135         ctx.close();
136         ctx = ( EventDirContext ) getSystemContext( service ).lookup( "" );
137         ctx.destroySubcontext( "ou=testentry" );
138 
139         //  Wait 1 second, as the process is asynchronous
140         Thread.sleep( 1000 );
141 
142         assertEquals( 1, listener.getEventRecords().size() );
143         rec = ( EventRecord ) listener.getEventRecords().get( 0 );
144         assertEquals( "objectAdded", rec.method );
145 
146         // readd the entry once again just to make sure
147         ctx.createSubcontext( "ou=testentry", testEntry );
148         
149         //  Wait 1 second, as the process is asynchronous
150         Thread.sleep( 1000 );
151 
152         assertEquals( 1, listener.getEventRecords().size() );
153         rec = ( EventRecord ) listener.getEventRecords().get( 0 );
154         assertEquals( "objectAdded", rec.method );
155     }
156 
157     
158     public class TestListener implements ObjectChangeListener, NamespaceChangeListener
159     {
160         List<EventRecord> events = new ArrayList<EventRecord>();
161 
162 
163         public List<EventRecord> getEventRecords()
164         {
165             return events;
166         }
167 
168 
169         public void objectChanged( NamingEvent event )
170         {
171             events.add( new EventRecord( "objectChanged", event ) );
172         }
173 
174 
175         public void namingExceptionThrown( NamingExceptionEvent event )
176         {
177             events.add( new EventRecord( "namingExceptionThrown", event ) );
178         }
179 
180 
181         public void objectAdded( NamingEvent event )
182         {
183             events.add( new EventRecord( "objectAdded", event ) );
184         }
185 
186 
187         public void objectRemoved( NamingEvent event )
188         {
189             events.add( new EventRecord( "objectRemoved", event ) );
190         }
191 
192 
193         public void objectRenamed( NamingEvent event )
194         {
195             events.add( new EventRecord( "objectRenamed", event ) );
196         }
197     }
198 
199     public class EventRecord
200     {
201         String method;
202         EventObject event;
203 
204 
205         EventRecord(String method, EventObject event)
206         {
207             this.method = method;
208             this.event = event;
209         }
210     }
211 }