use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method reactToChange.
private <F extends FocusType> SynchronizationSituationType reactToChange(Class<F> focusClass, ResourceObjectShadowChangeDescription change, ObjectSynchronizationType synchronizationPolicy, SynchronizationSituation<F> situation, ResourceType resource, boolean logDebug, PrismObject<SystemConfigurationType> configuration, Task task, OperationResult parentResult) throws ConfigurationException, ObjectNotFoundException, SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, CommunicationException, SecurityViolationException {
SynchronizationSituationType newSituation = situation.getSituation();
SynchronizationReactionType reactionDefinition = findReactionDefinition(synchronizationPolicy, situation, change.getSourceChannel(), resource);
if (reactionDefinition == null) {
LOGGER.trace("No reaction is defined for situation {} in {}", situation.getSituation(), resource);
return newSituation;
}
// seems to be unused so commented it out [med]
// PrismObject<? extends ObjectType> shadow = null;
// if (change.getCurrentShadow() != null) {
// shadow = change.getCurrentShadow();
// } else if (change.getOldShadow() != null) {
// shadow = change.getOldShadow();
// }
Boolean doReconciliation = determineReconciliation(synchronizationPolicy, reactionDefinition);
if (doReconciliation == null) {
// shadow.
if (change.getObjectDelta() == null) {
doReconciliation = true;
}
}
Boolean limitPropagation = determinePropagationLimitation(synchronizationPolicy, reactionDefinition, change.getSourceChannel());
ModelExecuteOptions options = new ModelExecuteOptions();
options.setReconcile(doReconciliation);
options.setLimitPropagation(limitPropagation);
final boolean willSynchronize = isSynchronize(reactionDefinition);
LensContext<F> lensContext = null;
if (willSynchronize) {
lensContext = createLensContext(focusClass, change, reactionDefinition, synchronizationPolicy, situation, options, configuration, parentResult);
}
if (LOGGER.isTraceEnabled() && lensContext != null) {
LOGGER.trace("---[ SYNCHRONIZATION context before action execution ]-------------------------\n" + "{}\n------------------------------------------", lensContext.debugDump());
}
if (willSynchronize) {
// there's no point in calling executeAction without context - so
// the actions are executed only if synchronize == true
executeActions(reactionDefinition, lensContext, situation, BeforeAfterType.BEFORE, resource, logDebug, task, parentResult);
Iterator<LensProjectionContext> iterator = lensContext.getProjectionContextsIterator();
LensProjectionContext originalProjectionContext = iterator.hasNext() ? iterator.next() : null;
try {
clockwork.run(lensContext, task, parentResult);
} catch (ConfigurationException | ObjectNotFoundException | SchemaException | PolicyViolationException | ExpressionEvaluationException | ObjectAlreadyExistsException | CommunicationException | SecurityViolationException e) {
LOGGER.error("SYNCHRONIZATION: Error in synchronization on {} for situation {}: {}: {}. Change was {}", new Object[] { resource, situation.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(reactionDefinition, lensContext, situation, BeforeAfterType.AFTER, resource, logDebug, task, parentResult);
if (originalProjectionContext != null) {
newSituation = originalProjectionContext.getSynchronizationSituationResolved();
}
} else {
LOGGER.trace("Skipping clockwork run on {} for situation {}, synchronize is set to false.", new Object[] { resource, situation.getSituation() });
}
return newSituation;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method createLensContext.
@NotNull
private <F extends FocusType> LensContext<F> createLensContext(Class<F> focusClass, ResourceObjectShadowChangeDescription change, SynchronizationReactionType reactionDefinition, ObjectSynchronizationType synchronizationPolicy, SynchronizationSituation<F> situation, ModelExecuteOptions options, PrismObject<SystemConfigurationType> configuration, OperationResult parentResult) throws ObjectNotFoundException, SchemaException {
LensContext<F> context = contextFactory.createSyncContext(focusClass, change);
context.setLazyAuditRequest(true);
context.setSystemConfiguration(configuration);
context.setOptions(options);
ResourceType resource = change.getResource().asObjectable();
if (ModelExecuteOptions.isLimitPropagation(options)) {
context.setTriggeredResource(resource);
}
context.rememberResource(resource);
PrismObject<ShadowType> shadow = getShadowFromChange(change);
if (InternalsConfig.consistencyChecks)
shadow.checkConsistence();
// Projection context
ShadowKindType kind = getKind(shadow, synchronizationPolicy);
String intent = getIntent(shadow, synchronizationPolicy);
boolean thombstone = isThombstone(change);
ResourceShadowDiscriminator descr = new ResourceShadowDiscriminator(resource.getOid(), kind, intent, thombstone);
LensProjectionContext projectionContext = context.createProjectionContext(descr);
projectionContext.setResource(resource);
projectionContext.setOid(getOidFromChange(change));
projectionContext.setSynchronizationSituationDetected(situation.getSituation());
// insert object delta if available in change
ObjectDelta<? extends ShadowType> delta = change.getObjectDelta();
if (delta != null) {
projectionContext.setSyncDelta((ObjectDelta<ShadowType>) delta);
} else {
projectionContext.setSyncAbsoluteTrigger(true);
}
// we insert account if available in change
PrismObject<ShadowType> currentAccount = shadow;
if (currentAccount != null) {
projectionContext.setLoadedObject(currentAccount);
if (!thombstone) {
projectionContext.setFullShadow(true);
}
projectionContext.setFresh(true);
}
if (delta != null && delta.isDelete()) {
projectionContext.setExists(false);
} else {
projectionContext.setExists(true);
}
projectionContext.setDoReconciliation(ModelExecuteOptions.isReconcile(options));
// Focus context
if (situation.getCurrentOwner() != null) {
F focusType = situation.getCurrentOwner();
LensFocusContext<F> focusContext = context.createFocusContext();
PrismObject<F> focusOld = (PrismObject<F>) focusType.asPrismObject();
focusContext.setLoadedObject(focusOld);
}
// Global stuff
ObjectReferenceType objectTemplateRef = null;
if (reactionDefinition.getObjectTemplateRef() != null) {
objectTemplateRef = reactionDefinition.getObjectTemplateRef();
} else if (synchronizationPolicy.getObjectTemplateRef() != null) {
objectTemplateRef = synchronizationPolicy.getObjectTemplateRef();
}
if (objectTemplateRef != null) {
ObjectTemplateType objectTemplate = repositoryService.getObject(ObjectTemplateType.class, objectTemplateRef.getOid(), null, parentResult).asObjectable();
context.setFocusTemplate(objectTemplate);
}
return context;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method determineSituationWithCorrelation.
/**
* account is not linked to user. you have to use correlation and
* confirmation rule to be sure user for this account doesn't exists
* resourceShadow only contains the data that were in the repository before
* the change. But the correlation/confirmation should work on the updated
* data. Therefore let's apply the changes before running
* correlation/confirmation
*/
private <F extends FocusType> SynchronizationSituation determineSituationWithCorrelation(Class<F> focusType, ResourceObjectShadowChangeDescription change, ObjectSynchronizationType synchronizationPolicy, PrismObject<F> owner, SystemConfigurationType configurationType, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException {
if (ChangeType.DELETE.equals(getModificationType(change))) {
// account was deleted and we know it didn't have owner
return new SynchronizationSituation<>(owner == null ? null : owner.asObjectable(), null, SynchronizationSituationType.DELETED);
}
PrismObject<? extends ShadowType> resourceShadow = change.getCurrentShadow();
ObjectDelta syncDelta = change.getObjectDelta();
if (resourceShadow == null && syncDelta != null && ChangeType.ADD.equals(syncDelta.getChangeType())) {
LOGGER.trace("Trying to compute current shadow from change delta add.");
PrismObject<ShadowType> shadow = syncDelta.computeChangedObject(syncDelta.getObjectToAdd());
resourceShadow = shadow;
change.setCurrentShadow(shadow);
}
Validate.notNull(resourceShadow, "Current shadow must not be null.");
ResourceType resource = change.getResource().asObjectable();
validateResourceInShadow(resourceShadow.asObjectable(), resource);
SynchronizationSituationType state = null;
LOGGER.trace("SYNCHRONIZATION: CORRELATION: Looking for list of {} objects based on correlation rule.", focusType.getSimpleName());
List<PrismObject<F>> users = correlationConfirmationEvaluator.findFocusesByCorrelationRule(focusType, resourceShadow.asObjectable(), synchronizationPolicy.getCorrelation(), resource, configurationType, task, result);
if (users == null) {
users = new ArrayList<>();
}
if (users.size() > 1) {
if (synchronizationPolicy.getConfirmation() == null) {
LOGGER.trace("SYNCHRONIZATION: CONFIRMATION: no confirmation defined.");
} else {
LOGGER.debug("SYNCHRONIZATION: CONFIRMATION: Checking objects from correlation with confirmation rule.");
users = correlationConfirmationEvaluator.findUserByConfirmationRule(focusType, users, resourceShadow.asObjectable(), resource, configurationType, synchronizationPolicy.getConfirmation(), task, result);
}
}
F user = null;
switch(users.size()) {
case 0:
state = SynchronizationSituationType.UNMATCHED;
break;
case 1:
switch(getModificationType(change)) {
case ADD:
case MODIFY:
state = SynchronizationSituationType.UNLINKED;
break;
case DELETE:
state = SynchronizationSituationType.DELETED;
break;
}
user = users.get(0).asObjectable();
break;
default:
state = SynchronizationSituationType.DISPUTED;
}
return new SynchronizationSituation(null, user, state);
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method saveSyncMetadata.
/**
* Saves situation, timestamps, kind and intent (if needed)
*/
private PrismObject<ShadowType> saveSyncMetadata(PrismObject<ShadowType> shadow, SynchronizationSituation situation, ResourceObjectShadowChangeDescription change, ObjectSynchronizationType synchronizationPolicy, Task task, OperationResult parentResult) {
if (shadow == null) {
return null;
}
ShadowType shadowType = shadow.asObjectable();
// new situation description
List<PropertyDelta<?>> deltas = SynchronizationUtils.createSynchronizationSituationAndDescriptionDelta(shadow, situation.getSituation(), change.getSourceChannel(), true);
if (shadowType.getKind() == null) {
ShadowKindType kind = synchronizationPolicy.getKind();
if (kind == null) {
kind = ShadowKindType.ACCOUNT;
}
PropertyDelta<ShadowKindType> kindDelta = PropertyDelta.createReplaceDelta(shadow.getDefinition(), ShadowType.F_KIND, kind);
deltas.add(kindDelta);
}
if (shadowType.getIntent() == null) {
String intent = synchronizationPolicy.getIntent();
if (intent == null) {
intent = SchemaConstants.INTENT_DEFAULT;
}
PropertyDelta<String> intentDelta = PropertyDelta.createReplaceDelta(shadow.getDefinition(), ShadowType.F_INTENT, intent);
deltas.add(intentDelta);
}
try {
repositoryService.modifyObject(shadowType.getClass(), shadow.getOid(), deltas, parentResult);
ItemDelta.applyTo(deltas, shadow);
task.recordObjectActionExecuted(shadow, ChangeType.MODIFY, null);
return shadow;
} catch (ObjectNotFoundException ex) {
task.recordObjectActionExecuted(shadow, ChangeType.MODIFY, ex);
// This may happen e.g. during some recon-livesync interactions.
// If the shadow is gone then it is gone. No point in recording the
// situation any more.
LOGGER.debug("Could not update situation in account, because shadow {} does not exist any more (this may be harmless)", shadow.getOid());
parentResult.getLastSubresult().setStatus(OperationResultStatus.HANDLED_ERROR);
} catch (ObjectAlreadyExistsException | SchemaException ex) {
task.recordObjectActionExecuted(shadow, ChangeType.MODIFY, ex);
LoggingUtils.logException(LOGGER, "### SYNCHRONIZATION # notifyChange(..): Save of synchronization situation failed: could not modify shadow " + shadow.getOid() + ": " + ex.getMessage(), ex);
parentResult.recordFatalError("Save of synchronization situation failed: could not modify shadow " + shadow.getOid() + ": " + ex.getMessage(), ex);
throw new SystemException("Save of synchronization situation failed: could not modify shadow " + shadow.getOid() + ": " + ex.getMessage(), ex);
} catch (Throwable t) {
task.recordObjectActionExecuted(shadow, ChangeType.MODIFY, t);
throw t;
}
return null;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method matchUserCorrelationRule.
/**
* Tries to match specified focus and shadow. Return true if it matches,
* false otherwise.
*/
@Override
public <F extends FocusType> boolean matchUserCorrelationRule(PrismObject<ShadowType> shadow, PrismObject<F> focus, ResourceType resourceType, PrismObject<SystemConfigurationType> configuration, Task task, OperationResult result) throws ConfigurationException, SchemaException, ObjectNotFoundException, ExpressionEvaluationException {
ObjectSynchronizationType synchronizationPolicy = determineSynchronizationPolicy(resourceType, shadow, configuration, task, result);
Class<F> focusClass;
// be null...
if (synchronizationPolicy != null) {
focusClass = determineFocusClass(synchronizationPolicy, resourceType);
} else {
focusClass = (Class) focus.asObjectable().getClass();
}
return correlationConfirmationEvaluator.matchUserCorrelationRule(focusClass, shadow, focus, synchronizationPolicy, resourceType, configuration == null ? null : configuration.asObjectable(), task, result);
}
Aggregations