use of com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType in project midpoint by Evolveum.
the class ConfigurationExceptionHandler method handleError.
@Override
public <T extends ShadowType> T handleError(T shadow, FailedOperation op, Exception ex, boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException {
if (!doDiscovery) {
parentResult.recordFatalError(ex);
if (ex instanceof ConfigurationException) {
throw (ConfigurationException) ex;
} else {
throw new ConfigurationException(ex.getMessage(), ex);
}
}
ObjectDelta delta = null;
switch(op) {
case ADD:
delta = ObjectDelta.createAddDelta(shadow.asPrismObject());
break;
case DELETE:
delta = ObjectDelta.createDeleteDelta(shadow.getClass(), shadow.getOid(), prismContext);
break;
case MODIFY:
Collection<? extends ItemDelta> modifications = null;
if (shadow.getObjectChange() != null) {
ObjectDeltaType deltaType = shadow.getObjectChange();
modifications = DeltaConvertor.toModifications(deltaType.getItemDelta(), shadow.asPrismObject().getDefinition());
}
delta = ObjectDelta.createModifyDelta(shadow.getOid(), modifications, shadow.getClass(), prismContext);
break;
case GET:
OperationResult operationResult = parentResult.createSubresult("com.evolveum.midpoint.provisioning.consistency.impl.ConfigurationExceptionHandler.handleError." + op.name());
operationResult.addParam("shadow", shadow);
operationResult.addParam("currentOperation", op);
operationResult.addParam("exception", ex.getMessage());
for (OperationResult subRes : parentResult.getSubresults()) {
subRes.muteError();
}
operationResult.recordPartialError("Could not get " + ObjectTypeUtil.toShortString(shadow) + " from the resource " + ObjectTypeUtil.toShortString(shadow.getResource()) + ", because of configuration error. Returning shadow from the repository");
shadow.setFetchResult(operationResult.createOperationResultType());
return shadow;
}
if (op != FailedOperation.GET) {
// Task task = taskManager.createTaskInstance();
ResourceOperationDescription operationDescription = createOperationDescription(shadow, ex, shadow.getResource(), delta, task, parentResult);
changeNotificationDispatcher.notifyFailure(operationDescription, task, parentResult);
}
if (shadow.getOid() == null) {
throw new ConfigurationException("Configuration error: " + ex.getMessage(), ex);
}
Collection<ItemDelta> modification = createAttemptModification(shadow, null);
try {
ConstraintsChecker.onShadowModifyOperation(modification);
cacheRepositoryService.modifyObject(shadow.asPrismObject().getCompileTimeClass(), shadow.getOid(), modification, parentResult);
} catch (Exception e) {
//this should not happen. But if it happens, we should return original exception
LOGGER.error("Unexpected error while modifying shadow {}: {}", shadow, e.getMessage(), e);
if (ex instanceof SchemaException) {
throw ((SchemaException) ex);
} else if (ex instanceof GenericFrameworkException) {
throw ((GenericFrameworkException) ex);
} else if (ex instanceof CommunicationException) {
throw ((CommunicationException) ex);
} else if (ex instanceof ObjectNotFoundException) {
throw ((ObjectNotFoundException) ex);
} else if (ex instanceof ObjectAlreadyExistsException) {
throw ((ObjectAlreadyExistsException) ex);
} else if (ex instanceof ConfigurationException) {
throw ((ConfigurationException) ex);
}
}
parentResult.recordFatalError("Configuration error: " + ex.getMessage(), ex);
throw new ConfigurationException("Configuration error: " + ex.getMessage(), ex);
}
use of com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType in project midpoint by Evolveum.
the class GenericErrorHandler method handleError.
// @Autowired
// private OperationFinisher operationFinisher;
@Override
public <T extends ShadowType> T handleError(T shadow, FailedOperation op, Exception ex, boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
if (!doDiscovery) {
parentResult.recordFatalError(ex);
if (ex instanceof GenericFrameworkException) {
throw (GenericFrameworkException) ex;
} else {
throw new GenericFrameworkException(ex.getMessage(), ex);
}
}
// OperationResult result = OperationResult.createOperationResult(shadow.getResult());
String operation = (shadow.getFailedOperationType() == null ? "null" : shadow.getFailedOperationType().name());
OperationResult result = parentResult.createSubresult(COMPENSATE_OPERATION);
result.addContext("compensatedOperation", operation);
result.addContext("operationType", op.name());
result.addParam("shadow", shadow);
result.addParam("currentOperation", op);
result.addParam("reconciled", true);
switch(op) {
case GET:
if (ShadowUtil.isDead(shadow) || ResourceTypeUtil.isDown(shadow.getResource()) || !compensate) {
result.recordStatus(OperationResultStatus.PARTIAL_ERROR, "Unable to get object from the resource. Probably it has not been created yet because of previous unavailability of the resource.");
result.computeStatus();
shadow.setFetchResult(parentResult.createOperationResultType());
return shadow;
}
if (shadow.getFailedOperationType() == null) {
String message = "Generic error in the connector. Can't process shadow " + ObjectTypeUtil.toShortString(shadow) + ": " + ex.getMessage();
result.recordFatalError(message, ex);
throw new GenericFrameworkException(message, ex);
}
try {
//ProvisioningOperationOptions.createCompletePostponed(false);
provisioningService.refreshShadow(shadow.asPrismObject(), null, task, result);
result.computeStatus();
if (result.isSuccess()) {
LOGGER.trace("Postponed operation was finished successfully while getting shadow. Getting new object.");
PrismObject prismShadow = provisioningService.getObject(shadow.getClass(), shadow.getOid(), null, task, result);
if (!prismShadow.hasCompleteDefinition()) {
LOGGER.trace("applying definitions to shadow");
provisioningService.applyDefinition(prismShadow, task, result);
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Got {} after finishing postponed operation.", prismShadow.debugDump());
}
shadow = (T) prismShadow.asObjectable();
}
// } catch(Exception e){
// result.recordFatalError("Could not finish operation " + operation + ". Reason: " + e.getMessage()));
// // just throw the origin exception
// throw new GenericFrameworkException(ex);
} finally {
result.computeStatus();
}
return shadow;
case MODIFY:
if (shadow.getFailedOperationType() == null) {
String message = "Generic error in the connector. Can't process shadow " + ObjectTypeUtil.toShortString(shadow) + ". ";
result.recordFatalError(message, ex);
throw new GenericFrameworkException(message, ex);
}
// get the modifications from the shadow before the account
// is created, because after successful creation of account,
// the modification will be lost
Collection<? extends ItemDelta> modifications = null;
if (shadow.getObjectChange() != null) {
ObjectDeltaType deltaType = shadow.getObjectChange();
modifications = DeltaConvertor.toModifications(deltaType.getItemDelta(), shadow.asPrismObject().getDefinition());
}
PropertyDelta.applyTo(modifications, shadow.asPrismObject());
provisioningService.refreshShadow(shadow.asPrismObject(), null, task, result);
result.computeStatus();
if (!result.isSuccess()) {
// account wasn't created, probably resource is
// still down, or there is other reason.just save the
// pending modifications to the shadow in the
// repository..next time by processing this shadow, we can try again
// TODO: probably there is a need to union current changes with previous
ConstraintsChecker.onShadowModifyOperation(modifications);
cacheRepositoryService.modifyObject(ShadowType.class, shadow.getOid(), modifications, result);
result.recordHandledError("Modifications not applied to the object, because resource is unreachable. They are stored to the shadow and will be applied when the resource goes online.");
}
return shadow;
case DELETE:
cacheRepositoryService.deleteObject(shadow.getClass(), shadow.getOid(), result);
result.recordStatus(OperationResultStatus.HANDLED_ERROR, "Object has been not created on the resource yet. Shadow deleted from the repository");
return shadow;
default:
result.recordFatalError("Can't process " + ObjectTypeUtil.toShortString(shadow) + ": " + ex.getMessage(), ex);
if (shadow.getOid() == null) {
throw new GenericFrameworkException("Can't process " + ObjectTypeUtil.toShortString(shadow) + ": " + ex.getMessage(), ex);
}
Collection<ItemDelta> modification = createAttemptModification(shadow, null);
ConstraintsChecker.onShadowModifyOperation(modification);
cacheRepositoryService.modifyObject(shadow.asPrismObject().getCompileTimeClass(), shadow.getOid(), modification, parentResult);
String message = "Can't process " + ObjectTypeUtil.toShortString(shadow) + ". ";
result.recordFatalError(message, ex);
throw new GenericFrameworkException(message, ex);
}
}
use of com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType in project midpoint by Evolveum.
the class WfTaskController method onTaskEvent.
//endregion
//region Processing work item (task) events
// workItem contains taskRef, assignee, candidates resolved (if possible)
// workItem can be freely modified (e.g. by overriding result, etc.)
@SuppressWarnings("unchecked")
public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationResult result) throws WorkflowException, SchemaException {
final TaskType shadowTaskType = WfContextUtil.getTask(workItem);
if (shadowTaskType == null) {
LOGGER.warn("No task in workItem " + workItem + ", audit and notifications couldn't be performed.");
return;
}
final Task shadowTask = taskManager.createTaskInstance(shadowTaskType.asPrismObject(), result);
final WfTask wfTask = recreateWfTask(shadowTask);
// auditing & notifications & event
if (taskEvent instanceof TaskCreatedEvent) {
AuditEventRecord auditEventRecord = getChangeProcessor(taskEvent).prepareWorkItemCreatedAuditRecord(workItem, taskEvent, wfTask, result);
auditService.audit(auditEventRecord, wfTask.getTask());
try {
notifyWorkItemCreated(workItem.getOriginalAssigneeRef(), workItem, wfTask, result);
if (workItem.getAssigneeRef() != null) {
WorkItemAllocationChangeOperationInfo operationInfo = new WorkItemAllocationChangeOperationInfo(null, Collections.emptyList(), workItem.getAssigneeRef());
notifyWorkItemAllocationChangeNewActors(workItem, operationInfo, null, wfTask.getTask(), result);
}
} catch (SchemaException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't send notification about work item create event", e);
}
} else if (taskEvent instanceof TaskDeletedEvent) {
// this might be cancellation because of:
// (1) user completion of this task
// (2) timed completion of this task
// (3) user completion of another task
// (4) timed completion of another task
// (5) process stop/deletion
//
// Actually, when the source is (4) timed completion of another task, it is quite probable that this task
// would be closed for the same reason. For a user it would be misleading if we would simply view this task
// as 'cancelled', while, in fact, it is e.g. approved/rejected because of a timed action.
WorkItemOperationKindType operationKind = BooleanUtils.isTrue(ActivitiUtil.getVariable(taskEvent.getVariables(), CommonProcessVariableNames.VARIABLE_WORK_ITEM_WAS_COMPLETED, Boolean.class, prismContext)) ? WorkItemOperationKindType.COMPLETE : WorkItemOperationKindType.CANCEL;
WorkItemEventCauseInformationType cause = ActivitiUtil.getVariable(taskEvent.getVariables(), CommonProcessVariableNames.VARIABLE_CAUSE, WorkItemEventCauseInformationType.class, prismContext);
boolean genuinelyCompleted = operationKind == WorkItemOperationKindType.COMPLETE;
MidPointPrincipal user;
try {
user = SecurityUtil.getPrincipal();
} catch (SecurityViolationException e) {
throw new SystemException("Couldn't determine current user: " + e.getMessage(), e);
}
// partial fallback
ObjectReferenceType userRef = user != null ? user.toObjectReference() : workItem.getPerformerRef();
if (!genuinelyCompleted) {
TaskType task = wfTask.getTask().getTaskPrismObject().asObjectable();
int foundTimedActions = 0;
for (TriggerType trigger : task.getTrigger()) {
if (!WfTimedActionTriggerHandler.HANDLER_URI.equals(trigger.getHandlerUri())) {
continue;
}
String workItemId = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_WORK_ITEM_ID);
if (!taskEvent.getTaskId().equals(workItemId)) {
continue;
}
Duration timeBeforeAction = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_TIME_BEFORE_ACTION);
if (timeBeforeAction != null) {
continue;
}
WorkItemActionsType actions = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_WORK_ITEM_ACTIONS);
if (actions == null || actions.getComplete() == null) {
continue;
}
long diff = XmlTypeConverter.toMillis(trigger.getTimestamp()) - clock.currentTimeMillis();
if (diff >= COMPLETION_TRIGGER_EQUALITY_THRESHOLD) {
continue;
}
CompleteWorkItemActionType completeAction = actions.getComplete();
operationKind = WorkItemOperationKindType.COMPLETE;
cause = new WorkItemEventCauseInformationType();
cause.setType(WorkItemEventCauseTypeType.TIMED_ACTION);
cause.setName(completeAction.getName());
cause.setDisplayName(completeAction.getDisplayName());
foundTimedActions++;
WorkItemResultType workItemOutput = new WorkItemResultType();
workItemOutput.setOutcome(completeAction.getOutcome() != null ? completeAction.getOutcome() : SchemaConstants.MODEL_APPROVAL_OUTCOME_REJECT);
workItem.setOutput(workItemOutput);
}
if (foundTimedActions > 1) {
LOGGER.warn("Multiple 'work item complete' timed actions ({}) for {}: {}", foundTimedActions, ObjectTypeUtil.toShortString(task), task.getTrigger());
}
}
// We don't pass userRef (initiator) to the audit method. It does need the whole object (not only the reference),
// so it fetches it directly from the security enforcer (logged-in user). This could change in the future.
AuditEventRecord auditEventRecord = getChangeProcessor(taskEvent).prepareWorkItemDeletedAuditRecord(workItem, cause, taskEvent, wfTask, result);
auditService.audit(auditEventRecord, wfTask.getTask());
try {
WorkItemAllocationChangeOperationInfo operationInfo = new WorkItemAllocationChangeOperationInfo(operationKind, workItem.getAssigneeRef(), null);
WorkItemOperationSourceInfo sourceInfo = new WorkItemOperationSourceInfo(userRef, cause, null);
if (workItem.getAssigneeRef().isEmpty()) {
notifyWorkItemDeleted(null, workItem, operationInfo, sourceInfo, wfTask, result);
} else {
for (ObjectReferenceType assignee : workItem.getAssigneeRef()) {
notifyWorkItemDeleted(assignee, workItem, operationInfo, sourceInfo, wfTask, result);
}
}
notifyWorkItemAllocationChangeCurrentActors(workItem, operationInfo, sourceInfo, null, wfTask.getTask(), result);
} catch (SchemaException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't audit work item complete event", e);
}
AbstractWorkItemOutputType output = workItem.getOutput();
if (genuinelyCompleted || output != null) {
WorkItemCompletionEventType event = new WorkItemCompletionEventType();
ActivitiUtil.fillInWorkItemEvent(event, user, taskEvent.getTaskId(), taskEvent.getVariables(), prismContext);
event.setCause(cause);
event.setOutput(output);
ObjectDeltaType additionalDelta = output instanceof WorkItemResultType && ((WorkItemResultType) output).getAdditionalDeltas() != null ? ((WorkItemResultType) output).getAdditionalDeltas().getFocusPrimaryDelta() : null;
MidpointUtil.recordEventInTask(event, additionalDelta, wfTask.getTask().getOid(), result);
}
MidpointUtil.removeTriggersForWorkItem(wfTask.getTask(), taskEvent.getTaskId(), result);
}
}
use of com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType in project midpoint by Evolveum.
the class ItemApprovalProcessInterface method extractWorkItemResult.
@Override
public WorkItemResultType extractWorkItemResult(Map<String, Object> variables) {
Boolean wasCompleted = ActivitiUtil.getVariable(variables, VARIABLE_WORK_ITEM_WAS_COMPLETED, Boolean.class, prismContext);
if (BooleanUtils.isNotTrue(wasCompleted)) {
return null;
}
WorkItemResultType result = new WorkItemResultType(prismContext);
result.setOutcome(ActivitiUtil.getVariable(variables, FORM_FIELD_OUTCOME, String.class, prismContext));
result.setComment(ActivitiUtil.getVariable(variables, FORM_FIELD_COMMENT, String.class, prismContext));
String additionalDeltaString = ActivitiUtil.getVariable(variables, FORM_FIELD_ADDITIONAL_DELTA, String.class, prismContext);
boolean isApproved = ApprovalUtils.isApproved(result);
if (isApproved && StringUtils.isNotEmpty(additionalDeltaString)) {
try {
ObjectDeltaType additionalDelta = prismContext.parserFor(additionalDeltaString).parseRealValue(ObjectDeltaType.class);
ObjectTreeDeltasType treeDeltas = new ObjectTreeDeltasType();
treeDeltas.setFocusPrimaryDelta(additionalDelta);
result.setAdditionalDeltas(treeDeltas);
} catch (SchemaException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't parse delta received from the activiti form:\n{}", e, additionalDeltaString);
throw new SystemException("Couldn't parse delta received from the activiti form: " + e.getMessage(), e);
}
}
return result;
}
use of com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType in project midpoint by Evolveum.
the class TestSanityLegacy method deleteObjectViaModelWS.
private OperationResultType deleteObjectViaModelWS(QName typeQName, String oid) throws FaultMessage {
ObjectDeltaListType deltaList = new ObjectDeltaListType();
ObjectDeltaType objectDelta = new ObjectDeltaType();
objectDelta.setOid(oid);
objectDelta.setObjectType(typeQName);
objectDelta.setChangeType(ChangeTypeType.DELETE);
deltaList.getDelta().add(objectDelta);
ObjectDeltaOperationListType list = modelWeb.executeChanges(deltaList, null);
return getOdoFromDeltaOperationList(list, objectDelta).getExecutionResult();
}
Aggregations