use of com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType.COMPLETED in project midpoint by Evolveum.
the class AbstractManualResourceTest method test300UnassignAccountWill.
@Test
public void test300UnassignAccountWill() throws Exception {
final String TEST_NAME = "test300UnassignAccountWill";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
unassignAccount(userWillOid, getResourceOid(), null, task, result);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 1);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo, OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowRepo, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class, accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 1);
pendingOperation = findPendingOperation(shadowModel, OperationResultStatusType.IN_PROGRESS, null);
assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class, accountWillOid, SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertShadowDead(shadowModelFuture);
assertShadowPassword(shadowModelFuture);
// Make sure that the account is still linked
PrismObject<UserType> userAfter = getUser(userWillOid);
display("User after", userAfter);
String accountWillOidAfter = getSingleLinkOid(userAfter);
assertEquals(accountWillOid, accountWillOidAfter);
assertNoAssignments(userAfter);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType.COMPLETED in project midpoint by Evolveum.
the class ResourceManager method completeResource.
/**
* Make sure that the resource is complete.
*
* It will check if the resource has a sufficiently fresh schema, etc.
*
* Returned resource may be the same or may be a different instance, but it
* is guaranteed that it will be "fresher" and will correspond to the
* repository state (assuming that the provided resource also corresponded
* to the repository state).
*
* The connector schema that was fetched before can be supplied to this
* method. This is just an optimization. It comes handy e.g. in test
* connection case.
*
* Note: This is not really the best place for this method. Need to figure
* out correct place later.
*
* @param repoResource
* Resource to check
* @param resourceSchema
* schema that was freshly pre-fetched (or null)
* @param parentResult
*
* @return completed resource
*/
private PrismObject<ResourceType> completeResource(PrismObject<ResourceType> repoResource, ResourceSchema resourceSchema, boolean fetchedSchema, Map<String, Collection<Object>> capabilityMap, GetOperationOptions options, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
// do not add as a subresult..it will be added later, if the completing
// of resource will be successfull.if not, it will be only set as a
// fetch result in the resource..
OperationResult result = parentResult.createMinorSubresult(OPERATION_COMPLETE_RESOURCE);
try {
applyConnectorSchemaToResource(repoResource, task, result);
} catch (SchemaException e) {
String message = "Schema error while applying connector schema to connectorConfiguration section of " + repoResource + ": " + e.getMessage();
result.recordPartialError(message, e);
LOGGER.warn(message, e);
return repoResource;
} catch (ObjectNotFoundException e) {
String message = "Object not found error while processing connector configuration of " + repoResource + ": " + e.getMessage();
result.recordPartialError(message, e);
LOGGER.warn(message, e);
return repoResource;
} catch (RuntimeException e) {
String message = "Unexpected error while processing connector configuration of " + repoResource + ": " + e.getMessage();
result.recordPartialError(message, e);
LOGGER.warn(message, e);
return repoResource;
}
PrismObject<ResourceType> newResource;
if (isComplete(repoResource)) {
// The resource is complete.
newResource = repoResource;
} else {
if (GetOperationOptions.isNoFetch(options)) {
// We need to fetch schema, but the noFetch option is specified. Therefore return whatever we have.
result.recordSuccessIfUnknown();
return repoResource;
}
try {
completeSchemaAndCapabilities(repoResource, resourceSchema, fetchedSchema, capabilityMap, task, result);
} catch (Exception ex) {
// Catch the exceptions. There are not critical. We need to catch them all because the connector may
// throw even undocumented runtime exceptions.
// Even non-complete resource may still be usable. The fetchResult indicates that there was an error
result.recordPartialError("Cannot complete resource schema and capabilities: " + ex.getMessage(), ex);
return repoResource;
}
try {
// Now we need to re-read the resource from the repository and re-aply the schemas. This ensures that we will
// cache the correct version and that we avoid race conditions, etc.
newResource = repositoryService.getObject(ResourceType.class, repoResource.getOid(), null, result);
applyConnectorSchemaToResource(newResource, task, result);
} catch (SchemaException e) {
result.recordFatalError(e);
throw e;
} catch (ObjectNotFoundException e) {
result.recordFatalError(e);
throw e;
} catch (RuntimeException e) {
result.recordFatalError(e);
throw e;
}
}
try {
// make sure it has parsed resource and refined schema. We are going to cache
// it, so we want to cache it with the parsed schemas
RefinedResourceSchemaImpl.getResourceSchema(newResource, prismContext);
RefinedResourceSchemaImpl.getRefinedSchema(newResource);
} catch (SchemaException e) {
String message = "Schema error while processing schemaHandling section of " + newResource + ": " + e.getMessage();
result.recordPartialError(message, e);
LOGGER.warn(message, e);
return newResource;
} catch (RuntimeException e) {
String message = "Unexpected error while processing schemaHandling section of " + newResource + ": " + e.getMessage();
result.recordPartialError(message, e);
LOGGER.warn(message, e);
return newResource;
}
result.recordSuccessIfUnknown();
return newResource;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType.COMPLETED in project midpoint by Evolveum.
the class CompletedTaskCleanupTriggerHandler method handle.
@Override
public <O extends ObjectType> void handle(@NotNull PrismObject<O> object, @NotNull TriggerType trigger, @NotNull RunningTask task, @NotNull OperationResult result) {
try {
// todo use repo preconditions to implement this
if (!(object.asObjectable() instanceof TaskType)) {
return;
}
TaskType completedTask = repositoryService.getObject(TaskType.class, object.getOid(), createReadOnlyCollection(), result).asObjectable();
LOGGER.trace("Checking completed task to be deleted {}", completedTask);
if (completedTask.getExecutionState() != TaskExecutionStateType.CLOSED) {
LOGGER.debug("Task {} is not closed, not deleting it.", completedTask);
return;
}
XMLGregorianCalendar completion = completedTask.getCompletionTimestamp();
if (completion == null) {
LOGGER.debug("Task {} has no completion timestamp, not deleting it.", completedTask);
return;
}
if (completedTask.getCleanupAfterCompletion() == null) {
LOGGER.debug("Task {} has no 'cleanup after completion' set, not deleting it.", completedTask);
return;
}
completion.add(completedTask.getCleanupAfterCompletion());
if (!XmlTypeConverter.isBeforeNow(completion)) {
LOGGER.debug("Task {} should be deleted no earlier than {}, not deleting it.", completedTask, completion);
// set 'cleanupAfterCompletion' after the task was completed. Let's jut ignore this situation.
return;
}
LOGGER.debug("Deleting completed task {}", completedTask);
taskManager.deleteTask(object.getOid(), result);
} catch (CommonException | RuntimeException | Error e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't delete completed task {}", e, object);
// do not retry this trigger execution
}
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType.COMPLETED in project midpoint by Evolveum.
the class TaskQuartzImplUtil method createTriggerForTask.
public static Trigger createTriggerForTask(Task task) throws ParseException {
if (task.getExecutionStatus() != TaskExecutionStatus.RUNNABLE) {
// no triggers for such tasks
return null;
}
// special case - recurrent task with no schedule (means "run on demand only")
if (task.isCycle() && (task.getSchedule() == null || (task.getSchedule().getInterval() == null && task.getSchedule().getCronLikePattern() == null))) {
return null;
}
TriggerBuilder<Trigger> tb = TriggerBuilder.newTrigger().withIdentity(createTriggerKeyForTask(task)).forJob(createJobKeyForTask(task));
if (task.getSchedule() != null) {
Date est = task.getSchedule().getEarliestStartTime() != null ? task.getSchedule().getEarliestStartTime().toGregorianCalendar().getTime() : null;
Date lst = task.getSchedule().getLatestStartTime() != null ? task.getSchedule().getLatestStartTime().toGregorianCalendar().getTime() : null;
// endAt must not be sooner than startAt
if (lst != null && est == null) {
if (lst.getTime() < System.currentTimeMillis()) {
// there's no point in setting est to current time
est = lst;
}
}
if (est != null) {
tb.startAt(est);
} else {
tb.startNow();
}
if (lst != null) {
tb.endAt(lst);
// LST is checked also within JobExecutor (needed mainly for tightly-bound recurrent tasks)
}
if (task.getSchedule().getLatestFinishTime() != null) {
tb.endAt(task.getSchedule().getLatestFinishTime().toGregorianCalendar().getTime());
// however, it is the responsibility of task handler to finish no later than this time
}
}
boolean looselyBoundRecurrent;
if (task.isCycle() && task.isLooselyBound()) {
looselyBoundRecurrent = true;
ScheduleType sch = task.getSchedule();
if (sch == null) {
return null;
//throw new IllegalStateException("Recurrent task " + task + " does not have a schedule.");
}
ScheduleBuilder sb;
if (sch.getInterval() != null) {
SimpleScheduleBuilder ssb = simpleSchedule().withIntervalInSeconds(sch.getInterval().intValue()).repeatForever();
if (sch.getMisfireAction() == null || sch.getMisfireAction() == MisfireActionType.EXECUTE_IMMEDIATELY) {
sb = ssb.withMisfireHandlingInstructionFireNow();
} else if (sch.getMisfireAction() == MisfireActionType.RESCHEDULE) {
sb = ssb.withMisfireHandlingInstructionNextWithRemainingCount();
} else {
throw new SystemException("Invalid value of misfireAction: " + sch.getMisfireAction() + " for task " + task);
}
} else if (sch.getCronLikePattern() != null) {
// may throw ParseException
CronScheduleBuilder csb = cronScheduleNonvalidatedExpression(sch.getCronLikePattern());
if (sch.getMisfireAction() == null || sch.getMisfireAction() == MisfireActionType.EXECUTE_IMMEDIATELY) {
sb = csb.withMisfireHandlingInstructionFireAndProceed();
} else if (sch.getMisfireAction() == MisfireActionType.RESCHEDULE) {
sb = csb.withMisfireHandlingInstructionDoNothing();
} else {
throw new SystemException("Invalid value of misfireAction: " + sch.getMisfireAction() + " for task " + task);
}
} else {
return null;
//throw new IllegalStateException("The schedule for task " + task + " is neither fixed nor cron-like one.");
}
tb.withSchedule(sb);
} else {
// even non-recurrent tasks will be triggered, to check whether they should not be restarted
// (their trigger will be erased when these tasks will be completed)
looselyBoundRecurrent = false;
// tb.withSchedule(simpleSchedule().withIntervalInMilliseconds(SINGLE_TASK_CHECK_INTERVAL).repeatForever());
}
tb.usingJobData("schedule", scheduleFingerprint(task.getSchedule()));
tb.usingJobData("looselyBoundRecurrent", looselyBoundRecurrent);
tb.usingJobData("handlerUri", task.getHandlerUri());
return tb.build();
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType.COMPLETED in project midpoint by Evolveum.
the class AbstractManualResourceTest method test220ModifyUserWillDisable.
/**
* disable - do not complete yet (do not wait for delta to expire, we want several deltas at once).
*/
@Test
public void test220ModifyUserWillDisable() throws Exception {
final String TEST_NAME = "test220ModifyUserWillDisable";
displayTestTile(TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
accountWillReqestTimestampStart = clock.currentTimeXMLGregorianCalendar();
// WHEN
displayWhen(TEST_NAME);
modifyUserReplace(userWillOid, ACTIVATION_ADMINISTRATIVE_STATUS_PATH, task, result, ActivationStatusType.DISABLED);
// THEN
displayThen(TEST_NAME);
display("result", result);
willLastCaseOid = assertInProgress(result);
accountWillReqestTimestampEnd = clock.currentTimeXMLGregorianCalendar();
PrismObject<ShadowType> shadowRepo = repositoryService.getObject(ShadowType.class, accountWillOid, null, result);
display("Repo shadow", shadowRepo);
assertPendingOperationDeltas(shadowRepo, 2);
PendingOperationType pendingOperation = findPendingOperation(shadowRepo, OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowRepo, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
assertNotNull("No ID in pending operation", pendingOperation.getId());
// Still old data in the repo. The operation is not completed yet.
assertShadowActivationAdministrativeStatusFromCache(shadowRepo, ActivationStatusType.ENABLED);
assertAttribute(shadowRepo, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttributeFromCache(shadowRepo, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
PrismObject<ShadowType> shadowModel = modelService.getObject(ShadowType.class, accountWillOid, null, task, result);
display("Model shadow", shadowModel);
ShadowType shadowTypeProvisioning = shadowModel.asObjectable();
assertShadowName(shadowModel, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowTypeProvisioning.getKind());
assertShadowActivationAdministrativeStatus(shadowModel, ActivationStatusType.ENABLED);
assertAttribute(shadowModel, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModel, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModel, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModel);
assertPendingOperationDeltas(shadowModel, 2);
pendingOperation = findPendingOperation(shadowModel, OperationResultStatusType.IN_PROGRESS, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd);
PrismObject<ShadowType> shadowModelFuture = modelService.getObject(ShadowType.class, accountWillOid, SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), task, result);
display("Model shadow (future)", shadowModelFuture);
assertShadowName(shadowModelFuture, USER_WILL_NAME);
assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, shadowModelFuture.asObjectable().getKind());
assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.DISABLED);
assertAttribute(shadowModelFuture, ATTR_USERNAME_QNAME, USER_WILL_NAME);
assertAttribute(shadowModelFuture, ATTR_FULLNAME_QNAME, USER_WILL_FULL_NAME_PIRATE);
assertAttributeFromBackingStore(shadowModelFuture, ATTR_DESCRIPTION_QNAME, ACCOUNT_WILL_DESCRIPTION_MANUAL);
assertShadowPassword(shadowModelFuture);
assertNotNull("No async reference in result", willLastCaseOid);
assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_OPEN);
}
Aggregations