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.awaitility.Awaitility.await;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertFalse;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  import static org.junit.jupiter.api.Assertions.assertNull;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  import static org.junit.jupiter.api.Assertions.fail;
28  
29  import java.time.OffsetDateTime;
30  import java.util.List;
31  import java.util.Set;
32  import java.util.concurrent.TimeUnit;
33  import java.util.concurrent.atomic.AtomicReference;
34  import java.util.stream.Collectors;
35  import javax.ws.rs.core.Response;
36  import org.apache.syncope.common.lib.to.ExecTO;
37  import org.apache.syncope.common.lib.to.ImplementationTO;
38  import org.apache.syncope.common.lib.to.JobTO;
39  import org.apache.syncope.common.lib.to.PagedResult;
40  import org.apache.syncope.common.lib.to.PullTaskTO;
41  import org.apache.syncope.common.lib.to.PushTaskTO;
42  import org.apache.syncope.common.lib.to.SchedTaskTO;
43  import org.apache.syncope.common.lib.to.TaskTO;
44  import org.apache.syncope.common.lib.types.IdRepoImplementationType;
45  import org.apache.syncope.common.lib.types.JobAction;
46  import org.apache.syncope.common.lib.types.TaskType;
47  import org.apache.syncope.common.rest.api.beans.ExecQuery;
48  import org.apache.syncope.common.rest.api.beans.ExecSpecs;
49  import org.apache.syncope.common.rest.api.beans.TaskQuery;
50  import org.apache.syncope.common.rest.api.service.TaskService;
51  import org.apache.syncope.fit.core.reference.TestSampleJobDelegate;
52  import org.junit.jupiter.api.Test;
53  
54  public class SchedTaskITCase extends AbstractTaskITCase {
55  
56      @Test
57      public void getJobClasses() {
58          Set<String> jobClasses = ANONYMOUS_CLIENT.platform().
59                  getJavaImplInfo(IdRepoImplementationType.TASKJOB_DELEGATE).get().getClasses();
60          assertNotNull(jobClasses);
61          assertFalse(jobClasses.isEmpty());
62      }
63  
64      @Test
65      public void list() {
66          PagedResult<SchedTaskTO> tasks =
67                  TASK_SERVICE.search(new TaskQuery.Builder(TaskType.SCHEDULED).build());
68          assertFalse(tasks.getResult().isEmpty());
69          tasks.getResult().stream().filter(
70                  task -> !(task instanceof SchedTaskTO) || task instanceof PullTaskTO || task instanceof PushTaskTO).
71                  forEachOrdered(item -> fail("This should not happen"));
72      }
73  
74      @Test
75      public void update() {
76          SchedTaskTO task = TASK_SERVICE.read(TaskType.SCHEDULED, SCHED_TASK_KEY, true);
77          assertNotNull(task);
78  
79          SchedTaskTO taskMod = new SchedTaskTO();
80          taskMod.setKey(SCHED_TASK_KEY);
81          taskMod.setName(task.getName());
82          taskMod.setCronExpression(null);
83  
84          TASK_SERVICE.update(TaskType.SCHEDULED, taskMod);
85          SchedTaskTO actual = TASK_SERVICE.read(TaskType.SCHEDULED, taskMod.getKey(), true);
86          assertNotNull(actual);
87          assertEquals(task.getKey(), actual.getKey());
88          assertNull(actual.getCronExpression());
89      }
90  
91      @Test
92      public void deferred() {
93          ImplementationTO taskJobDelegate = IMPLEMENTATION_SERVICE.read(
94                  IdRepoImplementationType.TASKJOB_DELEGATE, TestSampleJobDelegate.class.getSimpleName());
95          assertNotNull(taskJobDelegate);
96  
97          SchedTaskTO task = new SchedTaskTO();
98          task.setActive(true);
99          task.setName("deferred");
100         task.setJobDelegate(taskJobDelegate.getKey());
101 
102         Response response = TASK_SERVICE.create(TaskType.SCHEDULED, task);
103         task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
104         assertNotNull(task);
105         String taskKey = task.getKey();
106         assertNotNull(task);
107 
108         OffsetDateTime initial = OffsetDateTime.now();
109         OffsetDateTime later = initial.plusSeconds(2);
110 
111         AtomicReference<TaskTO> taskTO = new AtomicReference<>(task);
112         int preSyncSize = taskTO.get().getExecutions().size();
113         ExecTO execution = TASK_SERVICE.execute(new ExecSpecs.Builder().key(task.getKey()).startAt(later).build());
114         assertNotNull(execution.getExecutor());
115 
116         await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
117             try {
118                 taskTO.set(TASK_SERVICE.read(TaskType.SCHEDULED, taskKey, true));
119                 return preSyncSize < taskTO.get().getExecutions().size();
120             } catch (Exception e) {
121                 return false;
122             }
123         });
124 
125         PagedResult<ExecTO> execs =
126                 TASK_SERVICE.listExecutions(new ExecQuery.Builder().key(task.getKey()).build());
127         assertEquals(1, execs.getTotalCount());
128         assertTrue(execs.getResult().get(0).getStart().isAfter(initial));
129         // round 1 sec for safety
130         assertTrue(execs.getResult().get(0).getStart().plusSeconds(1).isAfter(later));
131     }
132 
133     @Test
134     public void issueSYNCOPE144() {
135         ImplementationTO taskJobDelegate = IMPLEMENTATION_SERVICE.read(
136                 IdRepoImplementationType.TASKJOB_DELEGATE, TestSampleJobDelegate.class.getSimpleName());
137         assertNotNull(taskJobDelegate);
138 
139         SchedTaskTO task = new SchedTaskTO();
140         task.setName("issueSYNCOPE144");
141         task.setDescription("issueSYNCOPE144 Description");
142         task.setJobDelegate(taskJobDelegate.getKey());
143 
144         Response response = TASK_SERVICE.create(TaskType.SCHEDULED, task);
145         task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
146         assertNotNull(task);
147         assertEquals("issueSYNCOPE144", task.getName());
148         assertEquals("issueSYNCOPE144 Description", task.getDescription());
149 
150         task = TASK_SERVICE.read(TaskType.SCHEDULED, task.getKey(), true);
151         assertNotNull(task);
152         assertEquals("issueSYNCOPE144", task.getName());
153         assertEquals("issueSYNCOPE144 Description", task.getDescription());
154 
155         task.setName("issueSYNCOPE144_2");
156         task.setDescription("issueSYNCOPE144 Description_2");
157 
158         response = TASK_SERVICE.create(TaskType.SCHEDULED, task);
159         task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
160         assertNotNull(task);
161         assertEquals("issueSYNCOPE144_2", task.getName());
162         assertEquals("issueSYNCOPE144 Description_2", task.getDescription());
163     }
164 
165     @Test
166     public void issueSYNCOPE660() {
167         List<JobTO> jobs = TASK_SERVICE.listJobs();
168         int oldSize = jobs.size();
169 
170         ImplementationTO taskJobDelegate = IMPLEMENTATION_SERVICE.read(
171                 IdRepoImplementationType.TASKJOB_DELEGATE, TestSampleJobDelegate.class.getSimpleName());
172         assertNotNull(taskJobDelegate);
173 
174         SchedTaskTO task = new SchedTaskTO();
175         task.setName("issueSYNCOPE660");
176         task.setDescription("issueSYNCOPE660 Description");
177         task.setJobDelegate(taskJobDelegate.getKey());
178 
179         Response response = TASK_SERVICE.create(TaskType.SCHEDULED, task);
180         task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
181 
182         jobs = TASK_SERVICE.listJobs();
183         assertEquals(oldSize + 1, jobs.size());
184 
185         TASK_SERVICE.actionJob(task.getKey(), JobAction.START);
186 
187         AtomicReference<List<JobTO>> run = new AtomicReference<>();
188         await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
189             try {
190                 run.set(TASK_SERVICE.listJobs().stream().filter(JobTO::isRunning).collect(Collectors.toList()));
191                 return !run.get().isEmpty();
192             } catch (Exception e) {
193                 return false;
194             }
195         });
196         assertEquals(1, run.get().size());
197         assertEquals(task.getKey(), run.get().get(0).getRefKey());
198 
199         TASK_SERVICE.actionJob(task.getKey(), JobAction.STOP);
200 
201         run.set(List.of());
202         await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> {
203             try {
204                 run.set(TASK_SERVICE.listJobs().stream().filter(JobTO::isRunning).collect(Collectors.toList()));
205                 return run.get().isEmpty();
206             } catch (Exception e) {
207                 return false;
208             }
209         });
210     }
211 }