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.pushpull;
20
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Objects;
24 import java.util.Set;
25 import java.util.stream.Collectors;
26 import java.util.stream.Stream;
27 import org.apache.syncope.common.lib.to.Item;
28 import org.apache.syncope.common.lib.to.Provision;
29 import org.apache.syncope.common.lib.to.ProvisioningReport;
30 import org.apache.syncope.common.lib.to.PullTaskTO;
31 import org.apache.syncope.common.lib.types.ClientExceptionType;
32 import org.apache.syncope.common.lib.types.ConflictResolutionAction;
33 import org.apache.syncope.common.lib.types.MatchingRule;
34 import org.apache.syncope.common.lib.types.PullMode;
35 import org.apache.syncope.common.lib.types.TaskType;
36 import org.apache.syncope.common.lib.types.UnmatchingRule;
37 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
38 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
39 import org.apache.syncope.core.persistence.api.entity.AnyType;
40 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
41 import org.apache.syncope.core.persistence.api.entity.VirSchema;
42 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
43 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
44 import org.apache.syncope.core.provisioning.api.Connector;
45 import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
46 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
47 import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
48 import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder;
49 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
50 import org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePullExecutor;
51 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
52 import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
53 import org.identityconnectors.framework.common.objects.ObjectClass;
54 import org.quartz.JobExecutionException;
55 import org.springframework.beans.factory.annotation.Autowired;
56
57 public class SinglePullJobDelegate extends PullJobDelegate implements SyncopeSinglePullExecutor {
58
59 @Autowired
60 protected ImplementationDAO implementationDAO;
61
62 @Autowired
63 protected RealmDAO realmDAO;
64
65 @Override
66 public List<ProvisioningReport> pull(
67 final ExternalResource resource,
68 final Provision provision,
69 final Connector connector,
70 final ReconFilterBuilder reconFilterBuilder,
71 final Set<String> moreAttrsToGet,
72 final PullTaskTO pullTaskTO,
73 final String executor) throws JobExecutionException {
74
75 LOG.debug("Executing pull on {}", resource);
76
77 taskType = TaskType.PULL;
78 try {
79 task = entityFactory.newEntity(PullTask.class);
80 task.setResource(resource);
81 task.setMatchingRule(pullTaskTO.getMatchingRule() == null
82 ? MatchingRule.UPDATE : pullTaskTO.getMatchingRule());
83 task.setUnmatchingRule(pullTaskTO.getUnmatchingRule() == null
84 ? UnmatchingRule.PROVISION : pullTaskTO.getUnmatchingRule());
85 task.setPullMode(PullMode.FILTERED_RECONCILIATION);
86 task.setPerformCreate(pullTaskTO.isPerformCreate());
87 task.setPerformUpdate(pullTaskTO.isPerformUpdate());
88 task.setPerformDelete(pullTaskTO.isPerformDelete());
89 task.setSyncStatus(pullTaskTO.isSyncStatus());
90 task.setDestinationRealm(realmDAO.findByFullPath(pullTaskTO.getDestinationRealm()));
91 task.setRemediation(pullTaskTO.isRemediation());
92
93
94 TemplateUtils.check(pullTaskTO.getTemplates(), ClientExceptionType.InvalidPullTask);
95 pullTaskTO.getTemplates().forEach((type, template) -> {
96 AnyType anyType = anyTypeDAO.find(type);
97 if (anyType == null) {
98 LOG.debug("Invalid AnyType {} specified, ignoring...", type);
99 } else {
100 AnyTemplatePullTask anyTemplate = task.getTemplate(anyType.getKey()).orElse(null);
101 if (anyTemplate == null) {
102 anyTemplate = entityFactory.newEntity(AnyTemplatePullTask.class);
103 anyTemplate.setAnyType(anyType);
104 anyTemplate.setPullTask(task);
105
106 task.add(anyTemplate);
107 }
108 anyTemplate.set(template);
109 }
110 });
111
112 profile = new ProvisioningProfile<>(connector, task);
113 profile.setDryRun(false);
114 profile.setConflictResolutionAction(ConflictResolutionAction.FIRSTMATCH);
115 profile.getActions().addAll(getPullActions(pullTaskTO.getActions().stream().
116 map(implementationDAO::find).filter(Objects::nonNull).collect(Collectors.toList())));
117 profile.setExecutor(executor);
118
119 for (PullActions action : profile.getActions()) {
120 action.beforeAll(profile);
121 }
122
123 AnyType anyType = anyTypeDAO.find(provision.getAnyType());
124
125 SyncopePullResultHandler handler;
126 GroupPullResultHandler ghandler = buildGroupHandler();
127 switch (anyType.getKind()) {
128 case USER:
129 handler = buildUserHandler();
130 break;
131
132 case GROUP:
133 handler = ghandler;
134 break;
135
136 case ANY_OBJECT:
137 default:
138 handler = buildAnyObjectHandler();
139 }
140 handler.setProfile(profile);
141
142
143 Set<String> matg = new HashSet<>(moreAttrsToGet);
144 profile.getActions().forEach(a -> matg.addAll(a.moreAttrsToGet(profile, provision)));
145
146 Stream<Item> mapItems = Stream.concat(
147 MappingUtils.getPullItems(provision.getMapping().getItems().stream()),
148 virSchemaDAO.find(task.getResource().getKey(), anyType.getKey()).stream().
149 map(VirSchema::asLinkingMappingItem));
150
151 connector.filteredReconciliation(
152 new ObjectClass(provision.getObjectClass()),
153 reconFilterBuilder,
154 handler,
155 MappingUtils.buildOperationOptions(mapItems, matg.toArray(String[]::new)));
156
157 try {
158 setGroupOwners(ghandler);
159 } catch (Exception e) {
160 LOG.error("While setting group owners", e);
161 }
162
163 for (PullActions action : profile.getActions()) {
164 action.afterAll(profile);
165 }
166
167 return profile.getResults();
168 } catch (Exception e) {
169 throw e instanceof JobExecutionException
170 ? (JobExecutionException) e
171 : new JobExecutionException("While pulling from connector", e);
172 } finally {
173 setStatus(null);
174 }
175 }
176 }