use of javax.xml.datatype.Duration in project midpoint by Evolveum.
the class TaskManagerQuartzImpl method cleanupTasks.
@Override
public void cleanupTasks(CleanupPolicyType policy, Task executionTask, OperationResult parentResult) throws SchemaException {
OperationResult result = parentResult.createSubresult(CLEANUP_TASKS);
if (policy.getMaxAge() == null) {
return;
}
Duration duration = policy.getMaxAge();
if (duration.getSign() > 0) {
duration = duration.negate();
}
Date deleteTasksClosedUpTo = new Date();
duration.addTo(deleteTasksClosedUpTo);
LOGGER.info("Starting cleanup for closed tasks deleting up to {} (duration '{}').", new Object[] { deleteTasksClosedUpTo, duration });
XMLGregorianCalendar timeXml = XmlTypeConverter.createXMLGregorianCalendar(deleteTasksClosedUpTo.getTime());
List<PrismObject<TaskType>> obsoleteTasks;
try {
ObjectQuery obsoleteTasksQuery = QueryBuilder.queryFor(TaskType.class, prismContext).item(TaskType.F_COMPLETION_TIMESTAMP).le(timeXml).and().item(TaskType.F_PARENT).isNull().build();
obsoleteTasks = repositoryService.searchObjects(TaskType.class, obsoleteTasksQuery, null, result);
} catch (SchemaException e) {
throw new SchemaException("Couldn't get the list of obsolete tasks: " + e.getMessage(), e);
}
// enable when having enough time
// result.createSubresult(result.getOperation()+".count").recordStatus(SUCCESS, "Task tree(s) to be deleted: " + obsoleteTasks.size());
// // show the result immediately
// try {
// executionTask.setResultImmediate(executionTask.getResult(), new OperationResult("dummy"));
// } catch (ObjectNotFoundException e) {
// LoggingUtils.logUnexpectedException(LOGGER, "Task {} does not exist", e, executionTask);
// }
LOGGER.debug("Found {} task tree(s) to be cleaned up", obsoleteTasks.size());
boolean interrupted = false;
int deleted = 0;
int problems = 0;
int bigProblems = 0;
for (PrismObject<TaskType> rootTaskPrism : obsoleteTasks) {
if (!executionTask.canRun()) {
result.recordWarning("Interrupted");
LOGGER.warn("Task cleanup was interrupted.");
interrupted = true;
break;
}
final String taskName = PolyString.getOrig(rootTaskPrism.getName());
final String taskOid = rootTaskPrism.getOid();
final long started = System.currentTimeMillis();
executionTask.recordIterativeOperationStart(taskName, null, TaskType.COMPLEX_TYPE, taskOid);
try {
// get whole tree
Task rootTask = createTaskInstance(rootTaskPrism, result);
List<Task> taskTreeMembers = rootTask.listSubtasksDeeply(result);
taskTreeMembers.add(rootTask);
LOGGER.trace("Removing task {} along with its {} children.", rootTask, taskTreeMembers.size() - 1);
Throwable lastProblem = null;
for (Task task : taskTreeMembers) {
try {
deleteTask(task.getOid(), result);
deleted++;
} catch (SchemaException | ObjectNotFoundException | RuntimeException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't delete obsolete task {}", e, task);
lastProblem = e;
problems++;
if (!task.getTaskIdentifier().equals(rootTask.getTaskIdentifier())) {
bigProblems++;
}
}
}
// approximate solution (as the problem might be connected to a subtask)
executionTask.recordIterativeOperationEnd(taskName, null, TaskType.COMPLEX_TYPE, taskOid, started, lastProblem);
} catch (Throwable t) {
executionTask.recordIterativeOperationEnd(taskName, null, TaskType.COMPLEX_TYPE, taskOid, started, t);
throw t;
}
}
result.computeStatusIfUnknown();
LOGGER.info("Task cleanup procedure " + (interrupted ? "was interrupted" : "finished") + ". Successfully deleted {} tasks; there were problems with deleting {} tasks.", deleted, problems);
if (bigProblems > 0) {
LOGGER.error("{} subtask(s) couldn't be deleted. Inspect that manually, otherwise they might reside in repo forever.", bigProblems);
}
String suffix = interrupted ? " Interrupted." : "";
if (problems == 0) {
parentResult.createSubresult(CLEANUP_TASKS + ".statistics").recordStatus(SUCCESS, "Successfully deleted " + deleted + " task(s)." + suffix);
} else {
parentResult.createSubresult(CLEANUP_TASKS + ".statistics").recordPartialError("Successfully deleted " + deleted + " task(s), " + "there was problems with deleting " + problems + " tasks." + suffix + (bigProblems > 0 ? (" " + bigProblems + " subtask(s) couldn't be deleted, please see the log.") : ""));
}
}
use of javax.xml.datatype.Duration in project midpoint by Evolveum.
the class WfContextUtil method createTriggers.
@NotNull
public static List<TriggerType> createTriggers(int escalationLevel, Date workItemCreateTime, Date workItemDeadline, List<WorkItemTimedActionsType> timedActionsList, PrismContext prismContext, Trace logger, @Nullable String workItemId, @NotNull String handlerUri) throws SchemaException {
List<TriggerType> triggers = new ArrayList<>();
for (WorkItemTimedActionsType timedActionsEntry : timedActionsList) {
Integer levelFrom;
Integer levelTo;
if (timedActionsEntry.getEscalationLevelFrom() == null && timedActionsEntry.getEscalationLevelTo() == null) {
levelFrom = levelTo = 0;
} else {
levelFrom = timedActionsEntry.getEscalationLevelFrom();
levelTo = timedActionsEntry.getEscalationLevelTo();
}
if (levelFrom != null && escalationLevel < levelFrom) {
logger.trace("Current escalation level is before 'escalationFrom', skipping timed actions {}", timedActionsEntry);
continue;
}
if (levelTo != null && escalationLevel > levelTo) {
logger.trace("Current escalation level is after 'escalationTo', skipping timed actions {}", timedActionsEntry);
continue;
}
// TODO evaluate the condition
List<TimedActionTimeSpecificationType> timeSpecifications = CloneUtil.cloneCollectionMembers(timedActionsEntry.getTime());
if (timeSpecifications.isEmpty()) {
timeSpecifications.add(new TimedActionTimeSpecificationType());
}
for (TimedActionTimeSpecificationType timeSpec : timeSpecifications) {
if (timeSpec.getValue().isEmpty()) {
timeSpec.getValue().add(XmlTypeConverter.createDuration(0));
}
for (Duration duration : timeSpec.getValue()) {
XMLGregorianCalendar mainTriggerTime = computeTriggerTime(duration, timeSpec.getBase(), workItemCreateTime, workItemDeadline);
TriggerType mainTrigger = createTrigger(mainTriggerTime, timedActionsEntry.getActions(), null, prismContext, workItemId, handlerUri);
triggers.add(mainTrigger);
List<Pair<Duration, AbstractWorkItemActionType>> notifyInfoList = getNotifyBefore(timedActionsEntry);
for (Pair<Duration, AbstractWorkItemActionType> notifyInfo : notifyInfoList) {
XMLGregorianCalendar notifyTime = (XMLGregorianCalendar) mainTriggerTime.clone();
notifyTime.add(notifyInfo.getKey().negate());
TriggerType notifyTrigger = createTrigger(notifyTime, null, notifyInfo, prismContext, workItemId, handlerUri);
triggers.add(notifyTrigger);
}
}
}
}
return triggers;
}
use of javax.xml.datatype.Duration in project midpoint by Evolveum.
the class ShadowCache method refreshShadow.
public PrismObject<ShadowType> refreshShadow(PrismObject<ShadowType> repoShadow, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
ShadowType shadowType = repoShadow.asObjectable();
List<PendingOperationType> pendingOperations = shadowType.getPendingOperation();
if (pendingOperations.isEmpty()) {
LOGGER.trace("Skipping refresh of {} because there are no pending operations", repoShadow);
return repoShadow;
}
LOGGER.trace("Refreshing {}", repoShadow);
ProvisioningContext ctx = ctxFactory.create(repoShadow, task, parentResult);
ctx.assertDefinition();
Duration gracePeriod = null;
ResourceConsistencyType consistency = ctx.getResource().getConsistency();
if (consistency != null) {
gracePeriod = consistency.getPendingOperationGracePeriod();
}
List<ObjectDelta<ShadowType>> notificationDeltas = new ArrayList<>();
List<PendingOperationType> sortedOperations = sortOperations(pendingOperations);
boolean isDead = ShadowUtil.isDead(shadowType);
ObjectDelta<ShadowType> shadowDelta = repoShadow.createModifyDelta();
for (PendingOperationType pendingOperation : sortedOperations) {
ItemPath containerPath = pendingOperation.asPrismContainerValue().getPath();
OperationResultStatusType statusType = pendingOperation.getResultStatus();
XMLGregorianCalendar completionTimestamp = pendingOperation.getCompletionTimestamp();
XMLGregorianCalendar now = null;
String asyncRef = pendingOperation.getAsynchronousOperationReference();
if (asyncRef != null) {
OperationResultStatus newStaus = resouceObjectConverter.refreshOperationStatus(ctx, repoShadow, asyncRef, parentResult);
now = clock.currentTimeXMLGregorianCalendar();
if (newStaus != null) {
OperationResultStatusType newStatusType = newStaus.createStatusType();
if (!newStatusType.equals(pendingOperation.getResultStatus())) {
boolean operationCompleted = isCompleted(newStatusType) && pendingOperation.getCompletionTimestamp() == null;
if (operationCompleted && gracePeriod == null) {
LOGGER.trace("Deleting pending operation because it is completed (no grace): {}", pendingOperation);
shadowDelta.addModificationDeleteContainer(new ItemPath(ShadowType.F_PENDING_OPERATION), pendingOperation.clone());
continue;
} else {
PropertyDelta<OperationResultStatusType> statusDelta = shadowDelta.createPropertyModification(containerPath.subPath(PendingOperationType.F_RESULT_STATUS));
statusDelta.setValuesToReplace(new PrismPropertyValue<>(newStatusType));
shadowDelta.addModification(statusDelta);
}
statusType = newStatusType;
if (operationCompleted) {
// Operation completed
PropertyDelta<XMLGregorianCalendar> timestampDelta = shadowDelta.createPropertyModification(containerPath.subPath(PendingOperationType.F_COMPLETION_TIMESTAMP));
timestampDelta.setValuesToReplace(new PrismPropertyValue<>(now));
shadowDelta.addModification(timestampDelta);
completionTimestamp = now;
ObjectDeltaType pendingDeltaType = pendingOperation.getDelta();
ObjectDelta<ShadowType> pendingDelta = DeltaConvertor.createObjectDelta(pendingDeltaType, prismContext);
if (pendingDelta.isAdd()) {
// We do not need to care about attributes in add deltas here. The add operation is already applied to
// attributes. We need this to "allocate" the identifiers, so iteration mechanism in the
// model can find unique values while taking pending create operations into consideration.
PropertyDelta<Boolean> existsDelta = shadowDelta.createPropertyModification(new ItemPath(ShadowType.F_EXISTS));
existsDelta.setValuesToReplace(new PrismPropertyValue<>(true));
shadowDelta.addModification(existsDelta);
}
if (pendingDelta.isModify()) {
for (ItemDelta<?, ?> pendingModification : pendingDelta.getModifications()) {
shadowDelta.addModification(pendingModification.clone());
}
}
if (pendingDelta.isDelete()) {
isDead = true;
if (gracePeriod == null) {
shadowDelta = repoShadow.createDeleteDelta();
notificationDeltas.add(pendingDelta);
break;
} else {
PropertyDelta<Boolean> deadDelta = shadowDelta.createPropertyModification(new ItemPath(ShadowType.F_DEAD));
deadDelta.setValuesToReplace(new PrismPropertyValue<>(true));
shadowDelta.addModification(deadDelta);
PropertyDelta<Boolean> existsDelta = shadowDelta.createPropertyModification(new ItemPath(ShadowType.F_EXISTS));
existsDelta.setValuesToReplace(new PrismPropertyValue<>(false));
shadowDelta.addModification(existsDelta);
}
}
notificationDeltas.add(pendingDelta);
}
}
}
}
if (now == null) {
now = clock.currentTimeXMLGregorianCalendar();
}
}
if (shadowDelta.isDelete()) {
LOGGER.trace("Deleting dead shadow because pending delete delta was completed (no grace period): {}", repoShadow);
shadowManager.deleteShadow(ctx, repoShadow, null, parentResult);
return null;
}
XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar();
boolean atLeastOnePendingOperationRemains = expirePendingOperations(ctx, repoShadow, shadowDelta, now, parentResult);
if (shadowType.getFailedOperationType() != null) {
atLeastOnePendingOperationRemains = true;
}
if (isDead && !atLeastOnePendingOperationRemains) {
LOGGER.trace("Deleting dead shadow because all pending operations expired: {}", repoShadow);
shadowManager.deleteShadow(ctx, repoShadow, null, parentResult);
return null;
}
if (!shadowDelta.isEmpty()) {
shadowManager.modifyShadowAttributes(ctx, repoShadow, shadowDelta.getModifications(), parentResult);
}
for (ObjectDelta<ShadowType> notificationDelta : notificationDeltas) {
ResourceOperationDescription operationDescription = createSuccessOperationDescription(ctx, repoShadow, notificationDelta, parentResult);
operationListener.notifySuccess(operationDescription, task, parentResult);
}
if (shadowDelta.isEmpty()) {
return repoShadow;
}
shadowDelta.applyTo(repoShadow);
return repoShadow;
}
use of javax.xml.datatype.Duration in project midpoint by Evolveum.
the class TestPrismParsing method assertUserWillExtension.
private void assertUserWillExtension(PrismObject<UserType> user) {
PrismContainer<?> extension = user.getExtension();
assertContainerDefinition(extension, "extension", DOMUtil.XSD_ANY, 0, 1);
PrismContainerValue<?> extensionValue = extension.getValue();
assertTrue("Extension parent", extensionValue.getParent() == extension);
assertNull("Extension ID", extensionValue.getId());
PrismProperty<String> stringType = extension.findProperty(EXTENSION_STRING_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(stringType, "BARbar", "FOObar");
PrismPropertyDefinition stringTypePropertyDef = stringType.getDefinition();
PrismAsserts.assertDefinition(stringTypePropertyDef, EXTENSION_STRING_TYPE_ELEMENT, DOMUtil.XSD_STRING, 0, -1);
assertNull("'Indexed' attribute on 'stringType' property is not null", stringTypePropertyDef.isIndexed());
PrismProperty<String> singleStringType = extension.findProperty(EXTENSION_SINGLE_STRING_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(singleStringType, "foobar");
PrismPropertyDefinition singleStringTypePropertyDef = singleStringType.getDefinition();
PrismAsserts.assertDefinition(singleStringTypePropertyDef, EXTENSION_SINGLE_STRING_TYPE_ELEMENT, DOMUtil.XSD_STRING, 0, 1);
assertNull("'Indexed' attribute on 'singleStringType' property is not null", singleStringTypePropertyDef.isIndexed());
PrismProperty<Double> doubleType = extension.findProperty(EXTENSION_DOUBLE_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(doubleType, 3.1415926535);
PrismPropertyDefinition doubleTypePropertyDef = doubleType.getDefinition();
PrismAsserts.assertDefinition(doubleTypePropertyDef, EXTENSION_DOUBLE_TYPE_ELEMENT, DOMUtil.XSD_DOUBLE, 0, -1);
assertNull("'Indexed' attribute on 'doubleType' property is not null", doubleTypePropertyDef.isIndexed());
PrismProperty<Integer> intType = extension.findProperty(EXTENSION_INT_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(intType, 42);
PrismPropertyDefinition intTypePropertyDef = intType.getDefinition();
PrismAsserts.assertDefinition(intTypePropertyDef, EXTENSION_INT_TYPE_ELEMENT, DOMUtil.XSD_INT, 0, -1);
assertNull("'Indexed' attribute on 'intType' property is not null", intTypePropertyDef.isIndexed());
PrismProperty<BigInteger> integerType = extension.findProperty(EXTENSION_INTEGER_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(integerType, new BigInteger("19134702400093278081449423917"));
PrismPropertyDefinition integerTypePropertyDef = integerType.getDefinition();
PrismAsserts.assertDefinition(integerTypePropertyDef, EXTENSION_INTEGER_TYPE_ELEMENT, DOMUtil.XSD_INTEGER, 0, -1);
assertNull("'Indexed' attribute on 'integerType' property is not null", integerTypePropertyDef.isIndexed());
PrismProperty<Long> longType = extension.findProperty(EXTENSION_LONG_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(longType, 299792458L);
PrismPropertyDefinition longTypePropertyDef = longType.getDefinition();
PrismAsserts.assertDefinition(longTypePropertyDef, EXTENSION_LONG_TYPE_ELEMENT, DOMUtil.XSD_LONG, 0, -1);
assertNull("'Indexed' attribute on 'longType' property is not null", longTypePropertyDef.isIndexed());
PrismProperty<XMLGregorianCalendar> dateType = extension.findProperty(EXTENSION_DATE_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(dateType, XmlTypeConverter.createXMLGregorianCalendar(1975, 5, 30, 22, 30, 0));
PrismPropertyDefinition dateTypePropertyDef = dateType.getDefinition();
PrismAsserts.assertDefinition(dateTypePropertyDef, EXTENSION_DATE_TYPE_ELEMENT, DOMUtil.XSD_DATETIME, 0, -1);
assertNull("'Indexed' attribute on 'longType' property is not null", dateTypePropertyDef.isIndexed());
PrismProperty<Duration> durationType = extension.findProperty(EXTENSION_DURATION_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(durationType, XmlTypeConverter.createDuration(true, 17, 3, 2, 0, 0, 0));
PrismPropertyDefinition durationTypePropertyDef = durationType.getDefinition();
PrismAsserts.assertDefinition(durationTypePropertyDef, EXTENSION_DURATION_TYPE_ELEMENT, DOMUtil.XSD_DURATION, 0, -1);
assertNull("'Indexed' attribute on 'longType' property is not null", durationTypePropertyDef.isIndexed());
PrismContainer<?> locationsType = extension.findContainer(EXTENSION_LOCATIONS_ELEMENT);
PrismContainerDefinition<?> localtionsDef = locationsType.getDefinition();
PrismAsserts.assertDefinition(localtionsDef, EXTENSION_LOCATIONS_ELEMENT, EXTENSION_LOCATIONS_TYPE_QNAME, 0, -1);
PrismProperty<String> ignoredType = extension.findProperty(EXTENSION_IGNORED_TYPE_ELEMENT);
PrismAsserts.assertPropertyValue(ignoredType, "this is just a fiction");
PrismPropertyDefinition ignoredTypePropertyDef = ignoredType.getDefinition();
PrismAsserts.assertDefinition(ignoredTypePropertyDef, EXTENSION_IGNORED_TYPE_ELEMENT, DOMUtil.XSD_STRING, 0, -1);
assertNull("'Indexed' attribute on 'ignoredType' property is not null", ignoredTypePropertyDef.isIndexed());
assertTrue("'Ignored' attribute on 'ignoredType' property is not true", ignoredTypePropertyDef.isIgnored());
PrismProperty<String> indexedString = extension.findProperty(EXTENSION_INDEXED_STRING_TYPE_ELEMENT);
PrismPropertyDefinition indexedStringPropertyDef = indexedString.getDefinition();
PrismAsserts.assertDefinition(indexedStringPropertyDef, EXTENSION_SINGLE_STRING_TYPE_ELEMENT, DOMUtil.XSD_STRING, 0, -1);
assertEquals("'Indexed' attribute on 'singleStringType' property is wrong", Boolean.FALSE, indexedStringPropertyDef.isIndexed());
ItemPath barPath = new ItemPath(new QName(NS_FOO, "extension"), EXTENSION_BAR_ELEMENT);
PrismProperty<String> barProperty = user.findProperty(barPath);
assertNotNull("Property " + barPath + " not found", barProperty);
PrismAsserts.assertPropertyValue(barProperty, "BAR");
PrismPropertyDefinition barPropertyDef = barProperty.getDefinition();
assertNotNull("No definition for bar", barPropertyDef);
PrismAsserts.assertDefinition(barPropertyDef, EXTENSION_BAR_ELEMENT, DOMUtil.XSD_STRING, 1, -1);
assertNull("'Indexed' attribute on 'bar' property is not null", barPropertyDef.isIndexed());
PrismProperty<?> multi = extension.findProperty(EXTENSION_MULTI_ELEMENT);
PrismPropertyDefinition multiPropertyDef = multi.getDefinition();
PrismAsserts.assertDefinition(multiPropertyDef, EXTENSION_MULTI_ELEMENT, DOMUtil.XSD_STRING, 1, -1);
assertNull("'Indexed' attribute on 'multi' property is not null", multiPropertyDef.isIndexed());
PrismAsserts.assertPropertyValue(extension, EXTENSION_BAR_ELEMENT, "BAR");
PrismAsserts.assertPropertyValue(extension, EXTENSION_NUM_ELEMENT, 42);
Collection<PrismPropertyValue<Object>> multiPVals = extension.findProperty(EXTENSION_MULTI_ELEMENT).getValues();
assertEquals("Multi", 3, multiPVals.size());
}
use of javax.xml.datatype.Duration in project midpoint by Evolveum.
the class AccCertUpdateHelper method createDeltasToRecordStageOpen.
// some bureaucracy... stage#, state, start time, triggers
List<ItemDelta<?, ?>> createDeltasToRecordStageOpen(AccessCertificationCampaignType campaign, AccessCertificationStageType newStage) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException {
final List<ItemDelta<?, ?>> itemDeltaList = new ArrayList<>();
itemDeltaList.add(createStageNumberDelta(newStage.getNumber()));
final PropertyDelta<AccessCertificationCampaignStateType> stateDelta = createStateDelta(IN_REVIEW_STAGE);
itemDeltaList.add(stateDelta);
final boolean campaignJustCreated = newStage.getNumber() == 1;
if (campaignJustCreated) {
PropertyDelta<XMLGregorianCalendar> startDelta = createStartTimeDelta(XmlTypeConverter.createXMLGregorianCalendar(new Date()));
itemDeltaList.add(startDelta);
}
final XMLGregorianCalendar stageDeadline = newStage.getDeadline();
if (stageDeadline != null) {
// auto-closing and notifications triggers
final AccessCertificationStageDefinitionType stageDef = CertCampaignTypeUtil.findStageDefinition(campaign, newStage.getNumber());
List<TriggerType> triggers = new ArrayList<>();
// pseudo-random ID so this trigger will not be deleted by trigger task handler (if this code itself is executed as part of previous trigger firing)
// TODO implement this more seriously!
long lastId = (long) (Math.random() * 1000000000);
final TriggerType triggerClose = new TriggerType(prismContext);
triggerClose.setHandlerUri(AccessCertificationCloseStageTriggerHandler.HANDLER_URI);
triggerClose.setTimestamp(stageDeadline);
triggerClose.setId(lastId);
triggers.add(triggerClose);
for (Duration beforeDeadline : stageDef.getNotifyBeforeDeadline()) {
final XMLGregorianCalendar beforeEnd = CloneUtil.clone(stageDeadline);
beforeEnd.add(beforeDeadline.negate());
if (XmlTypeConverter.toMillis(beforeEnd) > System.currentTimeMillis()) {
final TriggerType triggerBeforeEnd = new TriggerType(prismContext);
triggerBeforeEnd.setHandlerUri(AccessCertificationCloseStageApproachingTriggerHandler.HANDLER_URI);
triggerBeforeEnd.setTimestamp(beforeEnd);
triggerBeforeEnd.setId(++lastId);
triggers.add(triggerBeforeEnd);
}
}
ContainerDelta<TriggerType> triggerDelta = ContainerDelta.createModificationReplace(ObjectType.F_TRIGGER, AccessCertificationCampaignType.class, prismContext, triggers);
itemDeltaList.add(triggerDelta);
}
return itemDeltaList;
}
Aggregations