1   /*
2    * $Id: ServerNotificationsTestCase.java 11181 2008-03-05 17:31:34Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.management;
12  
13  import org.mule.api.context.notification.ServiceNotificationListener;
14  import org.mule.api.context.notification.CustomNotificationListener;
15  import org.mule.api.context.notification.MuleContextNotificationListener;
16  import org.mule.api.context.notification.ModelNotificationListener;
17  import org.mule.api.context.notification.ServerNotification;
18  import org.mule.context.notification.ServiceNotification;
19  import org.mule.context.notification.CustomNotification;
20  import org.mule.context.notification.MuleContextNotification;
21  import org.mule.context.notification.ModelNotification;
22  import org.mule.tck.AbstractMuleTestCase;
23  import org.mule.tck.testmodels.fruit.Apple;
24  
25  import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
26  import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
27  import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
28  import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
29  
30  public class ServerNotificationsTestCase extends AbstractMuleTestCase
31          implements ModelNotificationListener, MuleContextNotificationListener
32  {
33  
34      private final AtomicBoolean managerStopped = new AtomicBoolean(false);
35      private final AtomicInteger managerStoppedEvents = new AtomicInteger(0);
36      private final AtomicBoolean modelStopped = new AtomicBoolean(false);
37      private final AtomicInteger componentStartedCount = new AtomicInteger(0);
38      private final AtomicInteger customNotificationCount = new AtomicInteger(0);
39  
40      public ServerNotificationsTestCase()
41      {
42          setStartContext(true);
43      }
44      
45      // @Override
46      protected void doTearDown() throws Exception
47      {
48          managerStopped.set(true);
49          managerStoppedEvents.set(0);
50      }
51  
52      public void testStandardNotifications() throws Exception
53      {
54          muleContext.registerListener(this);
55          muleContext.stop();
56          assertTrue(modelStopped.get());
57          assertTrue(managerStopped.get());
58      }
59  
60      public void testMultipleRegistrations() throws Exception
61      {
62          muleContext.registerListener(this);
63          muleContext.registerListener(this);
64          muleContext.stop();
65          assertTrue(managerStopped.get());
66          assertEquals(2, managerStoppedEvents.get());
67      }
68  
69      public void testUnregistering() throws Exception
70      {
71          muleContext.registerListener(this);
72          muleContext.unregisterListener(this);
73          muleContext.stop();
74          // these should still be false because we unregistered ourselves
75          assertFalse(modelStopped.get());
76          assertFalse(managerStopped.get());
77      }
78  
79      public void testMismatchingUnregistrations() throws Exception
80      {
81          // this has changed in 2.x.  now, unregistering removes all related entries
82          muleContext.registerListener(this);
83          DummyListener dummy = new DummyListener();
84          muleContext.registerListener(dummy);
85          muleContext.registerListener(dummy);
86          muleContext.unregisterListener(dummy);
87          muleContext.stop();
88  
89          assertTrue(managerStopped.get());
90          assertEquals(1, managerStoppedEvents.get());
91      }
92  
93      public void testStandardNotificationsWithSubscription() throws Exception
94      {
95          final CountDownLatch latch = new CountDownLatch(1);
96          muleContext.registerListener(new ServiceNotificationListener()
97          {
98              public void onNotification(ServerNotification notification)
99              {
100                 if (notification.getAction() == ServiceNotification.SERVICE_STARTED)
101                 {
102                     componentStartedCount.incrementAndGet();
103                     assertEquals("component1", notification.getResourceIdentifier());
104                     latch.countDown();
105                 }
106             }
107         }, "component1");
108 
109         getTestService("component2", Apple.class);
110         getTestService("component1", Apple.class);
111 
112 
113         // Wait for the notifcation event to be fired as they are queued
114         latch.await(20000, TimeUnit.MILLISECONDS);
115         assertEquals(1, componentStartedCount.get());
116     }
117 
118     public void testStandardNotificationsWithWildcardSubscription() throws Exception
119     {
120         final CountDownLatch latch = new CountDownLatch(2);
121 
122         muleContext.registerListener(new ServiceNotificationListener()
123         {
124             public void onNotification(ServerNotification notification)
125             {
126                 if (notification.getAction() == ServiceNotification.SERVICE_STARTED)
127                 {
128                     componentStartedCount.incrementAndGet();
129                     assertFalse("noMatchComponent".equals(notification.getResourceIdentifier()));
130                     latch.countDown();
131                 }
132             }
133         }, "component*");
134 
135         //Components automatically get registered
136         getTestService("component2", Apple.class);
137         getTestService("component1", Apple.class);
138         getTestService("noMatchComponent", Apple.class);
139 
140         // Wait for the notifcation event to be fired as they are queued
141         latch.await(2000, TimeUnit.MILLISECONDS);
142         assertEquals(2, componentStartedCount.get());
143     }
144 
145     public void testCustomNotifications() throws Exception
146     {
147         final CountDownLatch latch = new CountDownLatch(2);
148 
149         muleContext.registerListener(new DummyNotificationListener()
150         {
151             public void onNotification(ServerNotification notification)
152             {
153                 if (notification.getAction() == DummyNotification.EVENT_RECEIVED)
154                 {
155                     customNotificationCount.incrementAndGet();
156                     assertEquals("hello", notification.getSource());
157                     latch.countDown();
158                 }
159             }
160         });
161 
162         muleContext.fireNotification(new DummyNotification("hello", DummyNotification.EVENT_RECEIVED));
163         muleContext.fireNotification(new DummyNotification("hello", DummyNotification.EVENT_RECEIVED));
164 
165         // Wait for the notifcation event to be fired as they are queued
166         latch.await(2000, TimeUnit.MILLISECONDS);
167         assertEquals(2, customNotificationCount.get());
168     }
169 
170     public void testCustomNotificationsWithWildcardSubscription() throws Exception
171     {
172 
173         final CountDownLatch latch = new CountDownLatch(2);
174 
175         muleContext.registerListener(new DummyNotificationListener()
176         {
177             public void onNotification(ServerNotification notification)
178             {
179                 if (notification.getAction() == DummyNotification.EVENT_RECEIVED)
180                 {
181                     customNotificationCount.incrementAndGet();
182                     assertFalse("e quick bro".equals(notification.getResourceIdentifier()));
183                     latch.countDown();
184                 }
185             }
186         }, "* quick brown*");
187 
188         muleContext.fireNotification(new DummyNotification("the quick brown fox jumped over the lazy dog",
189                                                                  DummyNotification.EVENT_RECEIVED));
190         muleContext.fireNotification(new DummyNotification("e quick bro", DummyNotification.EVENT_RECEIVED));
191         muleContext.fireNotification(new DummyNotification(" quick brown", DummyNotification.EVENT_RECEIVED));
192 
193         // Wait for the notifcation event to be fired as they are queued
194         latch.await(20000, TimeUnit.MILLISECONDS);
195         assertEquals(2, customNotificationCount.get());
196     }
197 
198     public void onNotification(ServerNotification notification)
199     {
200         if (notification.getAction() == ModelNotification.MODEL_STOPPED)
201         {
202             modelStopped.set(true);
203         }
204         else
205         {
206             if (notification.getAction() == MuleContextNotification.CONTEXT_STOPPED)
207             {
208                 managerStopped.set(true);
209                 managerStoppedEvents.incrementAndGet();
210             }
211         }
212     }
213 
214     public static interface DummyNotificationListener extends CustomNotificationListener
215     {
216         // no methods
217     }
218 
219     public class DummyNotification extends CustomNotification
220     {
221         /**
222          * Serial version
223          */
224         private static final long serialVersionUID = -1117307108932589331L;
225 
226         public static final int EVENT_RECEIVED = -999999;
227 
228         public DummyNotification(String message, int action)
229         {
230             super(message, action);
231             resourceIdentifier = message;
232         }
233     }
234 }