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;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.stream.Collectors;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.lang3.tuple.Pair;
29 import org.apache.syncope.common.lib.request.GroupCR;
30 import org.apache.syncope.common.lib.request.GroupUR;
31 import org.apache.syncope.common.lib.to.PropagationStatus;
32 import org.apache.syncope.common.lib.types.AnyTypeKind;
33 import org.apache.syncope.common.lib.types.ResourceOperation;
34 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
35 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
36 import org.apache.syncope.core.provisioning.api.PropagationByResource;
37 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
38 import org.apache.syncope.core.provisioning.api.WorkflowResult;
39 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
40 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
41 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
42 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
43 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
44 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
45 import org.identityconnectors.framework.common.objects.Attribute;
46 import org.springframework.transaction.annotation.Propagation;
47 import org.springframework.transaction.annotation.Transactional;
48
49 public class DefaultGroupProvisioningManager implements GroupProvisioningManager {
50
51 protected final GroupWorkflowAdapter gwfAdapter;
52
53 protected final PropagationManager propagationManager;
54
55 protected final PropagationTaskExecutor taskExecutor;
56
57 protected final GroupDataBinder groupDataBinder;
58
59 protected final GroupDAO groupDAO;
60
61 protected final VirAttrHandler virtAttrHandler;
62
63 public DefaultGroupProvisioningManager(
64 final GroupWorkflowAdapter gwfAdapter,
65 final PropagationManager propagationManager,
66 final PropagationTaskExecutor taskExecutor,
67 final GroupDataBinder groupDataBinder,
68 final GroupDAO groupDAO,
69 final VirAttrHandler virtAttrHandler) {
70
71 this.gwfAdapter = gwfAdapter;
72 this.propagationManager = propagationManager;
73 this.taskExecutor = taskExecutor;
74 this.groupDataBinder = groupDataBinder;
75 this.groupDAO = groupDAO;
76 this.virtAttrHandler = virtAttrHandler;
77 }
78
79 @Override
80 public Pair<String, List<PropagationStatus>> create(
81 final GroupCR groupCR, final boolean nullPriorityAsync, final String creator, final String context) {
82
83 WorkflowResult<String> created = gwfAdapter.create(groupCR, creator, context);
84
85 List<PropagationTaskInfo> tasks = propagationManager.getCreateTasks(
86 AnyTypeKind.GROUP,
87 created.getResult(),
88 null,
89 created.getPropByRes(),
90 groupCR.getVirAttrs(),
91 Set.of());
92 PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, creator);
93
94 return Pair.of(created.getResult(), propagationReporter.getStatuses());
95 }
96
97 @Transactional(propagation = Propagation.REQUIRES_NEW)
98 @Override
99 public Pair<String, List<PropagationStatus>> create(
100 final GroupCR groupCR,
101 final Map<String, String> groupOwnerMap,
102 final Set<String> excludedResources,
103 final boolean nullPriorityAsync,
104 final String creator,
105 final String context) {
106
107 WorkflowResult<String> created = gwfAdapter.create(groupCR, creator, context);
108
109
110 groupCR.getPlainAttr(StringUtils.EMPTY).
111 ifPresent(groupOwner -> groupOwnerMap.put(created.getResult(), groupOwner.getValues().get(0)));
112
113 List<PropagationTaskInfo> tasks = propagationManager.getCreateTasks(
114 AnyTypeKind.GROUP,
115 created.getResult(),
116 null,
117 created.getPropByRes(),
118 groupCR.getVirAttrs(),
119 excludedResources);
120 PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, creator);
121
122 return Pair.of(created.getResult(), propagationReporter.getStatuses());
123 }
124
125 @Transactional(propagation = Propagation.REQUIRES_NEW)
126 @Override
127 public Pair<GroupUR, List<PropagationStatus>> update(
128 final GroupUR groupUR,
129 final Set<String> excludedResources,
130 final boolean nullPriorityAsync,
131 final String updater,
132 final String context) {
133
134 Map<Pair<String, String>, Set<Attribute>> beforeAttrs = propagationManager.prepareAttrs(
135 AnyTypeKind.GROUP,
136 groupUR.getKey(),
137 null,
138 false,
139 null,
140 excludedResources);
141
142 WorkflowResult<GroupUR> updated = gwfAdapter.update(groupUR, updater, context);
143
144 List<PropagationTaskInfo> tasks = propagationManager.setAttributeDeltas(
145 propagationManager.getUpdateTasks(
146 AnyTypeKind.GROUP,
147 updated.getResult().getKey(),
148 false,
149 null,
150 updated.getPropByRes(),
151 null,
152 groupUR.getVirAttrs(),
153 excludedResources),
154 beforeAttrs,
155 updated.getResult());
156 PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, updater);
157
158 return Pair.of(updated.getResult(), propagationReporter.getStatuses());
159 }
160
161 @Override
162 public List<PropagationStatus> delete(
163 final String key, final boolean nullPriorityAsync, final String eraser, final String context) {
164
165 return delete(key, Set.of(), nullPriorityAsync, eraser, context);
166 }
167
168 @Transactional(propagation = Propagation.REQUIRES_NEW)
169 @Override
170 public List<PropagationStatus> delete(
171 final String key,
172 final Set<String> excludedResources,
173 final boolean nullPriorityAsync,
174 final String eraser,
175 final String context) {
176
177 List<PropagationTaskInfo> taskInfos = new ArrayList<>();
178
179
180
181 groupDataBinder.findUsersWithTransitiveResources(key).forEach((anyKey, propByRes) -> {
182 taskInfos.addAll(propagationManager.getDeleteTasks(
183 AnyTypeKind.USER,
184 anyKey,
185 propByRes,
186 null,
187 excludedResources));
188 });
189 groupDataBinder.findAnyObjectsWithTransitiveResources(key).forEach((anyKey, propByRes) -> {
190 taskInfos.addAll(propagationManager.getDeleteTasks(
191 AnyTypeKind.ANY_OBJECT,
192 anyKey,
193 propByRes,
194 null,
195 excludedResources));
196 });
197
198
199 taskInfos.addAll(propagationManager.getDeleteTasks(
200 AnyTypeKind.GROUP,
201 key,
202 null,
203 null,
204 null));
205
206 PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, eraser);
207
208 gwfAdapter.delete(key, eraser, context);
209
210 return propagationReporter.getStatuses();
211 }
212
213 @Override
214 public String link(final GroupUR groupUR, final String updater, final String context) {
215 return gwfAdapter.update(groupUR, updater, context).getResult().getKey();
216 }
217
218 @Override
219 public String unlink(final GroupUR groupUR, final String updater, final String context) {
220 return gwfAdapter.update(groupUR, updater, context).getResult().getKey();
221 }
222
223 @Override
224 public List<PropagationStatus> provision(
225 final String key,
226 final Collection<String> resources,
227 final boolean nullPriorityAsync,
228 final String executor) {
229
230 PropagationByResource<String> propByRes = new PropagationByResource<>();
231 propByRes.addAll(ResourceOperation.UPDATE, resources);
232
233 List<PropagationTaskInfo> taskInfos = propagationManager.getUpdateTasks(
234 AnyTypeKind.GROUP,
235 key,
236 false,
237 null,
238 propByRes,
239 null,
240 null,
241 null);
242 PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, executor);
243
244 return propagationReporter.getStatuses();
245 }
246
247 @Override
248 public List<PropagationStatus> deprovision(
249 final String key,
250 final Collection<String> resources,
251 final boolean nullPriorityAsync,
252 final String executor) {
253
254 PropagationByResource<String> propByRes = new PropagationByResource<>();
255 propByRes.addAll(ResourceOperation.DELETE, resources);
256
257 List<PropagationTaskInfo> taskInfos = propagationManager.getDeleteTasks(
258 AnyTypeKind.GROUP,
259 key,
260 propByRes,
261 null,
262 groupDAO.findAllResourceKeys(key).stream().
263 filter(resource -> !resources.contains(resource)).
264 collect(Collectors.toList()));
265 PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, executor);
266
267 return propagationReporter.getStatuses();
268 }
269 }