View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.email.functional;
8   
9   import static org.junit.Assert.assertEquals;
10  
11  import org.mule.api.MuleEventContext;
12  import org.mule.api.endpoint.InboundEndpoint;
13  import org.mule.api.lifecycle.Callable;
14  import org.mule.construct.SimpleFlowConstruct;
15  import org.mule.tck.probe.PollingProber;
16  import org.mule.tck.probe.Probe;
17  import org.mule.transport.email.GreenMailUtilities;
18  import org.mule.transport.email.ImapConnector;
19  import org.mule.transport.email.RetrieveMessageReceiver;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.concurrent.CountDownLatch;
24  
25  import javax.mail.internet.MimeMessage;
26  
27  import org.junit.Test;
28  
29  /**
30   * Tests the correct undeployment of an application with an IMAP inbound endpoint. This test is related to MULE-6737.
31   */
32  public class ImapUndeployTestCase extends AbstractEmailFunctionalTestCase
33  {
34  
35      private static final int NUMBER_OF_MESSAGES = 2;
36      private static int numberOfProcessedMessages = 0;
37  
38      private static final CountDownLatch disposeLatch = new CountDownLatch(1);
39      private static final CountDownLatch mailProcessorLatch = new CountDownLatch(1);
40  
41      public ImapUndeployTestCase()
42      {
43          super(STRING_MESSAGE, "imap", "imap-undeploy-test.xml");
44      }
45  
46      protected void generateAndStoreEmail() throws Exception
47      {
48          // Generate messages.
49          List<MimeMessage> messages = new ArrayList<MimeMessage>();
50          for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
51          {
52              messages.add(GreenMailUtilities.toMessage(DEFAULT_MESSAGE, DEFAULT_EMAIL, null));
53          }
54          storeEmail(messages);
55      }
56  
57      @Test
58      public void undeployImapApplication() throws Exception
59      {
60          /* Get the receiver so later we can check the stopping condition. This needs to be done before starting to
61           * dispose because the receiver is removed from the connector. */
62          final RetrieveMessageReceiver receiver = getReceiver();
63  
64          // Wait for first message to be processed by the MailMessageProcessor.
65          disposeLatch.await();
66  
67          // Launch a new thread "t" to dispose the context.
68          Thread t = new Thread()
69          {
70              @Override
71              public void run()
72              {
73                  muleContext.dispose();
74              }
75          };
76          t.start();
77  
78          // Wait until "t" has begun to stop.
79          new PollingProber(10000, 100).check(new Probe()
80          {
81              public boolean isSatisfied()
82              {
83                  return (receiver.isStopping() || receiver.isStopped());
84              }
85  
86              public String describeFailure()
87              {
88                  return null;
89              }
90          });
91          // Now that the context is stopping, allow message processing to go on.
92          mailProcessorLatch.countDown();
93  
94          // Assert that only one message has been procesed.
95          assertEquals(1, numberOfProcessedMessages);
96  
97          // Wait until context is disposed.
98          t.join();
99      }
100 
101     /**
102      * Retrieves the IMAP message receiver from the context.
103      *
104      * @return The IMAP message receiver.
105      */
106     private RetrieveMessageReceiver getReceiver()
107     {
108         SimpleFlowConstruct flow = (SimpleFlowConstruct) muleContext.getRegistry().lookupFlowConstruct("emailPollingFlow");
109         InboundEndpoint inboundEndpoint = (InboundEndpoint) flow.getMessageSource();
110         ImapConnector connector = (ImapConnector) inboundEndpoint.getConnector();
111         return (RetrieveMessageReceiver) connector.getReceiver(flow, inboundEndpoint);
112     }
113 
114     /**
115      * Custom component to help synchronize the disposing process.
116      */
117     public static class MailMessageProcessor implements Callable
118     {
119         public Object onCall(MuleEventContext eventContext) throws Exception
120         {
121             numberOfProcessedMessages++;
122             // Allow thread "t" to dispose.
123             disposeLatch.countDown();
124             // Wait until mule context has stopped.
125             mailProcessorLatch.await();
126             return eventContext.getMessage();
127         }
128     }
129 }