View Javadoc
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  package org.apache.syncope.fit.core;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import javax.ws.rs.core.Response;
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.commons.lang3.tuple.Pair;
29  import org.apache.cxf.jaxrs.client.WebClient;
30  import org.apache.syncope.client.lib.SyncopeClient;
31  import org.apache.syncope.common.lib.SyncopeConstants;
32  import org.apache.syncope.common.lib.request.GroupCR;
33  import org.apache.syncope.common.lib.to.ExecTO;
34  import org.apache.syncope.common.lib.to.GroupTO;
35  import org.apache.syncope.common.lib.to.ImplementationTO;
36  import org.apache.syncope.common.lib.to.NotificationTO;
37  import org.apache.syncope.common.lib.to.NotificationTaskTO;
38  import org.apache.syncope.common.lib.to.PagedResult;
39  import org.apache.syncope.common.lib.types.AnyTypeKind;
40  import org.apache.syncope.common.lib.types.IdRepoImplementationType;
41  import org.apache.syncope.common.lib.types.ImplementationEngine;
42  import org.apache.syncope.common.lib.types.TaskType;
43  import org.apache.syncope.common.lib.types.TraceLevel;
44  import org.apache.syncope.common.rest.api.RESTHeaders;
45  import org.apache.syncope.common.rest.api.beans.ExecSpecs;
46  import org.apache.syncope.common.rest.api.beans.TaskQuery;
47  import org.apache.syncope.common.rest.api.service.NotificationService;
48  import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
49  import org.apache.syncope.fit.core.reference.TestNotificationRecipientsProvider;
50  import org.junit.jupiter.api.Test;
51  
52  public class NotificationTaskITCase extends AbstractNotificationTaskITCase {
53  
54      @Test
55      public void notifyByMail() throws Exception {
56          String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
57          String subject = "Test notification " + getUUIDString();
58          Pair<String, String> created = createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
59          NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
60          assertNotNull(taskTO);
61          assertNotNull(taskTO.getNotification());
62  
63          execNotificationTask(TASK_SERVICE, taskTO.getKey(), MAX_WAIT_SECONDS);
64  
65          verifyMail(sender, subject, created.getRight(), MAX_WAIT_SECONDS);
66  
67          // verify message body
68          taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
69          assertNotNull(taskTO);
70          assertTrue(taskTO.isExecuted());
71          assertNotNull(taskTO.getTextBody());
72          assertTrue(taskTO.getTextBody().contains("Your email address is " + created.getRight() + '.'));
73          assertTrue(taskTO.getTextBody().contains("Your email address inside a link: "
74                  + "http://localhost/?email=" + created.getRight().replaceAll("@", "%40")));
75      }
76  
77      @Test
78      public void notifyByMailEmptyAbout() throws Exception {
79          String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
80          String subject = "Test notification " + getUUIDString();
81          Pair<String, String> created = createNotificationTask(true, false, TraceLevel.ALL, sender, subject);
82          NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
83          assertNotNull(taskTO);
84  
85          execNotificationTask(TASK_SERVICE, taskTO.getKey(), MAX_WAIT_SECONDS);
86  
87          verifyMail(sender, subject, created.getRight(), MAX_WAIT_SECONDS);
88      }
89  
90      @Test
91      public void notifyByMailWithRetry() throws Exception {
92          // 1. Set higher number of retries
93          Long origMaxRetries = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
94                  "notification.maxRetries", null, Long.class);
95  
96          confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "notification.maxRetries", 10);
97  
98          // 2. Stop mail server to force errors while sending out e-mails
99          WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/greenMail/stop").post(null);
100 
101         try {
102             // 3. create notification and user
103             String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
104             String subject = "Test notification " + getUUIDString();
105             Pair<String, String> created = createNotificationTask(true, true, TraceLevel.ALL, sender, subject);
106             NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
107             assertNotNull(taskTO);
108             assertNotNull(taskTO.getNotification());
109             int preExecs = taskTO.getExecutions().size();
110 
111             // 4. verify notification could not be delivered
112             execTask(TASK_SERVICE, TaskType.NOTIFICATION, taskTO.getKey(), NotificationJob.Status.NOT_SENT.name(), 5,
113                     false);
114 
115             taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
116             assertNotNull(taskTO);
117             assertFalse(taskTO.isExecuted());
118             assertTrue(preExecs <= taskTO.getExecutions().size());
119             for (ExecTO exec : taskTO.getExecutions()) {
120                 assertEquals(NotificationJob.Status.NOT_SENT.name(), exec.getStatus());
121             }
122         } finally {
123             // start mail server again
124             WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/greenMail/start").post(null);
125             // reset number of retries
126             confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "notification.maxRetries", origMaxRetries);
127         }
128     }
129 
130     @Test
131     public void issueSYNCOPE81() {
132         String sender = "syncope81@syncope.apache.org";
133         Pair<String, String> created = createNotificationTask(true, true, TraceLevel.ALL, sender, "Test notification");
134         NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
135         assertNotNull(taskTO);
136         assertNotNull(taskTO.getNotification());
137 
138         if (taskTO.getExecutions().isEmpty()) {
139             // generate an execution in order to verify the deletion of a notification task with one or more executions
140             execNotificationTask(TASK_SERVICE, taskTO.getKey(), MAX_WAIT_SECONDS);
141         }
142 
143         taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
144         assertTrue(taskTO.isExecuted());
145         assertFalse(taskTO.getExecutions().isEmpty());
146 
147         TASK_SERVICE.delete(TaskType.NOTIFICATION, taskTO.getKey());
148     }
149 
150     @Test
151     public void issueSYNCOPE86() {
152         // 1. create notification task
153         String sender = "syncope86@syncope.apache.org";
154         Pair<String, String> created = createNotificationTask(true, true, TraceLevel.ALL, sender, "Test notification");
155 
156         // 2. get NotificationTaskTO for user just created
157         NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
158         assertNotNull(taskTO);
159         assertNotNull(taskTO.getNotification());
160 
161         try {
162             // 3. execute the generated NotificationTask if needed
163             if (taskTO.getExecutions().isEmpty()) {
164                 execNotificationTask(TASK_SERVICE, taskTO.getKey(), MAX_WAIT_SECONDS);
165             }
166 
167             // 4. verify
168             taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
169             assertNotNull(taskTO);
170             assertTrue(taskTO.isExecuted());
171             assertFalse(taskTO.getExecutions().isEmpty());
172         } finally {
173             // Remove execution to make test re-runnable
174             taskTO.getExecutions().forEach(e -> TASK_SERVICE.deleteExecution(e.getKey()));
175         }
176     }
177 
178     @Test
179     public void issueSYNCOPE192() throws Exception {
180         String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
181         String subject = "Test notification " + getUUIDString();
182         Pair<String, String> created = createNotificationTask(true, true, TraceLevel.NONE, sender, subject);
183         NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
184         assertNotNull(taskTO);
185         assertNotNull(taskTO.getNotification());
186 
187         if (taskTO.getExecutions().isEmpty()) {
188             TASK_SERVICE.execute(new ExecSpecs.Builder().key(taskTO.getKey()).build());
189         }
190 
191         verifyMail(sender, subject, created.getRight(), MAX_WAIT_SECONDS);
192 
193         // verify that last exec status was updated
194         taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
195         assertNotNull(taskTO);
196         assertTrue(taskTO.isExecuted());
197         assertTrue(taskTO.getExecutions().isEmpty());
198         assertTrue(StringUtils.isNotBlank(taskTO.getLatestExecStatus()));
199     }
200 
201     @Test
202     public void issueSYNCOPE445() throws Exception {
203         String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
204         String subject = "Test notification " + getUUIDString();
205         Pair<String, String> created = createNotificationTask(
206                 true, true, TraceLevel.ALL, sender, subject, "syncope445@syncope.apache.org");
207         NotificationTaskTO taskTO = findNotificationTask(created.getLeft(), MAX_WAIT_SECONDS);
208         assertNotNull(taskTO);
209         assertNotNull(taskTO.getNotification());
210 
211         if (taskTO.getExecutions().isEmpty()) {
212             execNotificationTask(TASK_SERVICE, taskTO.getKey(), MAX_WAIT_SECONDS);
213         }
214 
215         verifyMail(sender, subject, created.getRight(), MAX_WAIT_SECONDS);
216 
217         // verify task
218         taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
219         assertTrue(taskTO.isExecuted());
220         assertNotNull(taskTO);
221         assertTrue(taskTO.getRecipients().contains("syncope445@syncope.apache.org"));
222     }
223 
224     @Test
225     public void issueSYNCOPE446() throws Exception {
226         // 1. Create notification
227         ImplementationTO recipientsProvider = new ImplementationTO();
228         recipientsProvider.setKey(TestNotificationRecipientsProvider.class.getSimpleName());
229         recipientsProvider.setEngine(ImplementationEngine.JAVA);
230         recipientsProvider.setType(IdRepoImplementationType.RECIPIENTS_PROVIDER);
231         recipientsProvider.setBody(TestNotificationRecipientsProvider.class.getName());
232         Response response = IMPLEMENTATION_SERVICE.create(recipientsProvider);
233         recipientsProvider = IMPLEMENTATION_SERVICE.read(
234                 recipientsProvider.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
235         assertNotNull(recipientsProvider);
236 
237         NotificationTO notification = new NotificationTO();
238         notification.setTraceLevel(TraceLevel.ALL);
239         notification.getEvents().add("[LOGIC]:[GroupLogic]:[]:[create]:[SUCCESS]");
240 
241         String groupName = "group" + getUUIDString();
242         notification.getAbouts().put(AnyTypeKind.GROUP.name(),
243                 SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo(groupName).query());
244 
245         notification.setRecipientsFIQL(SyncopeClient.getUserSearchConditionBuilder().
246                 inGroups("f779c0d4-633b-4be5-8f57-32eb478a3ca5").query());
247         notification.setSelfAsRecipient(false);
248         notification.setRecipientAttrName("email");
249         notification.getStaticRecipients().add("notificationtest@syncope.apache.org");
250         notification.setRecipientsProvider(recipientsProvider.getKey());
251 
252         String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
253         notification.setSender(sender);
254         String subject = "Test notification " + getUUIDString();
255         notification.setSubject(subject);
256         notification.setTemplate("optin");
257         notification.setActive(true);
258 
259         response = NOTIFICATION_SERVICE.create(notification);
260         notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
261         assertNotNull(notification);
262         assertEquals(recipientsProvider.getKey(), notification.getRecipientsProvider());
263 
264         // 2. create group
265         GroupCR groupCR = new GroupCR();
266         groupCR.setName(groupName);
267         groupCR.setRealm("/even/two");
268         GroupTO groupTO = createGroup(groupCR).getEntity();
269         assertNotNull(groupTO);
270 
271         // 3. verify
272         NotificationTaskTO taskTO = findNotificationTask(notification.getKey(), MAX_WAIT_SECONDS);
273         assertNotNull(taskTO);
274         assertNotNull(taskTO.getNotification());
275         assertTrue(taskTO.getRecipients().containsAll(
276                 new TestNotificationRecipientsProvider().provideRecipients(null)));
277 
278         execNotificationTask(TASK_SERVICE, taskTO.getKey(), MAX_WAIT_SECONDS);
279 
280         verifyMail(sender, subject, "notificationtest@syncope.apache.org", MAX_WAIT_SECONDS);
281     }
282 
283     @Test
284     public void issueSYNCOPE492() throws Exception {
285         String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org";
286         String subject = "Test notification " + getUUIDString();
287         Pair<String, String> created =
288                 createNotificationTask(false, true, TraceLevel.NONE, sender, subject, "syncope445@syncope.apache.org");
289 
290         // verify that no task was created for disabled notification
291         PagedResult<NotificationTaskTO> tasks = TASK_SERVICE.search(new TaskQuery.Builder(TaskType.NOTIFICATION).
292                 notification(created.getLeft()).build());
293         assertEquals(0, tasks.getSize());
294     }
295 }