1 package edu.internet2.middleware.grouper.pspng;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.util.*;
20 import java.util.logging.Level;
21
22 import edu.internet2.middleware.grouper.changeLog.*;
23 import org.apache.commons.lang.builder.ToStringBuilder;
24 import org.joda.time.DateTime;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import edu.internet2.middleware.subject.Subject;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class ProvisioningWorkItem {
47 final private static Logger LOG = LoggerFactory.getLogger(Provisioner.class);
48
49 public enum WORK_ITEM_COMMAND {FULL_SYNC_GROUP, REMOVE_EXTRA_GROUPS, HANDLE_CHANGELOG_ENTRY};
50
51 protected final WORK_ITEM_COMMAND command;
52 protected final ChangeLogEntry work;
53 protected String groupName;
54
55 protected DateTime asOfDate;
56 protected Boolean success=null;
57 protected String status=null;
58 protected String statusMessage=null;
59
60
61
62
63
64
65 protected Map<String, Object> provisioningData = new HashMap<String,Object>();
66
67
68
69
70
71
72
73
74
75
76 protected ProvisioningWorkItem(WORK_ITEM_COMMAND command, GrouperGroupInfo group, DateTime asOfDate) {
77 this.command = command;
78 this.work = null;
79 this.asOfDate = asOfDate;
80
81 if ( group != null )
82 this.groupName=group.getName();
83 else
84 this.groupName=null;
85 }
86
87
88 public ProvisioningWorkItem(ChangeLogEntry work) {
89 this.command = WORK_ITEM_COMMAND.HANDLE_CHANGELOG_ENTRY;
90 this.work=work;
91 this.asOfDate = new DateTime(work.getCreatedOn().getTime());
92 }
93
94 public static ProvisioningWorkItem createForFullSync(GrouperGroupInfo grouperGroupInfo, DateTime asOfDate) {
95 return new ProvisioningWorkItem(WORK_ITEM_COMMAND.FULL_SYNC_GROUP, grouperGroupInfo, asOfDate);
96 }
97
98 public static ProvisioningWorkItem createForGroupCleanup(DateTime asOfDate) {
99 return new ProvisioningWorkItem(WORK_ITEM_COMMAND.REMOVE_EXTRA_GROUPS, null, asOfDate);
100 }
101
102
103
104 public ChangeLogEntry getChangelogEntry() {
105 return work;
106 }
107
108
109
110
111
112
113
114
115
116
117 private void setStatus(Level logLevel, String status, String statusMessageFormat, Object... statusMessageArgs)
118 {
119 this.status=status;
120 this.statusMessage = String.format(statusMessageFormat, statusMessageArgs);
121
122 String msg;
123 if ( success ) {
124 msg = "Work item handled: {}";
125 }
126 else {
127 msg = "Work item not handled; {}";
128 }
129
130
131 if ( logLevel == Level.INFO ) {
132 LOG.info(msg, this);
133 }
134 else if ( logLevel == Level.WARNING ) {
135 LOG.warn(msg, this);
136 }
137 else if ( logLevel == Level.SEVERE ) {
138 LOG.error(msg, this);
139 }
140 else {
141 LOG.debug(msg, this);
142 }
143 }
144
145 public void markAsSkippedAndWarn(String statusMessageFormat, Object... statusMessageArgs)
146 {
147 success = true;
148 setStatus(Level.WARNING, "done", statusMessageFormat, statusMessageArgs);
149 }
150
151 public void markAsSkipped(String statusMessageFormat, Object... statusMessageArgs)
152 {
153 if ( success != null ) {
154 return;
155 }
156
157 success = true;
158 setStatus(Level.FINE, "done", statusMessageFormat, statusMessageArgs);
159 }
160
161 public void markAsSuccess(String statusMessageFormat, Object... statusMessageArgs)
162 {
163 success = true;
164 setStatus(Level.INFO, "done", statusMessageFormat, statusMessageArgs);
165 }
166
167 public void markAsFailure(String statusMessageFormat, Object... statusMessageArgs)
168 {
169 success = false;
170 setStatus(Level.SEVERE, "failed", statusMessageFormat, statusMessageArgs);
171 }
172
173
174
175
176
177 public boolean hasBeenProcessed() {
178
179 return success != null;
180 }
181
182
183 private String getGroupName() {
184 if ( groupName != null )
185 return groupName;
186 else if ( getChangelogEntry() == null )
187 return null;
188
189 groupName = ChangelogHandlingConfig.getGroupName(getChangelogEntry());
190
191 return groupName;
192 }
193
194 public GrouperGroupInfo getGroupInfo(Provisioner provisioner) {
195 String groupName = getGroupName();
196 if ( groupName == null ) {
197 LOG.debug("Group name not found in work item: {}", this);
198 return null;
199 }
200
201 GrouperGroupInfo result = provisioner.getGroupInfo(this);
202
203 LOG.debug("WorkItem {} is related to Group: {}", this, result);
204 return result;
205 }
206
207
208
209
210
211 public Long getGroupIdIndex() {
212 return ChangelogHandlingConfig.getGroupId(getChangelogEntry());
213 }
214
215 public String getAttributeName() {
216 return ChangelogHandlingConfig.getAttributeName(getChangelogEntry());
217 }
218
219
220 private String getSubjectId() {
221 return ChangelogHandlingConfig.getSubjectId(getChangelogEntry());
222 }
223
224 private String getSubjectSourceId() {
225 return ChangelogHandlingConfig.getSubjectSource(getChangelogEntry());
226 }
227
228 public Subject getSubject(Provisioner provisioner) {
229 if ( getChangelogEntry() == null )
230 return null;
231
232 final String subjectId = getSubjectId();
233 final String sourceId = getSubjectSourceId();
234
235 if ( subjectId == null || sourceId == null )
236 return null;
237
238 Subject subject = provisioner.getSubject(subjectId, sourceId);
239
240 return subject;
241 }
242
243 public boolean isSubjectUnresolvable(Provisioner provisioner) {
244 if ( getSubjectId()==null || getSubjectSourceId()==null ) {
245
246 return false;
247 }
248
249
250
251 if ( getSubject(provisioner)==null ) {
252 LOG.warn("Subject not found: {}@{}", getSubjectId(), getSubjectSourceId());
253 return true;
254 }
255
256
257 return false;
258 }
259
260
261 public void putProvisioningData(String key, Object value)
262 {
263 provisioningData.put(key, value);
264 }
265
266 public Object getProvisioningDataValue(String key)
267 {
268 return provisioningData.get(key);
269 }
270
271 public void addValueToProvisioningData(String key, Object value) {
272 List<Object> valueArray = (List) provisioningData.get(key);
273
274 if ( valueArray == null )
275 {
276 synchronized (provisioningData) {
277
278 if ( !provisioningData.containsKey(key) )
279 provisioningData.put(key, new ArrayList<Object>());
280
281 valueArray = (List) provisioningData.get(key);
282 }
283 }
284
285 valueArray.add(value);
286 }
287
288 public List<Object> getProvisioningDataValues(String key) {
289 return (List<Object>) provisioningData.get(key);
290 }
291
292 public boolean wasSuccessful() {
293 if ( success == null )
294 return false;
295
296 return success;
297 }
298
299 public boolean wasError() {
300 return !wasSuccessful();
301 }
302
303 public String getStatusMessage() {
304 return statusMessage;
305 }
306
307 @Override
308 public String toString() {
309 ToStringBuilder tsb = new ToStringBuilder(this)
310 .append("done", hasBeenProcessed() )
311 .append("successful", success)
312 .append("msg", statusMessage);
313
314 if ( work == null )
315 tsb.append("cmd", command);
316 else {
317 String groupName = getGroupName();
318 String subjectId = getSubjectId();
319 String subjectSourceId = getSubjectSourceId();
320
321 tsb.append("clog", String.format("clog #%d / %s", work.getSequenceNumber(), work.getChangeLogType()));
322 if ( groupName != null )
323 tsb.append("group", groupName);
324 if ( subjectId != null )
325 tsb.append("subject", String.format("%s@%s", subjectId, subjectSourceId));
326 }
327 return tsb.toString();
328 }
329
330
331 public String getMdcLabel() {
332 if ( work != null )
333 return String.format("%d/", work.getSequenceNumber());
334 else
335 return String.format("%s/", command);
336 }
337
338
339
340
341
342
343
344 public boolean matchesChangelogType(ChangeLogTypeBuiltin type) {
345 if ( getChangelogEntry() == null ) {
346 return false;
347 }
348
349 return getChangelogEntry().getChangeLogType().equalsCategoryAndAction(type);
350 }
351
352
353
354
355
356
357
358 public boolean matchesChangelogType(Collection<ChangeLogTypeBuiltin> types) {
359 return ChangelogHandlingConfig.containsChangelogEntryType(types, getChangelogEntry());
360 }
361 }