View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kcb.service.impl;
17  
18  import org.apache.commons.lang.RandomStringUtils;
19  import org.junit.Assert;
20  import org.junit.Test;
21  import org.kuali.rice.kcb.bo.MessageDelivery;
22  import org.kuali.rice.kcb.bo.MessageDeliveryStatus;
23  import org.kuali.rice.kcb.api.message.MessageDTO;
24  import org.kuali.rice.kcb.quartz.MessageProcessingJob;
25  import org.kuali.rice.kcb.test.KCBTestCase;
26  import org.kuali.rice.ksb.service.KSBServiceLocator;
27  import org.kuali.rice.test.BaselineTestCase.BaselineMode;
28  import org.kuali.rice.test.BaselineTestCase.Mode;
29  import org.quartz.JobExecutionContext;
30  import org.quartz.JobExecutionException;
31  import org.quartz.SchedulerException;
32  import org.quartz.listeners.JobListenerSupport;
33  import org.springframework.transaction.support.TransactionSynchronizationManager;
34  
35  import java.util.Collection;
36  import java.util.concurrent.CountDownLatch;
37  import java.util.concurrent.TimeUnit;
38  
39  import static org.junit.Assert.*;
40  
41  /**
42   * Tests MessagingService 
43   * 
44   * @author Kuali Rice Team (rice.collab@kuali.org)
45   */
46  /*
47  @PerTestUnitTestData({
48      @UnitTestData(filename = "file:ken/src/main/config/sql/KENBootstrap.sql", delimiter = "/"),
49      @UnitTestData(filename = "classpath:org/kuali/rice/kcb/test/KENTestData.sql")
50  }
51  )*/
52  @BaselineMode(Mode.CLEAR_DB)
53  public class MessagingServiceTest extends KCBTestCase {
54      private CountDownLatch signal = new CountDownLatch(1);
55  
56      @Override
57      public void setUp() throws Exception {
58          super.setUp();
59      
60          services.getRecipientPreferenceService().saveRecipientDelivererConfig("testuser5", "mock", new String[] { "Test Channel #1" });
61          services.getRecipientPreferenceService().saveRecipientDelivererConfig("testuser5", "sms", new String[] { "Test Channel #1" });
62          services.getRecipientPreferenceService().saveRecipientDelivererConfig("testuser5", "broken", new String[] { "Test Channel #1" }); // this one throws exceptions
63          services.getRecipientPreferenceService().saveRecipientDelivererConfig("testuser5", "bogus", new String[] { "Test Channel #1" }); // this one doesn't exist
64          
65          assertEquals(4, services.getRecipientPreferenceService().getDeliverersForRecipientAndChannel("testuser5", "Test Channel #1").size());
66      }
67  
68      protected long deliver() throws Exception {
69          MessageDTO message = new MessageDTO();
70          message.setContent("test content 1");
71          message.setChannel("Test Channel #1");
72          message.setContentType("test content type 1");
73          message.setDeliveryType("test delivery type 1");
74          message.setRecipient("testuser5");
75          message.setTitle("test title 1");
76          message.setOriginId("origin id");
77  
78          registerJobListener();
79  
80          long id = services.getMessagingService().deliver(message);
81  
82          waitForNextJobCompletion();
83  
84          Collection<MessageDelivery> deliveries = services.getMessageDeliveryService().getAllMessageDeliveries();
85          assertNotNull(deliveries);
86          int delivCount = services.getRecipientPreferenceService().getDeliverersForRecipientAndChannel("testuser5", "Test Channel #1").size();
87          assertEquals(delivCount, deliveries.size());
88          assertTrue(deliveries.size() > 0);
89          int failed = 0;
90          for (MessageDelivery delivery: deliveries) {
91              if ("broken".equals(delivery.getDelivererTypeName()) || "bogus".equals(delivery.getDelivererTypeName())) {
92                  assertEquals(MessageDeliveryStatus.UNDELIVERED.name(), delivery.getDeliveryStatus());
93                  assertEquals(1, delivery.getProcessCount().intValue());
94                  failed++;
95              } else {
96                  assertEquals(MessageDeliveryStatus.DELIVERED.name(), delivery.getDeliveryStatus());
97              }
98          }
99  
100         assertEquals(2, failed);
101         
102         // try up till max attempts, which for now is 3
103         
104         waitForNextJobCompletion();
105 
106         failed = 0;
107         deliveries = services.getMessageDeliveryService().getAllMessageDeliveries();
108         for (MessageDelivery delivery: deliveries) {
109             if ("broken".equals(delivery.getDelivererTypeName()) || "bogus".equals(delivery.getDelivererTypeName())) {
110                 assertEquals(MessageDeliveryStatus.UNDELIVERED.name(), delivery.getDeliveryStatus());
111                 assertEquals(2, delivery.getProcessCount().intValue());
112                 failed++;
113             } else {
114                 assertEquals(MessageDeliveryStatus.DELIVERED.name(), delivery.getDeliveryStatus());
115             }
116         }
117 
118         assertEquals(2, failed);
119         
120         waitForNextJobCompletion();
121 
122         failed = 0;
123         deliveries = services.getMessageDeliveryService().getAllMessageDeliveries();
124         for (MessageDelivery delivery: deliveries) {
125             if ("broken".equals(delivery.getDelivererTypeName()) || "bogus".equals(delivery.getDelivererTypeName())) {
126                 assertEquals(MessageDeliveryStatus.UNDELIVERED.name(), delivery.getDeliveryStatus());
127                 assertEquals(3, delivery.getProcessCount().intValue());
128                 failed++;
129             } else {
130                 assertEquals(MessageDeliveryStatus.DELIVERED.name(), delivery.getDeliveryStatus());
131             }
132         }
133 
134         assertEquals(2, failed);
135         
136         // finally the last attempt, nothing should have changed
137         
138         waitForNextJobCompletion();
139 
140         failed = 0;
141         deliveries = services.getMessageDeliveryService().getAllMessageDeliveries();
142         for (MessageDelivery delivery: deliveries) {
143             if ("broken".equals(delivery.getDelivererTypeName()) || "bogus".equals(delivery.getDelivererTypeName())) {
144                 assertEquals(MessageDeliveryStatus.UNDELIVERED.name(), delivery.getDeliveryStatus());
145                 assertEquals(3, delivery.getProcessCount().intValue());
146                 failed++;
147             } else {
148                 assertEquals(MessageDeliveryStatus.DELIVERED.name(), delivery.getDeliveryStatus());
149             }
150         }
151 
152         assertEquals(2, failed);
153 
154         return id;
155     }
156 
157     @Test
158     public void testDeliver() throws Exception {
159         Assert.assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
160 
161         deliver();
162     }
163     
164     @Test
165     public void testDismiss() throws Exception {
166         Assert.assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
167 
168         long id = deliver();
169 
170         registerJobListener();
171 
172         services.getMessagingService().remove(id, "a user", "a cause");
173         
174         waitForNextJobCompletion();
175 
176         Collection<MessageDelivery> deliveries = services.getMessageDeliveryService().getAllMessageDeliveries();
177         assertNotNull(deliveries);
178         // should be all gone except for the 2 bad deliveries
179         assertEquals(2, deliveries.size());
180         for (MessageDelivery d: deliveries) {
181             assertTrue("broken".equals(d.getDelivererTypeName()) || "bogus".equals(d.getDelivererTypeName()));
182         }
183     }
184     
185     @Test
186     public void testDismissByOriginId() throws Exception {
187         Assert.assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
188 
189         long id = deliver();
190 
191         registerJobListener();
192 
193         services.getMessagingService().removeByOriginId("origin id", "a user", "a cause");
194         
195         waitForNextJobCompletion();
196 
197         Collection<MessageDelivery> deliveries = services.getMessageDeliveryService().getAllMessageDeliveries();
198         assertNotNull(deliveries);
199         // should be all gone except for the 2 bad deliveries
200         assertEquals(2, deliveries.size());
201         
202         // should be all gone except for the 2 bad deliveries
203         assertEquals(2, deliveries.size());
204         for (MessageDelivery d: deliveries) {
205             assertTrue("broken".equals(d.getDelivererTypeName()) || "bogus".equals(d.getDelivererTypeName()));
206         }
207     }
208     
209     protected void registerJobListener() throws SchedulerException {
210         KSBServiceLocator.getScheduler().addGlobalJobListener(new JobListenerSupport() {
211             @Override
212             public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
213                 log.info("Job was executed: " + context);
214                 if (MessageProcessingJob.NAME.equals(context.getJobDetail().getName())) {
215                     signal.countDown();
216                 }
217             }
218             public String getName() {
219                 return System.currentTimeMillis() + RandomStringUtils.randomAlphanumeric(10);
220             }
221         });
222     }
223 
224     protected void waitForNextJobCompletion() throws InterruptedException {
225         log.info("Waiting for job to complete...");
226         signal.await(100, TimeUnit.SECONDS); // time limit so as not to hang tests if something goes wrong
227         signal = new CountDownLatch(1);
228         log.info("Job completed...");
229     }
230 }