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.core.persistence.jpa.outer;
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  import static org.junit.jupiter.api.Assertions.fail;
26  
27  import java.time.OffsetDateTime;
28  import java.util.ArrayList;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Set;
32  import java.util.UUID;
33  import org.apache.syncope.common.lib.types.AnyTypeKind;
34  import org.apache.syncope.common.lib.types.ExecStatus;
35  import org.apache.syncope.common.lib.types.IdMImplementationType;
36  import org.apache.syncope.common.lib.types.ImplementationEngine;
37  import org.apache.syncope.common.lib.types.MatchingRule;
38  import org.apache.syncope.common.lib.types.PullMode;
39  import org.apache.syncope.common.lib.types.ResourceOperation;
40  import org.apache.syncope.common.lib.types.TaskType;
41  import org.apache.syncope.common.lib.types.UnmatchingRule;
42  import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
43  import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
44  import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
45  import org.apache.syncope.core.persistence.api.dao.RealmDAO;
46  import org.apache.syncope.core.persistence.api.dao.TaskDAO;
47  import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
48  import org.apache.syncope.core.persistence.api.dao.UserDAO;
49  import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
50  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
51  import org.apache.syncope.core.persistence.api.entity.Implementation;
52  import org.apache.syncope.core.persistence.api.entity.task.PropagationData;
53  import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
54  import org.apache.syncope.core.persistence.api.entity.task.PullTask;
55  import org.apache.syncope.core.persistence.api.entity.task.PushTask;
56  import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
57  import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
58  import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
59  import org.apache.syncope.core.persistence.api.entity.user.User;
60  import org.apache.syncope.core.persistence.jpa.AbstractTest;
61  import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
62  import org.identityconnectors.framework.common.objects.Attribute;
63  import org.identityconnectors.framework.common.objects.AttributeBuilder;
64  import org.junit.jupiter.api.Test;
65  import org.springframework.beans.factory.annotation.Autowired;
66  import org.springframework.transaction.annotation.Transactional;
67  
68  @Transactional("Master")
69  public class TaskTest extends AbstractTest {
70  
71      @Autowired
72      private TaskDAO taskDAO;
73  
74      @Autowired
75      private TaskExecDAO taskExecDAO;
76  
77      @Autowired
78      private ExternalResourceDAO resourceDAO;
79  
80      @Autowired
81      private UserDAO userDAO;
82  
83      @Autowired
84      private RealmDAO realmDAO;
85  
86      @Autowired
87      private ImplementationDAO implementationDAO;
88  
89      @Autowired
90      private TaskUtilsFactory taskUtilsFactory;
91  
92      @Test
93      public void read() {
94          PropagationTask task = taskDAO.find(TaskType.PROPAGATION, "1e697572-b896-484c-ae7f-0c8f63fcbc6c");
95          assertNotNull(task);
96  
97          assertNotNull(task.getExecs());
98          assertFalse(task.getExecs().isEmpty());
99          assertEquals(1, task.getExecs().size());
100     }
101 
102     @Test
103     public void readMultipleOrderBy() {
104         List<OrderByClause> orderByClauses = new ArrayList<>();
105         OrderByClause clause1 = new OrderByClause();
106         clause1.setField("start");
107         OrderByClause clause2 = new OrderByClause();
108         clause2.setField("latestExecStatus");
109         OrderByClause clause3 = new OrderByClause();
110         clause3.setField("connObjectKey");
111         orderByClauses.add(clause1);
112         orderByClauses.add(clause2);
113         orderByClauses.add(clause3);
114         assertFalse(taskDAO.findAll(TaskType.PROPAGATION, null, null, null, null, -1, -1, orderByClauses).isEmpty());
115     }
116 
117     @Test
118     public void savePropagationTask() {
119         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
120         assertNotNull(resource);
121 
122         User user = userDAO.findByUsername("verdi");
123         assertNotNull(user);
124 
125         PropagationTask task = entityFactory.newEntity(PropagationTask.class);
126         task.setResource(resource);
127         task.setAnyTypeKind(AnyTypeKind.USER);
128         task.setAnyType(AnyTypeKind.USER.name());
129         task.setOperation(ResourceOperation.CREATE);
130         task.setConnObjectKey("one@two.com");
131 
132         Set<Attribute> attributes = new HashSet<>();
133         attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
134         attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
135         task.setPropagationData(new PropagationData(attributes));
136 
137         task = taskDAO.save(task);
138         assertNotNull(task);
139 
140         PropagationTask actual = taskDAO.find(TaskType.PROPAGATION, task.getKey());
141         assertEquals(task, actual);
142 
143         entityManager().flush();
144 
145         assertTrue(taskDAO.<PropagationTask>findAll(
146                 TaskType.PROPAGATION, resource, null, null, null, -1, -1, List.of()).
147                 contains(task));
148     }
149 
150     @Test
151     public void addPropagationTaskExecution() {
152         PropagationTask task = taskDAO.find(TaskType.PROPAGATION, "1e697572-b896-484c-ae7f-0c8f63fcbc6c");
153         assertNotNull(task);
154 
155         int executionNumber = task.getExecs().size();
156 
157         TaskExec<PropagationTask> execution = taskUtilsFactory.getInstance(TaskType.PROPAGATION).newTaskExec();
158         execution.setTask(task);
159         execution.setStatus(ExecStatus.CREATED.name());
160         execution.setStart(OffsetDateTime.now());
161         execution.setExecutor("admin");
162         task.add(execution);
163 
164         taskDAO.save(task);
165         entityManager().flush();
166 
167         task = taskDAO.find(TaskType.PROPAGATION, "1e697572-b896-484c-ae7f-0c8f63fcbc6c");
168         assertNotNull(task);
169 
170         assertEquals(executionNumber + 1, task.getExecs().size());
171     }
172 
173     @Test
174     public void addPullTaskExecution() {
175         PullTask task = (PullTask) taskDAO.find(TaskType.PULL, "c41b9b71-9bfa-4f90-89f2-84787def4c5c");
176         assertNotNull(task);
177 
178         int executionNumber = task.getExecs().size();
179 
180         TaskExec<SchedTask> execution = taskUtilsFactory.getInstance(TaskType.PULL).newTaskExec();
181         execution.setStatus("Text-free status");
182         execution.setTask(task);
183         execution.setStart(OffsetDateTime.now());
184         execution.setMessage("A message");
185         execution.setExecutor("admin");
186         task.add(execution);
187 
188         taskDAO.save(task);
189         entityManager().flush();
190 
191         task = (PullTask) taskDAO.find(TaskType.PULL, "c41b9b71-9bfa-4f90-89f2-84787def4c5c");
192         assertNotNull(task);
193 
194         assertEquals(executionNumber + 1, task.getExecs().size());
195     }
196 
197     @Test
198     public void addPushTaskExecution() {
199         PushTask task = (PushTask) taskDAO.find(TaskType.PUSH, "af558be4-9d2f-4359-bf85-a554e6e90be1");
200         assertNotNull(task);
201 
202         int executionNumber = task.getExecs().size();
203 
204         TaskExec<SchedTask> execution = taskUtilsFactory.getInstance(TaskType.PUSH).newTaskExec();
205         execution.setStatus("Text-free status");
206         execution.setTask(task);
207         execution.setStart(OffsetDateTime.now());
208         execution.setMessage("A message");
209         execution.setExecutor("admin");
210         task.add(execution);
211 
212         taskDAO.save(task);
213         entityManager().flush();
214 
215         task = (PushTask) taskDAO.find(TaskType.PUSH, "af558be4-9d2f-4359-bf85-a554e6e90be1");
216         assertNotNull(task);
217 
218         assertEquals(executionNumber + 1, task.getExecs().size());
219     }
220 
221     @Test
222     public void deleteTask() {
223         taskDAO.delete(TaskType.PROPAGATION, "1e697572-b896-484c-ae7f-0c8f63fcbc6c");
224 
225         entityManager().flush();
226 
227         assertTrue(taskDAO.find("1e697572-b896-484c-ae7f-0c8f63fcbc6c").isEmpty());
228         assertTrue(taskExecDAO.find("e58ca1c7-178a-4012-8a71-8aa14eaf0655").isEmpty());
229     }
230 
231     @Test
232     public void deleteTaskExecution() {
233         TaskExec<PropagationTask> execution =
234                 taskExecDAO.find(TaskType.PROPAGATION, "e58ca1c7-178a-4012-8a71-8aa14eaf0655");
235         int executionNumber = execution.getTask().getExecs().size();
236 
237         taskExecDAO.delete(TaskType.PROPAGATION, "e58ca1c7-178a-4012-8a71-8aa14eaf0655");
238 
239         entityManager().flush();
240 
241         assertTrue(taskExecDAO.find("e58ca1c7-178a-4012-8a71-8aa14eaf0655").isEmpty());
242 
243         PropagationTask task = taskDAO.find(TaskType.PROPAGATION, "1e697572-b896-484c-ae7f-0c8f63fcbc6c");
244         assertEquals(task.getExecs().size(), executionNumber - 1);
245     }
246 
247     @Test
248     public void savePullTask() {
249         PullTask task = entityFactory.newEntity(PullTask.class);
250         task.setName("savePullTask");
251         task.setDescription("PullTask description");
252         task.setActive(true);
253         task.setPullMode(PullMode.FULL_RECONCILIATION);
254         task.setJobDelegate(implementationDAO.find("PullJobDelegate"));
255         task.setDestinationRealm(realmDAO.getRoot());
256         task.setCronExpression("BLA BLA");
257         task.setMatchingRule(MatchingRule.UPDATE);
258         task.setUnmatchingRule(UnmatchingRule.PROVISION);
259 
260         // now adding PullActions
261         Implementation pullActions = entityFactory.newEntity(Implementation.class);
262         pullActions.setKey("PullActions" + UUID.randomUUID().toString());
263         pullActions.setEngine(ImplementationEngine.JAVA);
264         pullActions.setType(IdMImplementationType.PULL_ACTIONS);
265         pullActions.setBody(PullActions.class.getName());
266         pullActions = implementationDAO.save(pullActions);
267         entityManager().flush();
268 
269         task.add(pullActions);
270 
271         // this save() fails because of an invalid Cron Expression
272         try {
273             taskDAO.save(task);
274             fail();
275         } catch (InvalidEntityException e) {
276             assertNotNull(e);
277         }
278         task.setCronExpression(null);
279 
280         // this save() fails because a PullTask requires a target resource
281         try {
282             taskDAO.save(task);
283             fail();
284         } catch (InvalidEntityException e) {
285             assertNotNull(e);
286         }
287         task.setResource(resourceDAO.find("ws-target-resource-1"));
288 
289         // this save() finally works
290         task = (PullTask) taskDAO.save(task);
291         assertNotNull(task);
292 
293         PullTask actual = (PullTask) taskDAO.find(TaskType.PULL, task.getKey());
294         assertEquals(task, actual);
295     }
296 
297     @Test
298     public void issueSYNCOPE144() {
299         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
300         assertNotNull(resource);
301 
302         Implementation pullActions = entityFactory.newEntity(Implementation.class);
303         pullActions.setKey("syncope144");
304         pullActions.setEngine(ImplementationEngine.JAVA);
305         pullActions.setType(IdMImplementationType.PULL_ACTIONS);
306         pullActions.setBody(PullActions.class.getName());
307         pullActions = implementationDAO.save(pullActions);
308 
309         PullTask task = entityFactory.newEntity(PullTask.class);
310 
311         task.setResource(resource);
312         task.setName("issueSYNCOPE144");
313         task.setDescription("issueSYNCOPE144 Description");
314         task.setActive(true);
315         task.setPullMode(PullMode.FULL_RECONCILIATION);
316         task.add(pullActions);
317         task.setMatchingRule(MatchingRule.UPDATE);
318         task.setUnmatchingRule(UnmatchingRule.PROVISION);
319 
320         task = (PullTask) taskDAO.save(task);
321         assertNotNull(task);
322 
323         PullTask actual = (PullTask) taskDAO.find(TaskType.PULL, task.getKey());
324         assertEquals(task, actual);
325         assertEquals("issueSYNCOPE144", actual.getName());
326         assertEquals("issueSYNCOPE144 Description", actual.getDescription());
327 
328         actual.setName("issueSYNCOPE144_2");
329         actual.setDescription("issueSYNCOPE144 Description_2");
330 
331         actual = (PullTask) taskDAO.save(actual);
332         assertNotNull(actual);
333         assertEquals("issueSYNCOPE144_2", actual.getName());
334         assertEquals("issueSYNCOPE144 Description_2", actual.getDescription());
335     }
336 }