use of com.evolveum.midpoint.model.api.ModelExecuteOptions in project midpoint by Evolveum.
the class TestAssignmentValidity method test130JackAssignRoleSailorValidToRaw.
/**
* Raw modification of assignment. The assignment is not effective immediately,
* as this is raw operation. So, nothing much happens. Yet.
* MID-4110
*/
@Test
public void test130JackAssignRoleSailorValidToRaw() throws Exception {
Task task = getTestTask();
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = getUser(USER_JACK_OID);
display("User jack before", userBefore);
ActivationType activationType = new ActivationType();
jackPirateValidTo = getTimestamp("PT10M");
activationType.setValidTo(jackPirateValidTo);
ModelExecuteOptions options = executeOptions().raw();
// WHEN
when();
modifyUserAssignment(USER_JACK_OID, ROLE_STRONG_SAILOR_OID, RoleType.COMPLEX_TYPE, null, task, null, activationType, true, options, result);
// THEN
then();
assertSuccess(result);
PrismObject<UserType> userAfter = getUser(USER_JACK_OID);
display("User jack after", userAfter);
assertAssignments(userAfter, 1);
AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_STRONG_SAILOR_OID);
assertEffectiveActivation(assignmentTypeAfter, null);
assertRoleMembershipRef(userAfter);
assertDelegatedRef(userAfter);
assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME);
}
use of com.evolveum.midpoint.model.api.ModelExecuteOptions in project midpoint by Evolveum.
the class TestAssignmentValidity method test110JackAssignRolePirateValidToRaw.
/**
* Raw modification of assignment. The assignment is not effective immediately,
* as this is raw operation. So, nothing much happens. Yet.
* MID-4110
*/
@Test
public void test110JackAssignRolePirateValidToRaw() throws Exception {
Task task = getTestTask();
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = getUser(USER_JACK_OID);
display("User jack before", userBefore);
ActivationType activationType = new ActivationType();
jackPirateValidTo = getTimestamp("PT10M");
activationType.setValidTo(jackPirateValidTo);
ModelExecuteOptions options = executeOptions().raw();
// WHEN
when();
modifyUserAssignment(USER_JACK_OID, ROLE_PIRATE_OID, RoleType.COMPLEX_TYPE, null, task, null, activationType, true, options, result);
// THEN
then();
assertSuccess(result);
PrismObject<UserType> userAfter = getUser(USER_JACK_OID);
display("User jack after", userAfter);
assertAssignments(userAfter, 1);
AssignmentType assignmentTypeAfter = assertAssignedRole(userAfter, ROLE_PIRATE_OID);
assertEffectiveActivation(assignmentTypeAfter, null);
assertRoleMembershipRef(userAfter);
assertDelegatedRef(userAfter);
assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME);
}
use of com.evolveum.midpoint.model.api.ModelExecuteOptions in project midpoint by Evolveum.
the class ObjectImporter method addObject.
private <T extends ObjectType> void addObject(PrismObject<T> object, boolean overwrite, ImportOptionsType importOptions, Task task, OperationResult parentResult) throws ObjectAlreadyExistsException, SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException {
ObjectDelta<T> delta = DeltaFactory.Object.createAddDelta(object);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(delta);
ModelExecuteOptions modelOptions;
if (importOptions.getModelExecutionOptions() != null) {
modelOptions = ModelExecuteOptions.fromModelExecutionOptionsType(importOptions.getModelExecutionOptions());
} else {
modelOptions = ModelExecuteOptions.create(prismContext);
}
if (modelOptions.getRaw() == null) {
modelOptions.raw(true);
}
if (modelOptions.getOverwrite() == null) {
modelOptions.overwrite(overwrite);
}
if (isFalse(importOptions.isEncryptProtectedValues()) && modelOptions.getNoCrypt() == null) {
modelOptions.noCrypt(true);
}
Collection<ObjectDeltaOperation<? extends ObjectType>> executedDeltas = modelService.executeChanges(deltas, modelOptions, task, parentResult);
String oidOfAddedObject = ObjectDeltaOperation.findFocusDeltaOidInCollection(executedDeltas);
if (oidOfAddedObject == null) {
LOGGER.warn("No OID of added object. Executed deltas:\n{}", DebugUtil.debugDump(executedDeltas));
} else {
if (object.canRepresent(ResourceType.COMPLEX_TYPE) && isTrue(importOptions.isFetchResourceSchema())) {
modelService.testResource(oidOfAddedObject, task);
}
}
}
use of com.evolveum.midpoint.model.api.ModelExecuteOptions in project midpoint by Evolveum.
the class ClockworkConflictResolver method resolveFocusConflict.
private <F extends ObjectType> HookOperationMode resolveFocusConflict(LensContext<F> context, Context resolutionContext, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, ConfigurationException, CommunicationException, SecurityViolationException, PolicyViolationException, ObjectAlreadyExistsException {
ConflictResolutionType resolutionPolicy = resolutionContext.resolutionPolicy;
if (resolutionPolicy == null || resolutionPolicy.getAction() == ConflictResolutionActionType.NONE) {
if (resolutionContext.conflictExceptionPresent) {
throw new SystemException("Conflict exception present but resolution policy is null/NONE");
}
return HookOperationMode.FOREGROUND;
}
PrismObject<F> focusObject = context.getFocusContext() != null ? context.getFocusContext().getObjectAny() : null;
ModelExecuteOptions options = new ModelExecuteOptions(prismContext);
switch(resolutionPolicy.getAction()) {
case FAIL:
throw new SystemException("Conflict detected while updating " + focusObject);
case LOG:
LOGGER.warn("Conflict detected while updating {}", focusObject);
return HookOperationMode.FOREGROUND;
// TODO what to do with this?
case ERROR:
// TODO what to do with this?
case RESTART:
case RECOMPUTE:
break;
case RECONCILE:
options.reconcile();
break;
case NONE:
throw new AssertionError("Already treated");
default:
throw new IllegalStateException("Unsupported conflict resolution action: " + resolutionPolicy.getAction());
}
// so, recompute is the action
LOGGER.debug("CONFLICT: Conflict detected while updating {}, recomputing (options={})", focusObject, options);
String nonEligibilityReason = getNonEligibilityReason(context);
if (nonEligibilityReason != null) {
if (!nonEligibilityReason.isEmpty()) {
LOGGER.warn("Not eligible for conflict resolution by repetition: {}", nonEligibilityReason);
}
return HookOperationMode.FOREGROUND;
}
ConflictResolutionType focusConflictResolution = new ConflictResolutionType();
focusConflictResolution.setAction(ConflictResolutionActionType.ERROR);
options.focusConflictResolution(focusConflictResolution);
int preconditionAttempts = 0;
while (true) {
int attemptOld = context.getConflictResolutionAttemptNumber();
int attemptNew = attemptOld + 1;
boolean shouldExecuteAttempt = shouldExecuteAttempt(resolutionPolicy, attemptNew);
if (!shouldExecuteAttempt) {
LOGGER.warn("CONFLICT: Couldn't resolve conflict even after {} resolution attempt(s), giving up.", attemptOld);
return HookOperationMode.FOREGROUND;
}
delay(context, resolutionPolicy, attemptNew + preconditionAttempts);
Class<F> focusClass = context.getFocusContext().getObjectTypeClass();
String oid = context.getFocusContext().getOid();
// Not using read-only here because we are loading the focus (that will be worked with)
PrismObject<F> focus = repositoryService.getObject(focusClass, oid, null, result);
LensContext<FocusType> contextNew = contextFactory.createRecomputeContext(focus, options, task, result);
contextNew.setProgressListeners(new ArrayList<>(emptyIfNull(context.getProgressListeners())));
contextNew.setConflictResolutionAttemptNumber(attemptNew);
LOGGER.debug("CONFLICT: Recomputing {} as reaction to conflict (options={}, attempts={},{}, readVersion={})", context.getFocusContext().getHumanReadableName(), options, attemptNew, preconditionAttempts, contextNew.getFocusContext().getObjectReadVersion());
ClockworkConflictResolver.Context conflictResolutionContext = new ClockworkConflictResolver.Context();
// this is a recursion; but limited to max attempts which should not be a large number
HookOperationMode hookOperationMode = clockwork.runWithConflictDetection(contextNew, conflictResolutionContext, task, result);
if (!conflictResolutionContext.focusConflictPresent) {
LOGGER.debug("CONFLICT: Clean recompute of {} achieved (options={}, attempts={},{})", context.getFocusContext().getHumanReadableName(), options, attemptNew, preconditionAttempts);
return hookOperationMode;
}
// Actually, we could stop distinguish precondition-based and "normal" retries...
if (conflictResolutionContext.conflictExceptionPresent) {
preconditionAttempts++;
LOGGER.debug("CONFLICT: Recompute precondition failed (attempt {}, precondition attempt {}), trying again", attemptNew, preconditionAttempts);
if (preconditionAttempts < MAX_PRECONDITION_CONFLICT_RESOLUTION_ATTEMPTS) {
continue;
}
LOGGER.warn("CONFLICT: Couldn't resolve conflict even after {} resolution attempt(s) and {} precondition attempts, giving up.", attemptOld, preconditionAttempts);
return HookOperationMode.FOREGROUND;
}
}
}
use of com.evolveum.midpoint.model.api.ModelExecuteOptions in project midpoint by Evolveum.
the class SynchronizationServiceImpl method reactToChange.
private <F extends FocusType> void reactToChange(SynchronizationContext<F> syncCtx, ResourceObjectShadowChangeDescription change, OperationResult result) throws ConfigurationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ExpressionEvaluationException, CommunicationException {
LOGGER.trace("Synchronization context:\n{}", syncCtx.debugDumpLazily(1));
SynchronizationReactionType reaction = syncCtx.getReaction(result);
if (reaction == null) {
LOGGER.trace("No reaction is defined for situation {} in {}", syncCtx.getSituation(), syncCtx.getResource());
return;
}
if (!isSynchronize(reaction)) {
LOGGER.trace("Skipping clockwork run on {} for situation {} because 'synchronize' is set to false (or there are " + "no actions and 'synchronize' is not set).", syncCtx.getResource(), syncCtx.getSituation());
return;
}
Task task = syncCtx.getTask();
ModelExecuteOptions options = createOptions(syncCtx, change);
LensContext<F> lensContext = createLensContext(syncCtx, change, options, result);
lensContext.setDoReconciliationForAllProjections(BooleanUtils.isTrue(reaction.isReconcileAll()));
LOGGER.trace("---[ SYNCHRONIZATION context before action execution ]-------------------------\n" + "{}\n------------------------------------------", lensContext.debugDumpLazily());
// there's no point in calling executeAction without context - so
// the actions are executed only if we are doing the synchronization
executeActions(syncCtx, lensContext, BeforeAfterType.BEFORE, task, result);
try {
clockworkMedic.enterModelMethod(false);
try {
if (change.isSimulate()) {
clockwork.previewChanges(lensContext, null, task, result);
} else {
clockwork.run(lensContext, task, result);
}
} finally {
clockworkMedic.exitModelMethod(false);
}
} catch (Exception e) {
LOGGER.error("SYNCHRONIZATION: Error in synchronization on {} for situation {}: {}: {}. Change was {}", syncCtx.getResource(), syncCtx.getSituation(), e.getClass().getSimpleName(), e.getMessage(), change, e);
// what to do here? We cannot throw the error back. All that the notifyChange method
// could do is to convert it to SystemException. But that indicates an internal error and it will
// break whatever code called the notifyChange in the first place. We do not want that.
// If the clockwork could not do anything with the exception then perhaps nothing can be done at all.
// So just log the error (the error should be remembered in the result and task already)
// and then just go on.
}
// note: actions "AFTER" seem to be useless here (basically they
// modify lens context - which is relevant only if followed by
// clockwork run)
executeActions(syncCtx, lensContext, BeforeAfterType.AFTER, task, result);
}
Aggregations