use of com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType in project midpoint by Evolveum.
the class AssignmentTripleEvaluator method evaluateAssignment.
private <F extends FocusType> EvaluatedAssignmentImpl<F> evaluateAssignment(ItemDeltaItem<PrismContainerValue<AssignmentType>, PrismContainerDefinition<AssignmentType>> assignmentIdi, PlusMinusZero mode, boolean evaluateOld, LensContext<F> context, ObjectType source, AssignmentEvaluator<F> assignmentEvaluator, String assignmentPlacementDesc, Task task, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, PolicyViolationException {
OperationResult result = parentResult.createMinorSubresult(AssignmentProcessor.class.getSimpleName() + ".evaluateAssignment");
result.addParam("assignmentDescription", assignmentPlacementDesc);
try {
// Evaluate assignment. This follows to the assignment targets, follows to the inducements,
// evaluates all the expressions, etc.
EvaluatedAssignmentImpl<F> evaluatedAssignment = assignmentEvaluator.evaluate(assignmentIdi, mode, evaluateOld, source, assignmentPlacementDesc, task, result);
context.rememberResources(evaluatedAssignment.getResources(task, result));
result.recordSuccess();
return evaluatedAssignment;
} catch (ObjectNotFoundException ex) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing of assignment resulted in error {}: {}", ex, SchemaDebugUtil.prettyPrint(LensUtil.getAssignmentType(assignmentIdi, evaluateOld)));
}
if (ModelExecuteOptions.isForce(context.getOptions())) {
result.recordHandledError(ex);
return null;
}
ModelUtils.recordFatalError(result, ex);
return null;
} catch (SchemaException ex) {
AssignmentType assignmentType = LensUtil.getAssignmentType(assignmentIdi, evaluateOld);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing of assignment resulted in error {}: {}", ex, SchemaDebugUtil.prettyPrint(assignmentType));
}
ModelUtils.recordFatalError(result, ex);
String resourceOid = FocusTypeUtil.determineConstructionResource(assignmentType);
if (resourceOid == null) {
// This is a role assignment or something like that. Just throw the original exception for now.
throw ex;
}
ResourceShadowDiscriminator rad = new ResourceShadowDiscriminator(resourceOid, FocusTypeUtil.determineConstructionKind(assignmentType), FocusTypeUtil.determineConstructionIntent(assignmentType));
LensProjectionContext accCtx = context.findProjectionContext(rad);
if (accCtx != null) {
accCtx.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.BROKEN);
}
return null;
} catch (ExpressionEvaluationException | PolicyViolationException e) {
result.recordFatalError(e);
throw e;
}
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType in project midpoint by Evolveum.
the class ConsolidationProcessor method consolidateValuesToModifyDelta.
private <F extends FocusType> ObjectDelta<ShadowType> consolidateValuesToModifyDelta(LensContext<F> context, LensProjectionContext projCtx, boolean addUnchangedValues, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, PolicyViolationException {
// "Squeeze" all the relevant mappings into a data structure that we can process conveniently. We want to have all the
// (meta)data about relevant for a specific attribute in one data structure, not spread over several account constructions.
Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> squeezedAttributes = sqeeze(projCtx, construction -> (Collection) construction.getAttributeMappings());
projCtx.setSqueezedAttributes(squeezedAttributes);
Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> squeezedAssociations = sqeeze(projCtx, construction -> construction.getAssociationMappings());
projCtx.setSqueezedAssociations(squeezedAssociations);
// So, we do it here - once and for all.
if (!squeezedAssociations.isEmpty()) {
fillInAssociationNames(squeezedAssociations);
}
MappingExtractor<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>, F> auxiliaryObjectClassExtractor = construction -> {
PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> prod = new PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>() {
@Override
public QName getMappingQName() {
return ShadowType.F_AUXILIARY_OBJECT_CLASS;
}
@Override
public PrismValueDeltaSetTriple<PrismPropertyValue<QName>> getOutputTriple() {
PrismValueDeltaSetTriple<PrismPropertyValue<QName>> triple = new PrismValueDeltaSetTriple<>();
if (construction.getAuxiliaryObjectClassDefinitions() != null) {
for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : construction.getAuxiliaryObjectClassDefinitions()) {
triple.addToZeroSet(new PrismPropertyValue<QName>(auxiliaryObjectClassDefinition.getTypeName()));
}
}
return triple;
}
@Override
public MappingStrengthType getStrength() {
return MappingStrengthType.STRONG;
}
@Override
public PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> clone() {
return this;
}
@Override
public boolean isExclusive() {
return false;
}
@Override
public boolean isAuthoritative() {
return true;
}
@Override
public boolean isSourceless() {
return false;
}
};
Collection<PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>> col = new ArrayList<>(1);
col.add(prod);
return col;
};
Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>>> squeezedAuxiliaryObjectClasses = sqeeze(projCtx, auxiliaryObjectClassExtractor);
projCtx.setSqueezedAuxiliaryObjectClasses(squeezedAuxiliaryObjectClasses);
ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
ObjectDelta<ShadowType> objectDelta = new ObjectDelta<ShadowType>(ShadowType.class, ChangeType.MODIFY, prismContext);
objectDelta.setOid(projCtx.getOid());
// Let's be very very lazy about fetching the account from the resource.
if (!projCtx.hasFullShadow() && (hasActiveWeakMapping(squeezedAttributes, projCtx) || hasActiveWeakMapping(squeezedAssociations, projCtx) || (hasActiveStrongMapping(squeezedAttributes, projCtx) || hasActiveStrongMapping(squeezedAssociations, projCtx)))) {
// Full account was not yet loaded. This will cause problems as
// the weak mapping may be applied even though it should not be
// applied
// and also same changes may be discarded because of unavailability
// of all
// account's attributes.Therefore load the account now, but with
// doNotDiscovery options..
// We also need to get account if there are strong mappings. Strong mappings
// should always be applied. So reading the account now will indirectly
// trigger reconciliation which makes sure that the strong mappings are
// applied.
// By getting accounts from provisioning, there might be a problem with
// resource availability. We need to know, if the account was read full
// or we have only the shadow from the repository. If we have only
// shadow, the weak mappings may applied even if they should not be.
contextLoader.loadFullShadow(context, projCtx, "weak or strong mapping", task, result);
if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
return null;
}
}
boolean completeAccount = projCtx.hasFullShadow();
ObjectDelta<ShadowType> existingDelta = projCtx.getDelta();
// AUXILIARY OBJECT CLASSES
ItemPath auxiliaryObjectClassItemPath = new ItemPath(ShadowType.F_AUXILIARY_OBJECT_CLASS);
PrismPropertyDefinition<QName> auxiliaryObjectClassPropertyDef = projCtx.getObjectDefinition().findPropertyDefinition(auxiliaryObjectClassItemPath);
PropertyDelta<QName> auxiliaryObjectClassAPrioriDelta = null;
RefinedResourceSchema refinedSchema = projCtx.getRefinedResourceSchema();
List<QName> auxOcNames = new ArrayList<>();
List<RefinedObjectClassDefinition> auxOcDefs = new ArrayList<>();
ObjectDelta<ShadowType> projDelta = projCtx.getDelta();
if (projDelta != null) {
auxiliaryObjectClassAPrioriDelta = projDelta.findPropertyDelta(auxiliaryObjectClassItemPath);
}
for (Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>>> entry : squeezedAuxiliaryObjectClasses.entrySet()) {
DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>> ivwoTriple = entry.getValue();
LOGGER.trace("CONSOLIDATE auxiliary object classes ({})", new Object[] { discr });
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Auxiliary object class triple:\n{}", ivwoTriple.debugDump());
}
for (ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> ivwo : ivwoTriple.getAllValues()) {
QName auxObjectClassName = ivwo.getItemValue().getValue();
if (auxOcNames.contains(auxObjectClassName)) {
continue;
}
auxOcNames.add(auxObjectClassName);
RefinedObjectClassDefinition auxOcDef = refinedSchema.getRefinedDefinition(auxObjectClassName);
if (auxOcDef == null) {
LOGGER.error("Auxiliary object class definition {} for {} not found in the schema, but it should be there, dumping context:\n{}", auxObjectClassName, discr, context.debugDump());
throw new IllegalStateException("Auxiliary object class definition " + auxObjectClassName + " for " + discr + " not found in the context, but it should be there");
}
auxOcDefs.add(auxOcDef);
}
ItemDelta<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> itemDelta = LensUtil.consolidateTripleToDelta(auxiliaryObjectClassItemPath, ivwoTriple, auxiliaryObjectClassPropertyDef, auxiliaryObjectClassAPrioriDelta, projCtx.getObjectNew(), null, null, addUnchangedValues, completeAccount, false, discr.toHumanReadableDescription(), false);
PropertyDelta<QName> propDelta = (PropertyDelta) itemDelta;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Auxiliary object class delta:\n{}", propDelta.debugDump());
}
if (!propDelta.isEmpty()) {
objectDelta.addModification(propDelta);
}
}
RefinedObjectClassDefinition structuralObjectClassDefinition = projCtx.getStructuralObjectClassDefinition();
if (structuralObjectClassDefinition == null) {
LOGGER.error("Structural object class definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump());
throw new IllegalStateException("Structural object class definition for " + discr + " not found in the context, but it should be there");
}
RefinedObjectClassDefinition rOcDef = new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxOcDefs);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Object class definition for {} consolidation:\n{}", discr, rOcDef.debugDump());
}
// with the data in ItemValueWithOrigin triples.
for (Map.Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> entry : squeezedAttributes.entrySet()) {
QName attributeName = entry.getKey();
DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>> triple = entry.getValue();
PropertyDelta<?> propDelta = consolidateAttribute(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeAccount, attributeName, (DeltaSetTriple) triple);
if (propDelta != null) {
objectDelta.addModification(propDelta);
}
}
// ASSOCIATIONS
for (Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> entry : squeezedAssociations.entrySet()) {
QName associationName = entry.getKey();
DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>> triple = entry.getValue();
ContainerDelta<ShadowAssociationType> containerDelta = consolidateAssociation(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeAccount, associationName, triple);
if (containerDelta != null) {
objectDelta.addModification(containerDelta);
}
}
return objectDelta;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType in project midpoint by Evolveum.
the class ActivationProcessor method processLifecycleFocus.
private <F extends FocusType> void processLifecycleFocus(LensContext<F> context, LensProjectionContext projCtx, XMLGregorianCalendar now, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException, CommunicationException, ConfigurationException, SecurityViolationException {
LensFocusContext<F> focusContext = context.getFocusContext();
if (focusContext == null) {
LOGGER.trace("Skipping lifecycle evaluation because there is no focus");
return;
}
ResourceObjectLifecycleDefinitionType lifecycleDef = null;
ResourceObjectTypeDefinitionType resourceAccountDefType = projCtx.getResourceObjectTypeDefinitionType();
if (resourceAccountDefType != null) {
lifecycleDef = resourceAccountDefType.getLifecycle();
}
ResourceBidirectionalMappingType lifecycleStateMappingType = null;
if (lifecycleDef != null) {
lifecycleStateMappingType = lifecycleDef.getLifecycleState();
}
if (lifecycleStateMappingType == null || lifecycleStateMappingType.getOutbound() == null) {
if (!projCtx.isAdd()) {
LOGGER.trace("Skipping lifecycle evaluation because this is not add operation (default expression)");
return;
}
PrismObject<F> focusNew = focusContext.getObjectNew();
if (focusNew == null) {
LOGGER.trace("Skipping lifecycle evaluation because there is no new focus (default expression)");
return;
}
PrismObject<ShadowType> projectionNew = projCtx.getObjectNew();
if (projectionNew == null) {
LOGGER.trace("Skipping lifecycle evaluation because there is no new projection (default expression)");
return;
}
String lifecycle = midpointFunctions.computeProjectionLifecycle(focusNew.asObjectable(), projectionNew.asObjectable(), projCtx.getResource());
LOGGER.trace("Computed projection lifecycle (default expression): {}", lifecycle);
if (lifecycle != null) {
PrismPropertyDefinition<String> propDef = projCtx.getObjectDefinition().findPropertyDefinition(SchemaConstants.PATH_LIFECYCLE_STATE);
PropertyDelta<String> lifeCycleDelta = propDef.createEmptyDelta(SchemaConstants.PATH_LIFECYCLE_STATE);
PrismPropertyValue<String> pval = new PrismPropertyValue<String>(lifecycle);
pval.setOriginType(OriginType.OUTBOUND);
lifeCycleDelta.setValuesToReplace(pval);
projCtx.swallowToSecondaryDelta(lifeCycleDelta);
}
} else {
LOGGER.trace("Computing projection lifecycle (mapping): {}", lifecycleStateMappingType);
evaluateActivationMapping(context, projCtx, lifecycleStateMappingType, SchemaConstants.PATH_LIFECYCLE_STATE, SchemaConstants.PATH_LIFECYCLE_STATE, null, now, true, ObjectType.F_LIFECYCLE_STATE.getLocalPart(), task, result);
}
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType in project midpoint by Evolveum.
the class ActivationProcessor method evaluateExistenceMapping.
private <F extends FocusType> boolean evaluateExistenceMapping(final LensContext<F> context, final LensProjectionContext accCtx, final XMLGregorianCalendar now, final boolean current, Task task, final OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
final String accCtxDesc = accCtx.toHumanReadableString();
final Boolean legal = accCtx.isLegal();
if (legal == null) {
throw new IllegalStateException("Null 'legal' for " + accCtxDesc);
}
ResourceObjectTypeDefinitionType resourceAccountDefType = accCtx.getResourceObjectTypeDefinitionType();
if (resourceAccountDefType == null) {
return legal;
}
ResourceActivationDefinitionType activationType = resourceAccountDefType.getActivation();
if (activationType == null) {
return legal;
}
ResourceBidirectionalMappingType existenceType = activationType.getExistence();
if (existenceType == null) {
return legal;
}
List<MappingType> outbound = existenceType.getOutbound();
if (outbound == null || outbound.isEmpty()) {
// "default mapping"
return legal;
}
MappingEvaluatorParams<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>, ShadowType, F> params = new MappingEvaluatorParams<>();
params.setMappingTypes(outbound);
params.setMappingDesc("outbound existence mapping in projection " + accCtxDesc);
params.setNow(now);
params.setAPrioriTargetObject(accCtx.getObjectOld());
params.setEvaluateCurrent(current);
params.setTargetContext(accCtx);
params.setFixTarget(true);
params.setContext(context);
params.setInitializer(builder -> {
ItemDeltaItem<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> legalSourceIdi = getLegalIdi(accCtx);
Source<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> legalSource = new Source<>(legalSourceIdi, ExpressionConstants.VAR_LEGAL);
builder.defaultSource(legalSource);
ItemDeltaItem<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> assignedIdi = getAssignedIdi(accCtx);
Source<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> assignedSource = new Source<>(assignedIdi, ExpressionConstants.VAR_ASSIGNED);
builder.addSource(assignedSource);
ItemDeltaItem<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> focusExistsSourceIdi = getFocusExistsIdi(context.getFocusContext());
Source<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> focusExistsSource = new Source<>(focusExistsSourceIdi, ExpressionConstants.VAR_FOCUS_EXISTS);
builder.addSource(focusExistsSource);
builder.addVariableDefinition(ExpressionConstants.VAR_FOCUS, context.getFocusContext().getObjectDeltaObject());
builder.addVariableDefinition(ExpressionConstants.VAR_USER, context.getFocusContext().getObjectDeltaObject());
builder.addVariableDefinition(ExpressionConstants.VAR_SHADOW, accCtx.getObjectDeltaObject());
builder.addVariableDefinition(ExpressionConstants.VAR_RESOURCE, accCtx.getResource());
builder.originType(OriginType.OUTBOUND);
builder.originObject(accCtx.getResource());
return builder;
});
final MutableBoolean output = new MutableBoolean(false);
params.setProcessor((mappingOutputPath, outputStruct) -> {
PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> outputTriple = outputStruct.getOutputTriple();
if (outputTriple == null) {
// The "default existence mapping"
output.setValue(legal);
return false;
}
Collection<PrismPropertyValue<Boolean>> nonNegativeValues = outputTriple.getNonNegativeValues();
// (e.g. because the condition is false). This should be fixed.
if (nonNegativeValues == null || nonNegativeValues.isEmpty()) {
throw new ExpressionEvaluationException("Activation existence expression resulted in null or empty value for projection " + accCtxDesc);
}
if (nonNegativeValues.size() > 1) {
throw new ExpressionEvaluationException("Activation existence expression resulted in too many values (" + nonNegativeValues.size() + ") for projection " + accCtxDesc);
}
output.setValue(nonNegativeValues.iterator().next().getValue());
return false;
});
PrismPropertyDefinitionImpl<Boolean> shadowExistsDef = new PrismPropertyDefinitionImpl<>(SHADOW_EXISTS_PROPERTY_NAME, DOMUtil.XSD_BOOLEAN, prismContext);
shadowExistsDef.setMinOccurs(1);
shadowExistsDef.setMaxOccurs(1);
params.setTargetItemDefinition(shadowExistsDef);
mappingEvaluator.evaluateMappingSetProjection(params, task, result);
return (boolean) output.getValue();
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType in project midpoint by Evolveum.
the class ActivationProcessor method processActivationMetadata.
public <F extends FocusType> void processActivationMetadata(LensContext<F> context, LensProjectionContext accCtx, XMLGregorianCalendar now, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException {
ObjectDelta<ShadowType> projDelta = accCtx.getDelta();
if (projDelta == null) {
return;
}
PropertyDelta<ActivationStatusType> statusDelta = projDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS);
if (statusDelta != null && !statusDelta.isDelete()) {
// we have to determine if the status really changed
PrismObject<ShadowType> oldShadow = accCtx.getObjectOld();
ActivationStatusType statusOld = null;
if (oldShadow != null && oldShadow.asObjectable().getActivation() != null) {
statusOld = oldShadow.asObjectable().getActivation().getAdministrativeStatus();
}
PrismProperty<ActivationStatusType> statusPropNew = (PrismProperty<ActivationStatusType>) statusDelta.getItemNewMatchingPath(null);
ActivationStatusType statusNew = statusPropNew.getRealValue();
if (statusNew == statusOld) {
LOGGER.trace("Administrative status not changed ({}), timestamp and/or reason will be recorded", statusNew);
} else {
// timestamps
PropertyDelta<XMLGregorianCalendar> timestampDelta = LensUtil.createActivationTimestampDelta(statusNew, now, getActivationDefinition(), OriginType.OUTBOUND);
accCtx.swallowToSecondaryDelta(timestampDelta);
// disableReason
if (statusNew == ActivationStatusType.DISABLED) {
PropertyDelta<String> disableReasonDelta = projDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_DISABLE_REASON);
if (disableReasonDelta == null) {
String disableReason = null;
ObjectDelta<ShadowType> projPrimaryDelta = accCtx.getPrimaryDelta();
ObjectDelta<ShadowType> projSecondaryDelta = accCtx.getSecondaryDelta();
if (projPrimaryDelta != null && projPrimaryDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS) != null && (projSecondaryDelta == null || projSecondaryDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS) == null)) {
disableReason = SchemaConstants.MODEL_DISABLE_REASON_EXPLICIT;
} else if (accCtx.isLegal()) {
disableReason = SchemaConstants.MODEL_DISABLE_REASON_MAPPED;
} else {
disableReason = SchemaConstants.MODEL_DISABLE_REASON_DEPROVISION;
}
PrismPropertyDefinition<String> disableReasonDef = activationDefinition.findPropertyDefinition(ActivationType.F_DISABLE_REASON);
disableReasonDelta = disableReasonDef.createEmptyDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_DISABLE_REASON));
disableReasonDelta.setValueToReplace(new PrismPropertyValue<String>(disableReason, OriginType.OUTBOUND, null));
accCtx.swallowToSecondaryDelta(disableReasonDelta);
}
}
}
}
}
Aggregations