1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.java.data;
20
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.Optional;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.stream.Collectors;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.syncope.common.lib.SyncopeClientException;
28 import org.apache.syncope.common.lib.command.CommandArgs;
29 import org.apache.syncope.common.lib.command.CommandTO;
30 import org.apache.syncope.common.lib.form.FormProperty;
31 import org.apache.syncope.common.lib.form.FormPropertyValue;
32 import org.apache.syncope.common.lib.form.SyncopeForm;
33 import org.apache.syncope.common.lib.to.ExecTO;
34 import org.apache.syncope.common.lib.to.FormPropertyDefTO;
35 import org.apache.syncope.common.lib.to.MacroTaskTO;
36 import org.apache.syncope.common.lib.to.NotificationTaskTO;
37 import org.apache.syncope.common.lib.to.PropagationTaskTO;
38 import org.apache.syncope.common.lib.to.ProvisioningTaskTO;
39 import org.apache.syncope.common.lib.to.PullTaskTO;
40 import org.apache.syncope.common.lib.to.PushTaskTO;
41 import org.apache.syncope.common.lib.to.SchedTaskTO;
42 import org.apache.syncope.common.lib.to.TaskTO;
43 import org.apache.syncope.common.lib.types.ClientExceptionType;
44 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
45 import org.apache.syncope.common.lib.types.ImplementationEngine;
46 import org.apache.syncope.common.lib.types.JobType;
47 import org.apache.syncope.common.lib.types.MatchingRule;
48 import org.apache.syncope.common.lib.types.TaskType;
49 import org.apache.syncope.common.lib.types.UnmatchingRule;
50 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
51 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
52 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
53 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
54 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
55 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
56 import org.apache.syncope.core.persistence.api.entity.AnyType;
57 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
58 import org.apache.syncope.core.persistence.api.entity.Implementation;
59 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
60 import org.apache.syncope.core.persistence.api.entity.task.FormPropertyDef;
61 import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
62 import org.apache.syncope.core.persistence.api.entity.task.MacroTaskCommand;
63 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
64 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
65 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
66 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
67 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
68 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
69 import org.apache.syncope.core.persistence.api.entity.task.Task;
70 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
71 import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
72 import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
73 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
74 import org.apache.syncope.core.provisioning.api.job.JobNamer;
75 import org.apache.syncope.core.provisioning.api.macro.MacroActions;
76 import org.apache.syncope.core.provisioning.java.job.MacroJobDelegate;
77 import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
78 import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
79 import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
80 import org.apache.syncope.core.spring.implementation.ImplementationManager;
81 import org.quartz.Scheduler;
82 import org.quartz.SchedulerException;
83 import org.quartz.Trigger;
84 import org.quartz.TriggerKey;
85 import org.slf4j.Logger;
86 import org.slf4j.LoggerFactory;
87 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
88
89 public class TaskDataBinderImpl extends AbstractExecutableDatabinder implements TaskDataBinder {
90
91 protected static final Logger LOG = LoggerFactory.getLogger(TaskDataBinder.class);
92
93 protected final RealmDAO realmDAO;
94
95 protected final ExternalResourceDAO resourceDAO;
96
97 protected final TaskExecDAO taskExecDAO;
98
99 protected final AnyTypeDAO anyTypeDAO;
100
101 protected final ImplementationDAO implementationDAO;
102
103 protected final EntityFactory entityFactory;
104
105 protected final SchedulerFactoryBean scheduler;
106
107 protected final TaskUtilsFactory taskUtilsFactory;
108
109 protected final Map<String, MacroActions> perContextMacroActions = new ConcurrentHashMap<>();
110
111 public TaskDataBinderImpl(
112 final RealmDAO realmDAO,
113 final ExternalResourceDAO resourceDAO,
114 final TaskExecDAO taskExecDAO,
115 final AnyTypeDAO anyTypeDAO,
116 final ImplementationDAO implementationDAO,
117 final EntityFactory entityFactory,
118 final SchedulerFactoryBean scheduler,
119 final TaskUtilsFactory taskUtilsFactory) {
120
121 this.realmDAO = realmDAO;
122 this.resourceDAO = resourceDAO;
123 this.taskExecDAO = taskExecDAO;
124 this.anyTypeDAO = anyTypeDAO;
125 this.implementationDAO = implementationDAO;
126 this.entityFactory = entityFactory;
127 this.scheduler = scheduler;
128 this.taskUtilsFactory = taskUtilsFactory;
129 }
130
131 protected void fill(final ProvisioningTask<?> provisioningTask, final ProvisioningTaskTO provisioningTaskTO) {
132 if (provisioningTask instanceof PushTask && provisioningTaskTO instanceof PushTaskTO) {
133 PushTask pushTask = (PushTask) provisioningTask;
134 PushTaskTO pushTaskTO = (PushTaskTO) provisioningTaskTO;
135
136 Implementation jobDelegate = pushTaskTO.getJobDelegate() == null
137 ? implementationDAO.findByType(IdRepoImplementationType.TASKJOB_DELEGATE).stream().
138 filter(impl -> PushJobDelegate.class.getSimpleName().equals(impl.getKey())).
139 findFirst().orElse(null)
140 : implementationDAO.find(pushTaskTO.getJobDelegate());
141 if (jobDelegate == null) {
142 jobDelegate = entityFactory.newEntity(Implementation.class);
143 jobDelegate.setKey(PushJobDelegate.class.getSimpleName());
144 jobDelegate.setEngine(ImplementationEngine.JAVA);
145 jobDelegate.setType(IdRepoImplementationType.TASKJOB_DELEGATE);
146 jobDelegate.setBody(PushJobDelegate.class.getName());
147 jobDelegate = implementationDAO.save(jobDelegate);
148 }
149 pushTask.setJobDelegate(jobDelegate);
150
151 pushTask.setSourceRealm(realmDAO.findByFullPath(pushTaskTO.getSourceRealm()));
152
153 pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
154 ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
155 pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
156 ? UnmatchingRule.ASSIGN : pushTaskTO.getUnmatchingRule());
157
158 pushTaskTO.getFilters().forEach((type, fiql) -> {
159 AnyType anyType = anyTypeDAO.find(type);
160 if (anyType == null) {
161 LOG.debug("Invalid AnyType {} specified, ignoring...", type);
162 } else {
163 pushTask.getFilters().put(anyType.getKey(), fiql);
164 }
165 });
166
167 pushTask.getFilters().entrySet().
168 removeIf(filter -> !pushTaskTO.getFilters().containsKey(filter.getKey()));
169 } else if (provisioningTask instanceof PullTask && provisioningTaskTO instanceof PullTaskTO) {
170 PullTask pullTask = (PullTask) provisioningTask;
171 PullTaskTO pullTaskTO = (PullTaskTO) provisioningTaskTO;
172
173 Implementation jobDelegate = pullTaskTO.getJobDelegate() == null
174 ? implementationDAO.findByType(IdRepoImplementationType.TASKJOB_DELEGATE).stream().
175 filter(impl -> PullJobDelegate.class.getSimpleName().equals(impl.getKey())).
176 findFirst().orElse(null)
177 : implementationDAO.find(pullTaskTO.getJobDelegate());
178 if (jobDelegate == null) {
179 jobDelegate = entityFactory.newEntity(Implementation.class);
180 jobDelegate.setKey(PullJobDelegate.class.getSimpleName());
181 jobDelegate.setEngine(ImplementationEngine.JAVA);
182 jobDelegate.setType(IdRepoImplementationType.TASKJOB_DELEGATE);
183 jobDelegate.setBody(PullJobDelegate.class.getName());
184 jobDelegate = implementationDAO.save(jobDelegate);
185 }
186 pullTask.setJobDelegate(jobDelegate);
187
188 pullTask.setPullMode(pullTaskTO.getPullMode());
189
190 if (pullTaskTO.getReconFilterBuilder() == null) {
191 pullTask.setReconFilterBuilder(null);
192 } else {
193 Optional.ofNullable(implementationDAO.find(pullTaskTO.getReconFilterBuilder())).ifPresentOrElse(
194 pullTask::setReconFilterBuilder,
195 () -> LOG.debug("Invalid Implementation {}, ignoring...", pullTaskTO.getReconFilterBuilder()));
196 }
197
198 pullTask.setDestinationRealm(realmDAO.findByFullPath(pullTaskTO.getDestinationRealm()));
199
200 pullTask.setMatchingRule(pullTaskTO.getMatchingRule() == null
201 ? MatchingRule.UPDATE : pullTaskTO.getMatchingRule());
202 pullTask.setUnmatchingRule(pullTaskTO.getUnmatchingRule() == null
203 ? UnmatchingRule.PROVISION : pullTaskTO.getUnmatchingRule());
204
205
206 TemplateUtils.check(pullTaskTO.getTemplates(), ClientExceptionType.InvalidPullTask);
207 pullTaskTO.getTemplates().forEach((type, template) -> {
208 AnyType anyType = anyTypeDAO.find(type);
209 if (anyType == null) {
210 LOG.debug("Invalid AnyType {} specified, ignoring...", type);
211 } else {
212 AnyTemplatePullTask anyTemplate = pullTask.getTemplate(anyType.getKey()).orElse(null);
213 if (anyTemplate == null) {
214 anyTemplate = entityFactory.newEntity(AnyTemplatePullTask.class);
215 anyTemplate.setAnyType(anyType);
216 anyTemplate.setPullTask(pullTask);
217
218 pullTask.add(anyTemplate);
219 }
220 anyTemplate.set(template);
221 }
222 });
223
224 pullTask.getTemplates().
225 removeIf(anyTemplate -> !pullTaskTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey()));
226
227 pullTask.setRemediation(pullTaskTO.isRemediation());
228 }
229
230
231 provisioningTask.setPerformCreate(provisioningTaskTO.isPerformCreate());
232 provisioningTask.setPerformUpdate(provisioningTaskTO.isPerformUpdate());
233 provisioningTask.setPerformDelete(provisioningTaskTO.isPerformDelete());
234 provisioningTask.setSyncStatus(provisioningTaskTO.isSyncStatus());
235
236 provisioningTaskTO.getActions().forEach(
237 action -> Optional.ofNullable(implementationDAO.find(action)).ifPresentOrElse(
238 provisioningTask::add,
239 () -> LOG.debug("Invalid Implementation {}, ignoring...", action)));
240
241 provisioningTask.getActions().removeIf(impl -> !provisioningTaskTO.getActions().contains(impl.getKey()));
242
243 provisioningTask.setConcurrentSettings(provisioningTaskTO.getConcurrentSettings());
244 }
245
246 protected void fill(final MacroTask macroTask, final MacroTaskTO macroTaskTO) {
247 macroTask.setRealm(Optional.ofNullable(realmDAO.findByFullPath(macroTaskTO.getRealm())).
248 orElseThrow(() -> new NotFoundException("Realm " + macroTaskTO.getRealm())));
249
250 macroTask.getCommands().clear();
251 macroTaskTO.getCommands().
252 forEach(command -> Optional.ofNullable(implementationDAO.find(command.getKey())).ifPresentOrElse(
253 impl -> {
254 try {
255 CommandArgs args = command.getArgs();
256 if (args == null) {
257 args = ImplementationManager.emptyArgs(impl);
258 }
259
260 MacroTaskCommand macroTaskCommand = entityFactory.newEntity(MacroTaskCommand.class);
261 macroTaskCommand.setCommand(impl);
262 macroTaskCommand.setArgs(args);
263
264 macroTaskCommand.setMacroTask(macroTask);
265 macroTask.add(macroTaskCommand);
266 } catch (Exception e) {
267 LOG.error("While adding Command {} to Macro", impl.getKey(), e);
268
269 SyncopeClientException sce = SyncopeClientException.build(
270 ClientExceptionType.InvalidImplementationType);
271 sce.getElements().add("While adding Command " + impl.getKey() + ": " + e.getMessage());
272 throw sce;
273 }
274 },
275 () -> LOG.error("Could not find Command {}", command.getKey())));
276
277 macroTask.setContinueOnError(macroTaskTO.isContinueOnError());
278 macroTask.setSaveExecs(macroTaskTO.isSaveExecs());
279
280 macroTask.getFormPropertyDefs().clear();
281 macroTaskTO.getFormPropertyDefs().forEach(fpdTO -> {
282 FormPropertyDef fpd = entityFactory.newEntity(FormPropertyDef.class);
283 fpd.setKey(fpdTO.getKey());
284 fpd.setName(fpdTO.getName());
285 fpd.setType(fpdTO.getType());
286 fpd.setReadable(fpdTO.isReadable());
287 fpd.setWritable(fpdTO.isWritable());
288 fpd.setStringRegExp(fpdTO.getStringRegEx());
289 fpd.setRequired(fpdTO.isRequired());
290 fpd.setDatePattern(fpdTO.getDatePattern());
291 fpd.setEnumValues(fpdTO.getEnumValues());
292 fpd.setDropdownSingleSelection(fpdTO.isDropdownSingleSelection());
293 fpd.setDropdownFreeForm(fpdTO.isDropdownFreeForm());
294
295 fpd.setMacroTask(macroTask);
296 macroTask.add(fpd);
297 });
298
299 if (macroTaskTO.getMacroActions() == null) {
300 macroTask.setMacroAction(null);
301 } else {
302 Optional.ofNullable(implementationDAO.find(macroTaskTO.getMacroActions())).ifPresentOrElse(
303 macroTask::setMacroAction,
304 () -> LOG.debug("Invalid Implementation {}, ignoring...", macroTaskTO.getMacroActions()));
305 }
306 }
307
308 @Override
309 public SchedTask createSchedTask(final SchedTaskTO taskTO, final TaskUtils taskUtils) {
310 Class<? extends TaskTO> taskTOClass = taskUtils.taskTOClass();
311 if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
312 throw new IllegalArgumentException(String.format("Expected %s, found %s", taskTOClass, taskTO.getClass()));
313 }
314
315 SchedTask task = taskUtils.newTask();
316 task.setStartAt(taskTO.getStartAt());
317 task.setCronExpression(taskTO.getCronExpression());
318 task.setName(taskTO.getName());
319 task.setDescription(taskTO.getDescription());
320 task.setActive(taskTO.isActive());
321
322 if (taskUtils.getType() == TaskType.SCHEDULED) {
323 task.setJobDelegate(Optional.ofNullable(implementationDAO.find(taskTO.getJobDelegate())).
324 orElseThrow(() -> new NotFoundException("JobDelegate " + taskTO.getJobDelegate())));
325 } else if (taskTO instanceof MacroTaskTO) {
326 MacroTaskTO macroTaskTO = (MacroTaskTO) taskTO;
327 MacroTask macroTask = (MacroTask) task;
328
329 Implementation jobDelegate = macroTaskTO.getJobDelegate() == null
330 ? implementationDAO.findByType(IdRepoImplementationType.TASKJOB_DELEGATE).stream().
331 filter(impl -> MacroJobDelegate.class.getName().equals(impl.getBody())).
332 findFirst().orElse(null)
333 : implementationDAO.find(macroTaskTO.getJobDelegate());
334 if (jobDelegate == null) {
335 jobDelegate = entityFactory.newEntity(Implementation.class);
336 jobDelegate.setKey(MacroJobDelegate.class.getSimpleName());
337 jobDelegate.setEngine(ImplementationEngine.JAVA);
338 jobDelegate.setType(IdRepoImplementationType.TASKJOB_DELEGATE);
339 jobDelegate.setBody(MacroJobDelegate.class.getName());
340 jobDelegate = implementationDAO.save(jobDelegate);
341 }
342 macroTask.setJobDelegate(jobDelegate);
343
344 macroTask.setRealm(Optional.ofNullable(realmDAO.findByFullPath(macroTaskTO.getRealm())).
345 orElseThrow(() -> new NotFoundException("Realm " + macroTaskTO.getRealm())));
346
347 fill(macroTask, macroTaskTO);
348 } else if (taskTO instanceof ProvisioningTaskTO) {
349 ProvisioningTaskTO provisioningTaskTO = (ProvisioningTaskTO) taskTO;
350 ProvisioningTask<?> provisioningTask = (ProvisioningTask<?>) task;
351
352 provisioningTask.setResource(Optional.ofNullable(resourceDAO.find(provisioningTaskTO.getResource())).
353 orElseThrow(() -> new NotFoundException("Resource " + provisioningTaskTO.getResource())));
354
355 fill(provisioningTask, provisioningTaskTO);
356 }
357
358 return task;
359 }
360
361 @Override
362 public void updateSchedTask(final SchedTask task, final SchedTaskTO taskTO, final TaskUtils taskUtils) {
363 Class<? extends TaskTO> taskTOClass = taskUtils.taskTOClass();
364 if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
365 throw new IllegalArgumentException(String.format("Expected %s, found %s", taskTOClass, taskTO.getClass()));
366 }
367
368 if (StringUtils.isBlank(taskTO.getName())) {
369 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
370 sce.getElements().add("name");
371 throw sce;
372 }
373
374 task.setName(taskTO.getName());
375 task.setDescription(taskTO.getDescription());
376 task.setCronExpression(taskTO.getCronExpression());
377 task.setActive(taskTO.isActive());
378
379 if (task instanceof MacroTask) {
380 fill((MacroTask) task, (MacroTaskTO) taskTO);
381 } else if (task instanceof ProvisioningTask) {
382 fill((ProvisioningTask) task, (ProvisioningTaskTO) taskTO);
383 }
384 }
385
386 @Override
387 public String buildRefDesc(final Task<?> task) {
388 return taskUtilsFactory.getInstance(task).getType().name() + ' '
389 + "Task "
390 + task.getKey() + ' '
391 + (task instanceof SchedTask
392 ? SchedTask.class.cast(task).getName()
393 : task instanceof PropagationTask
394 ? PropagationTask.class.cast(task).getConnObjectKey()
395 : StringUtils.EMPTY);
396 }
397
398 @Override
399 public ExecTO getExecTO(final TaskExec<?> execution) {
400 ExecTO execTO = new ExecTO();
401 execTO.setKey(execution.getKey());
402 execTO.setStatus(execution.getStatus());
403 execTO.setMessage(execution.getMessage());
404 execTO.setStart(execution.getStart());
405 execTO.setEnd(execution.getEnd());
406 execTO.setExecutor(execution.getExecutor());
407
408 if (execution.getTask() != null && execution.getTask().getKey() != null) {
409 execTO.setJobType(JobType.TASK);
410 execTO.setRefKey(execution.getTask().getKey());
411 execTO.setRefDesc(buildRefDesc(execution.getTask()));
412 }
413
414 return execTO;
415 }
416
417 protected void fill(final SchedTaskTO schedTaskTO, final SchedTask schedTask) {
418 schedTaskTO.setName(schedTask.getName());
419 schedTaskTO.setDescription(schedTask.getDescription());
420 schedTaskTO.setCronExpression(schedTask.getCronExpression());
421 schedTaskTO.setActive(schedTask.isActive());
422
423 schedTaskTO.setLastExec(schedTaskTO.getStart());
424
425 String triggerName = JobNamer.getTriggerName(JobNamer.getJobKey(schedTask).getName());
426 try {
427 Trigger trigger = scheduler.getScheduler().getTrigger(new TriggerKey(triggerName, Scheduler.DEFAULT_GROUP));
428 if (trigger != null) {
429 schedTaskTO.setLastExec(toOffsetDateTime(trigger.getPreviousFireTime()));
430 schedTaskTO.setNextExec(toOffsetDateTime(trigger.getNextFireTime()));
431 }
432 } catch (SchedulerException e) {
433 LOG.warn("While trying to get to " + triggerName, e);
434 }
435
436 if (schedTaskTO instanceof ProvisioningTaskTO && schedTask instanceof ProvisioningTask) {
437 ProvisioningTaskTO provisioningTaskTO = (ProvisioningTaskTO) schedTaskTO;
438 ProvisioningTask<?> provisioningTask = (ProvisioningTask<?>) schedTask;
439
440 provisioningTaskTO.setResource(provisioningTask.getResource().getKey());
441
442 provisioningTaskTO.getActions().addAll(
443 provisioningTask.getActions().stream().map(Implementation::getKey).collect(Collectors.toList()));
444
445 provisioningTaskTO.setPerformCreate(provisioningTask.isPerformCreate());
446 provisioningTaskTO.setPerformUpdate(provisioningTask.isPerformUpdate());
447 provisioningTaskTO.setPerformDelete(provisioningTask.isPerformDelete());
448 provisioningTaskTO.setSyncStatus(provisioningTask.isSyncStatus());
449
450 provisioningTaskTO.setConcurrentSettings(provisioningTask.getConcurrentSettings());
451 }
452 }
453
454 @Override
455 public <T extends TaskTO> T getTaskTO(final Task<?> task, final TaskUtils taskUtils, final boolean details) {
456 T taskTO = taskUtils.newTaskTO();
457 taskTO.setKey(task.getKey());
458
459 Optional.ofNullable(taskExecDAO.findLatestStarted(taskUtils.getType(), task)).ifPresentOrElse(
460 latestExec -> {
461 taskTO.setLatestExecStatus(latestExec.getStatus());
462 taskTO.setStart(latestExec.getStart());
463 taskTO.setEnd(latestExec.getEnd());
464 taskTO.setLastExecutor(latestExec.getExecutor());
465 },
466 () -> taskTO.setLatestExecStatus(StringUtils.EMPTY));
467
468 if (details) {
469 task.getExecs().stream().
470 filter(Objects::nonNull).
471 forEach(execution -> taskTO.getExecutions().add(getExecTO(execution)));
472 }
473
474 switch (taskUtils.getType()) {
475 case PROPAGATION:
476 PropagationTask propagationTask = (PropagationTask) task;
477 PropagationTaskTO propagationTaskTO = (PropagationTaskTO) taskTO;
478
479 propagationTaskTO.setOperation(propagationTask.getOperation());
480 propagationTaskTO.setConnObjectKey(propagationTask.getConnObjectKey());
481 propagationTaskTO.setOldConnObjectKey(propagationTask.getOldConnObjectKey());
482 propagationTaskTO.setPropagationData(propagationTask.getSerializedPropagationData());
483 propagationTaskTO.setResource(propagationTask.getResource().getKey());
484 propagationTaskTO.setObjectClassName(propagationTask.getObjectClassName());
485 propagationTaskTO.setAnyTypeKind(propagationTask.getAnyTypeKind());
486 propagationTaskTO.setAnyType(propagationTask.getAnyType());
487 propagationTaskTO.setEntityKey(propagationTask.getEntityKey());
488 break;
489
490 case SCHEDULED:
491 SchedTask schedTask = (SchedTask) task;
492 SchedTaskTO schedTaskTO = (SchedTaskTO) taskTO;
493
494 fill(schedTaskTO, schedTask);
495
496 schedTaskTO.setJobDelegate(schedTask.getJobDelegate().getKey());
497 break;
498
499 case MACRO:
500 MacroTask macroTask = (MacroTask) task;
501 MacroTaskTO macroTaskTO = (MacroTaskTO) taskTO;
502
503 fill(macroTaskTO, macroTask);
504
505 macroTaskTO.setJobDelegate(macroTask.getJobDelegate().getKey());
506 macroTaskTO.setRealm(macroTask.getRealm().getFullPath());
507
508 macroTask.getCommands().forEach(mct -> macroTaskTO.getCommands().add(
509 new CommandTO.Builder(mct.getCommand().getKey()).args(mct.getArgs()).build()));
510
511 macroTaskTO.setContinueOnError(macroTask.isContinueOnError());
512 macroTaskTO.setSaveExecs(macroTask.isSaveExecs());
513
514 macroTask.getFormPropertyDefs().forEach(fpd -> {
515 FormPropertyDefTO fpdTO = new FormPropertyDefTO();
516 fpdTO.setKey(fpd.getKey());
517 fpdTO.setName(fpd.getName());
518 fpdTO.setType(fpd.getType());
519 fpdTO.setReadable(fpd.isReadable());
520 fpdTO.setWritable(fpd.isWritable());
521 fpdTO.setRequired(fpd.isRequired());
522 fpdTO.setStringRegEx(fpd.getStringRegEx());
523 fpdTO.setDatePattern(fpd.getDatePattern());
524 fpdTO.getEnumValues().putAll(fpd.getEnumValues());
525 fpdTO.setDropdownSingleSelection(fpd.isDropdownSingleSelection());
526 fpdTO.setDropdownFreeForm(fpd.isDropdownFreeForm());
527
528 macroTaskTO.getFormPropertyDefs().add(fpdTO);
529 });
530
531 Optional.ofNullable(macroTask.getMacroActions()).
532 ifPresent(fv -> macroTaskTO.setMacroActions(fv.getKey()));
533 break;
534
535 case PULL:
536 PullTask pullTask = (PullTask) task;
537 PullTaskTO pullTaskTO = (PullTaskTO) taskTO;
538
539 fill(pullTaskTO, pullTask);
540
541 pullTaskTO.setDestinationRealm(pullTask.getDestinationRealm().getFullPath());
542 pullTaskTO.setMatchingRule(pullTask.getMatchingRule() == null
543 ? MatchingRule.UPDATE : pullTask.getMatchingRule());
544 pullTaskTO.setUnmatchingRule(pullTask.getUnmatchingRule() == null
545 ? UnmatchingRule.PROVISION : pullTask.getUnmatchingRule());
546 pullTaskTO.setPullMode(pullTask.getPullMode());
547
548 Optional.ofNullable(pullTask.getReconFilterBuilder()).
549 ifPresent(rfb -> pullTaskTO.setReconFilterBuilder(rfb.getKey()));
550
551 pullTask.getTemplates().
552 forEach(template -> pullTaskTO.getTemplates().
553 put(template.getAnyType().getKey(), template.get()));
554
555 pullTaskTO.setRemediation(pullTask.isRemediation());
556 break;
557
558 case PUSH:
559 PushTask pushTask = (PushTask) task;
560 PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
561
562 fill(pushTaskTO, pushTask);
563
564 pushTaskTO.setSourceRealm(pushTask.getSourceRealm().getFullPath());
565 pushTaskTO.setMatchingRule(pushTask.getMatchingRule() == null
566 ? MatchingRule.LINK : pushTask.getMatchingRule());
567 pushTaskTO.setUnmatchingRule(pushTask.getUnmatchingRule() == null
568 ? UnmatchingRule.ASSIGN : pushTask.getUnmatchingRule());
569
570 pushTaskTO.getFilters().putAll(pushTask.getFilters());
571 break;
572
573 case NOTIFICATION:
574 NotificationTask notificationTask = (NotificationTask) task;
575 NotificationTaskTO notificationTaskTO = (NotificationTaskTO) taskTO;
576
577 notificationTaskTO.setNotification(notificationTask.getNotification().getKey());
578 notificationTaskTO.setAnyTypeKind(notificationTask.getAnyTypeKind());
579 notificationTaskTO.setEntityKey(notificationTask.getEntityKey());
580 notificationTaskTO.setSender(notificationTask.getSender());
581 notificationTaskTO.getRecipients().addAll(notificationTask.getRecipients());
582 notificationTaskTO.setSubject(notificationTask.getSubject());
583 notificationTaskTO.setHtmlBody(notificationTask.getHtmlBody());
584 notificationTaskTO.setTextBody(notificationTask.getTextBody());
585 notificationTaskTO.setExecuted(notificationTask.isExecuted());
586 if (notificationTask.isExecuted() && StringUtils.isBlank(taskTO.getLatestExecStatus())) {
587 taskTO.setLatestExecStatus("[EXECUTED]");
588 }
589 notificationTaskTO.setTraceLevel(notificationTask.getTraceLevel());
590 break;
591
592 default:
593 }
594
595 return taskTO;
596 }
597
598 @Override
599 public SyncopeForm getMacroTaskForm(final MacroTask task) {
600 if (task.getFormPropertyDefs().isEmpty()) {
601 throw new NotFoundException("No form properties defined for MacroTask " + task.getKey());
602 }
603
604 Optional<MacroActions> actions;
605 if (task.getMacroActions() == null) {
606 actions = Optional.empty();
607 } else {
608 try {
609 actions = Optional.of(ImplementationManager.build(
610 task.getMacroActions(),
611 () -> perContextMacroActions.get(task.getMacroActions().getKey()),
612 instance -> perContextMacroActions.put(task.getMacroActions().getKey(), instance)));
613 } catch (Exception e) {
614 LOG.error("Could not build {}", task.getMacroActions().getKey(), e);
615
616 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidImplementation);
617 sce.getElements().add("Could not build " + task.getMacroActions().getKey());
618 throw sce;
619 }
620 }
621
622 SyncopeForm form = new SyncopeForm();
623
624 form.getProperties().addAll(task.getFormPropertyDefs().stream().map(fpd -> {
625 FormProperty prop = new FormProperty();
626 prop.setId(fpd.getKey());
627 prop.setName(fpd.getName());
628 prop.setReadable(fpd.isReadable());
629 prop.setRequired(fpd.isRequired());
630 prop.setWritable(fpd.isWritable());
631 prop.setType(fpd.getType());
632 actions.flatMap(a -> a.getDefaultValue(fpd.getKey())).ifPresent(v -> prop.setValue(v));
633 switch (prop.getType()) {
634 case String:
635 prop.setStringRegEx(fpd.getStringRegEx());
636 break;
637
638 case Date:
639 prop.setDatePattern(fpd.getDatePattern());
640 break;
641
642 case Enum:
643 fpd.getEnumValues().
644 forEach((key, value) -> prop.getEnumValues().add(new FormPropertyValue(key, value)));
645 break;
646
647 case Dropdown:
648 actions.ifPresent(a -> a.getDropdownValues(fpd.getKey()).
649 forEach((key, value) -> prop.getDropdownValues().add(new FormPropertyValue(key, value))));
650 prop.setDropdownSingleSelection(fpd.isDropdownSingleSelection());
651 prop.setDropdownFreeForm(fpd.isDropdownFreeForm());
652 break;
653
654 default:
655 }
656 return prop;
657 }).collect(Collectors.toList()));
658
659 return form;
660 }
661 }