View Javadoc

1   /*
2    * $Id: MuleContextLifecycleTestCase.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.context;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.MuleException;
15  import org.mule.api.context.MuleContextBuilder;
16  import org.mule.api.context.notification.MuleContextNotificationListener;
17  import org.mule.api.lifecycle.Disposable;
18  import org.mule.api.lifecycle.Initialisable;
19  import org.mule.api.lifecycle.LifecycleException;
20  import org.mule.api.lifecycle.Startable;
21  import org.mule.api.lifecycle.Stoppable;
22  import org.mule.api.security.SecurityManager;
23  import org.mule.config.builders.DefaultsConfigurationBuilder;
24  import org.mule.context.notification.MuleContextNotification;
25  import org.mule.lifecycle.MuleContextLifecycleManager;
26  import org.mule.util.UUID;
27  import org.mule.util.queue.QueueManager;
28  
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.List;
32  import java.util.concurrent.atomic.AtomicBoolean;
33  import java.util.concurrent.atomic.AtomicReference;
34  
35  import org.junit.Before;
36  import org.junit.Test;
37  import org.mockito.Mockito;
38  
39  import static org.junit.Assert.assertEquals;
40  import static org.junit.Assert.assertFalse;
41  import static org.junit.Assert.assertNotNull;
42  import static org.junit.Assert.assertSame;
43  import static org.junit.Assert.assertTrue;
44  import static org.mule.tck.MuleAssert.assertTrue;
45  
46  public class MuleContextLifecycleTestCase 
47  {
48      private MuleContextBuilder ctxBuilder;
49      private SensingLifecycleManager lifecycleManager;
50      
51      @Before
52      public void setup() throws Exception
53      {
54          ctxBuilder = new DefaultMuleContextBuilder();
55          lifecycleManager = new SensingLifecycleManager();
56          ctxBuilder.setLifecycleManager(lifecycleManager);
57      }
58      
59      //
60      // Initialize
61      //
62      @Test
63      public void initaliseSuccessful() throws Exception
64      {
65          MuleContext ctx = ctxBuilder.buildMuleContext();
66          assertFalse(ctx.isInitialised());
67          assertFalse(ctx.isInitialising());
68          assertFalse(ctx.isStarted());
69          assertFalse(ctx.isDisposed());
70          assertFalse(ctx.isDisposing());
71  
72          ctx.initialise();
73          assertTrue(ctx.isInitialised());
74          assertFalse(ctx.isInitialising());
75          assertFalse(ctx.isStarted());
76          assertFalse(ctx.isDisposed());
77          assertFalse(ctx.isDisposing());
78      }
79  
80      @Test(expected=IllegalStateException.class)
81      public void initialiseOnInitialised() throws MuleException
82      {
83          MuleContext ctx = ctxBuilder.buildMuleContext();
84          ctx.initialise();
85  
86          // Can't call twice
87          ctx.initialise();
88      }
89      
90      @Test(expected=IllegalStateException.class)
91      public void initialiseOnStarted() throws Exception
92      {
93          MuleContext ctx = ctxBuilder.buildMuleContext();
94          ctx.initialise();
95          new DefaultsConfigurationBuilder().configure(ctx);
96          ctx.start();
97  
98          // Attempt to initialise once started should fail!
99          ctx.initialise();
100     }
101 
102     @Test(expected=IllegalStateException.class)
103     public void initialiseOnStopped() throws Exception
104     {
105         MuleContext ctx = ctxBuilder.buildMuleContext();
106         ctx.initialise();
107         new DefaultsConfigurationBuilder().configure(ctx);
108         ctx.start();
109         ctx.stop();
110         
111         // Attempt to initialise once stopped should fail!
112         ctx.initialise();
113     }
114 
115     @Test(expected=IllegalStateException.class)
116     public void initialiseOnDisposed() throws Exception
117     {
118         MuleContext ctx = ctxBuilder.buildMuleContext();
119         ctx.initialise();
120         new DefaultsConfigurationBuilder().configure(ctx);
121         ctx.start();
122         ctx.stop();
123         ctx.dispose();
124 
125         // Attempt to initialise once disposed should fail!
126         ctx.initialise();
127     }
128 
129     //
130     // Start
131     //    
132     @Test(expected=IllegalStateException.class)
133     public void startBeforeInitialise() throws Exception
134     {
135         MuleContext ctx = ctxBuilder.buildMuleContext();
136         ctx.start();
137     }
138     
139     @Test
140     public void startOnInitialised() throws Exception
141     {
142         MuleContext ctx = ctxBuilder.buildMuleContext();
143         ctx.initialise();
144         
145         new DefaultsConfigurationBuilder().configure(ctx);
146         NotificationListener listener = new NotificationListener();
147         ctx.registerListener(listener);
148         ctx.start();
149         
150         assertTrue(ctx.isInitialised());
151         assertFalse(ctx.isInitialising());
152         assertTrue(ctx.isStarted());
153         assertFalse(ctx.isDisposed());
154         assertFalse(ctx.isDisposing());
155 
156         assertTrue("CONTEXT_STARTING notification never fired", listener.startingNotificationFired);
157         assertTrue("CONTEXT_STARTED notification never fired", listener.startedNotificationFired);
158     }
159 
160     @Test(expected=IllegalStateException.class)
161     public void startOnStarted() throws Exception
162     {
163         MuleContext ctx = ctxBuilder.buildMuleContext();
164         ctx.initialise();
165         
166         new DefaultsConfigurationBuilder().configure(ctx);
167         NotificationListener listener = new NotificationListener();
168         ctx.registerListener(listener);
169         ctx.start();
170 
171         assertTrue("CONTEXT_STARTING notification never fired", listener.startingNotificationFired);
172         assertTrue("CONTEXT_STARTED notification never fired", listener.startedNotificationFired);
173         
174         // Can't call twice
175         ctx.start();
176     }
177 
178     @Test
179     public void startOnStopped() throws Exception
180     {
181         MuleContext ctx = ctxBuilder.buildMuleContext();
182         ctx.initialise();
183         new DefaultsConfigurationBuilder().configure(ctx);
184         ctx.start();
185 
186         ctx.stop();
187         ctx.start();
188         assertTrue(ctx.isInitialised());
189         assertFalse(ctx.isInitialising());
190         assertTrue(ctx.isStarted());
191         assertFalse(ctx.isDisposed());
192         assertFalse(ctx.isDisposing());
193     }
194 
195     @Test(expected=IllegalStateException.class)
196     public void startOnDisposed() throws Exception
197     {
198         MuleContext ctx = ctxBuilder.buildMuleContext();
199         ctx.initialise();
200         ctx.dispose();
201         
202         // Attempt to start once disposed should fail!
203         ctx.start();
204     }
205     
206     //
207     // Stop
208     //
209     @Test(expected=IllegalStateException.class)
210     public void stopBeforeInitialise() throws Exception
211     {
212         MuleContext ctx = ctxBuilder.buildMuleContext();
213 
214         // Attempt to stop before initialise should fail!
215         ctx.stop();
216     }
217  
218     @Test(expected=IllegalStateException.class)
219     public void stopOnInitialised() throws Exception
220     {
221         MuleContext ctx = ctxBuilder.buildMuleContext();
222         ctx.initialise();
223         
224         // cannot stop if not started
225         ctx.stop();
226     }
227     
228     @Test
229     public void stopOnStarted() throws Exception
230     {
231         MuleContext ctx = buildStartedMuleContext();
232         
233         ctx.stop();
234         assertTrue(ctx.isInitialised());
235         assertFalse(ctx.isInitialising());
236         assertFalse(ctx.isStarted());
237         assertFalse(ctx.isDisposed());
238         assertFalse(ctx.isDisposing());
239     }
240     
241     @Test(expected=IllegalStateException.class)
242     public void stopOnStopped() throws Exception
243     {
244         MuleContext ctx = buildStartedMuleContext();
245         ctx.stop();
246         
247         // Can't call twice
248         ctx.stop();
249     }
250     
251     @Test(expected=IllegalStateException.class)
252     public void stopOnDisposed() throws Exception
253     {
254         MuleContext ctx = buildStartedMuleContext();
255         ctx.stop();
256         ctx.dispose();
257         
258         // Attempt to stop once disposed should fail!
259         ctx.stop();
260     }
261 
262     //
263     // Dispose
264     //
265     @Test
266     public void disposeBeforeInitialised()
267     {
268         MuleContext ctx = ctxBuilder.buildMuleContext();
269         ctx.dispose();
270         assertFalse(ctx.isInitialised());
271         assertFalse(ctx.isInitialising());
272         assertFalse(ctx.isStarted());
273         assertTrue(ctx.isDisposed());
274         assertFalse(ctx.isDisposing());
275         
276         assertLifecycleManagerDidApplyPhases(Disposable.PHASE_NAME);
277     }
278     
279     @Test
280     public void disposeOnInitialised() throws Exception
281     {
282         MuleContext ctx = ctxBuilder.buildMuleContext();
283         ctx.initialise();
284         ctx.dispose();
285         assertFalse(ctx.isInitialised());
286         assertFalse(ctx.isInitialising());
287         assertFalse(ctx.isStarted());
288         assertTrue(ctx.isDisposed());
289         assertFalse(ctx.isDisposing());
290         
291         assertLifecycleManagerDidApplyPhases(Initialisable.PHASE_NAME, Disposable.PHASE_NAME);
292     }
293     
294     @Test
295     public void disposeOnStarted() throws Exception
296     {
297         MuleContext ctx = ctxBuilder.buildMuleContext();
298         ctx.initialise();
299         new DefaultsConfigurationBuilder().configure(ctx);
300         final NotificationListener listener = new NotificationListener();
301         ctx.registerListener(listener);
302 
303         ctx.start();
304         ctx.dispose();
305         assertFalse(ctx.isInitialised());
306         assertFalse(ctx.isInitialising());
307         assertFalse(ctx.isStarted());
308         assertTrue(ctx.isDisposed());
309         assertFalse(ctx.isDisposing());
310 
311         // disposing started must go through stop
312         assertLifecycleManagerDidApplyAllPhases();
313 
314         assertTrue("CONTEXT_STOPPING notification never fired", listener.stoppingNotificationFired.get());
315         assertTrue("CONTEXT_STOPPED notification never fired", listener.stoppedNotificationFired.get());
316     }
317     
318     @Test
319     public void disposeOnStopped() throws Exception
320     {
321         MuleContext  ctx = ctxBuilder.buildMuleContext();
322         ctx.initialise();
323         new DefaultsConfigurationBuilder().configure(ctx);
324         ctx.start();
325         ctx.stop();
326         ctx.dispose();
327         assertFalse(ctx.isInitialised());
328         assertFalse(ctx.isInitialising());
329         assertFalse(ctx.isStarted());
330         assertTrue(ctx.isDisposed());
331         assertFalse(ctx.isDisposing());
332         
333         assertLifecycleManagerDidApplyAllPhases();
334     }
335     
336     @Test(expected=IllegalStateException.class)
337     public void disposeOnDisposed() throws Exception
338     {
339         MuleContext ctx = ctxBuilder.buildMuleContext();
340         ctx.initialise();
341         ctx.dispose();
342         
343         // can't call twice
344         ctx.dispose();
345     }
346 
347     @Test
348     public void notificationHasMuleContextRef() throws Exception
349     {
350         MuleContext ctx = ctxBuilder.buildMuleContext();
351         ctx.initialise();
352         new DefaultsConfigurationBuilder().configure(ctx);
353         
354         final AtomicReference<MuleContext> contextFromNotification = new AtomicReference<MuleContext>();
355         final AtomicReference<String> resourceId = new AtomicReference<String>();
356         MuleContextNotificationListener<MuleContextNotification> listener = 
357             new MuleContextNotificationListener<MuleContextNotification>()
358         {
359             public void onNotification(MuleContextNotification notification)
360             {
361                 contextFromNotification.set(notification.getMuleContext());
362                 resourceId.set(notification.getResourceIdentifier());
363             }
364         };
365         ctx.registerListener(listener);
366         ctx.start();
367 
368         assertNotNull(contextFromNotification.get());
369         assertSame(ctx, contextFromNotification.get());
370         assertEquals(ctx.getConfiguration().getId(), resourceId.get());
371     }
372 
373     private MuleContext buildStartedMuleContext() throws Exception
374     {
375         MuleContext ctx = ctxBuilder.buildMuleContext();
376         ctx.initialise();
377     
378         // DefaultMuleContext refuses to start without these objects in place
379         SecurityManager securityManager = Mockito.mock(SecurityManager.class);
380         ctx.getRegistry().registerObject(UUID.getUUID(), securityManager);
381         
382         QueueManager queueManager = Mockito.mock(QueueManager.class);
383         ctx.getRegistry().registerObject(UUID.getUUID(), queueManager);
384         
385         ctx.start();
386         return ctx;
387     }
388 
389     private void assertLifecycleManagerDidApplyPhases(String... phaseNames)
390     {
391         assertTrue(lifecycleManager.didApplyPhases(phaseNames));
392     }
393     
394     private void assertLifecycleManagerDidApplyAllPhases()
395     {
396         assertLifecycleManagerDidApplyPhases(
397             Initialisable.PHASE_NAME,
398             Startable.PHASE_NAME,
399             Stoppable.PHASE_NAME,
400             Disposable.PHASE_NAME);
401     }
402 
403     private static class SensingLifecycleManager extends MuleContextLifecycleManager
404     {
405         private List<String> appliedLifecyclePhases;
406         
407         public SensingLifecycleManager()
408         {
409             super();
410             appliedLifecyclePhases = new ArrayList<String>();
411         }
412 
413         public boolean didApplyPhases(String... phaseNames)
414         {
415             List<String> expectedPhases = Arrays.asList(phaseNames);
416             return expectedPhases.equals(appliedLifecyclePhases);
417         }
418 
419         @Override
420         public void fireLifecycle(String phase) throws LifecycleException
421         {
422             appliedLifecyclePhases.add(phase);
423             super.fireLifecycle(phase);
424         }
425     }
426     
427     static class NotificationListener implements MuleContextNotificationListener<MuleContextNotification>
428     {
429         final AtomicBoolean startingNotificationFired = new AtomicBoolean(false);
430         final AtomicBoolean startedNotificationFired = new AtomicBoolean(false);
431         final AtomicBoolean stoppingNotificationFired = new AtomicBoolean(false);
432         final AtomicBoolean stoppedNotificationFired = new AtomicBoolean(false);
433 
434         public void onNotification(MuleContextNotification notification)
435         {
436             switch (notification.getAction())
437             {
438                 case MuleContextNotification.CONTEXT_STARTING: 
439                     startingNotificationFired.set(true); 
440                     break;
441                     
442                 case MuleContextNotification.CONTEXT_STARTED: 
443                     startedNotificationFired.set(true); 
444                     break;
445                     
446                 case MuleContextNotification.CONTEXT_STOPPING: 
447                     stoppingNotificationFired.set(true); 
448                     break;
449                     
450                 case MuleContextNotification.CONTEXT_STOPPED: 
451                     stoppedNotificationFired.set(true); 
452                     break;
453             }
454         }
455     }
456 }