use of com.evolveum.midpoint.prism.PrismPropertyValue in project midpoint by Evolveum.
the class AssignmentProcessor method processAssignmentsProjectionsWithFocus.
/**
* Processing focus-projection assignments (including roles).
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private <F extends FocusType> void processAssignmentsProjectionsWithFocus(LensContext<F> context, XMLGregorianCalendar now, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, CommunicationException, ConfigurationException, SecurityViolationException {
// PREPARE ASSIGNMENT DELTA
LensFocusContext<F> focusContext = context.getFocusContext();
ObjectDelta<F> focusDelta = focusContext.getDelta();
if (focusDelta != null && focusDelta.isDelete()) {
processFocusDelete(context, result);
return;
}
checkAssignmentDeltaSanity(context);
// ASSIGNMENT EVALUATION
// Initializing assignment evaluator. This will be used later to process all the assignments including the nested
// assignments (roles).
AssignmentEvaluator<F> assignmentEvaluator = createAssignmentEvaluator(context, now);
ObjectType source = determineSource(focusContext);
AssignmentTripleEvaluator<F> assignmentTripleEvaluator = new AssignmentTripleEvaluator<>();
assignmentTripleEvaluator.setActivationComputer(activationComputer);
assignmentTripleEvaluator.setAssignmentEvaluator(assignmentEvaluator);
assignmentTripleEvaluator.setContext(context);
assignmentTripleEvaluator.setNow(now);
assignmentTripleEvaluator.setPrismContext(prismContext);
assignmentTripleEvaluator.setResult(result);
assignmentTripleEvaluator.setSource(source);
assignmentTripleEvaluator.setTask(task);
// Normal processing. The enforcement policy requires that assigned accounts should be added, so we need to figure out
// which assignments were added. Do a complete recompute for all the enforcement modes. We can do that because this does
// not create deltas, it just creates the triples. So we can decide what to do later when we convert triples to deltas.
// Evaluates all assignments and sorts them to triple: added, removed and untouched assignments.
// This is where most of the assignment-level action happens.
DeltaSetTriple<EvaluatedAssignmentImpl<F>> evaluatedAssignmentTriple = assignmentTripleEvaluator.processAllAssignments();
policyRuleProcessor.addGlobalPoliciesToAssignments(context, evaluatedAssignmentTriple, task, result);
context.setEvaluatedAssignmentTriple((DeltaSetTriple) evaluatedAssignmentTriple);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("evaluatedAssignmentTriple:\n{}", evaluatedAssignmentTriple.debugDump());
}
// PROCESSING POLICIES
policyRuleProcessor.processPolicies(context, evaluatedAssignmentTriple, result);
boolean needToReevaluateAssignments = policyRuleProcessor.processPruning(context, evaluatedAssignmentTriple, result);
if (needToReevaluateAssignments) {
LOGGER.debug("Re-evaluating assignments because exclusion pruning rule was triggered");
evaluatedAssignmentTriple = assignmentTripleEvaluator.processAllAssignments();
context.setEvaluatedAssignmentTriple((DeltaSetTriple) evaluatedAssignmentTriple);
policyRuleProcessor.addGlobalPoliciesToAssignments(context, evaluatedAssignmentTriple, task, result);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("re-evaluatedAssignmentTriple:\n{}", evaluatedAssignmentTriple.debugDump());
}
policyRuleProcessor.processPolicies(context, evaluatedAssignmentTriple, result);
}
//policyRuleProcessor.storeAssignmentPolicySituation(context, evaluatedAssignmentTriple, result);
// PROCESSING FOCUS
Map<ItemPath, DeltaSetTriple<? extends ItemValueWithOrigin<?, ?>>> focusOutputTripleMap = new HashMap<>();
collectFocusTripleFromMappings(evaluatedAssignmentTriple.getPlusSet(), focusOutputTripleMap, PlusMinusZero.PLUS);
collectFocusTripleFromMappings(evaluatedAssignmentTriple.getMinusSet(), focusOutputTripleMap, PlusMinusZero.MINUS);
collectFocusTripleFromMappings(evaluatedAssignmentTriple.getZeroSet(), focusOutputTripleMap, PlusMinusZero.ZERO);
ObjectDeltaObject<F> focusOdo = focusContext.getObjectDeltaObject();
Collection<ItemDelta<?, ?>> focusDeltas = objectTemplateProcessor.computeItemDeltas(focusOutputTripleMap, null, focusOdo.getObjectDelta(), focusOdo.getNewObject(), focusContext.getObjectDefinition(), "focus mappings in assignments of " + focusContext.getHumanReadableName());
LOGGER.trace("Computed focus deltas: {}", focusDeltas);
focusContext.applyProjectionWaveSecondaryDeltas(focusDeltas);
focusContext.recompute();
// PROCESSING PROJECTIONS
// Evaluate the constructions in assignements now. These were not evaluated in the first pass of AssignmentEvaluator
// because there may be interaction from focusMappings of some roles to outbound mappings of other roles.
// Now we have complete focus with all the focusMappings so we can evaluate the constructions
evaluateConstructions(context, evaluatedAssignmentTriple, task, result);
ComplexConstructionConsumer<ResourceShadowDiscriminator, Construction<F>> consumer = new ComplexConstructionConsumer<ResourceShadowDiscriminator, Construction<F>>() {
private boolean processOnlyExistingProjCxts;
@Override
public boolean before(ResourceShadowDiscriminator rat) {
if (rat.getResourceOid() == null) {
throw new IllegalStateException("Resource OID null in ResourceAccountType during assignment processing");
}
if (rat.getIntent() == null) {
throw new IllegalStateException("Account type is null in ResourceAccountType during assignment processing");
}
processOnlyExistingProjCxts = false;
if (ModelExecuteOptions.isLimitPropagation(context.getOptions())) {
if (context.getTriggeredResourceOid() != null && !rat.getResourceOid().equals(context.getTriggeredResourceOid())) {
LOGGER.trace("Skipping processing construction for shadow identified by {} because of limitation to propagate changes only for resource {}", rat, context.getTriggeredResourceOid());
return false;
}
if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY.equals(QNameUtil.uriToQName(context.getChannel()))) {
// TODO is this message OK? [med]
LOGGER.trace("Processing of shadow identified by {} will be skipped because of limitation for discovery channel.");
processOnlyExistingProjCxts = true;
}
}
return true;
}
@Override
public void onAssigned(ResourceShadowDiscriminator rat, String desc) {
LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
projectionContext.setAssigned(true);
projectionContext.setAssignedOld(false);
projectionContext.setLegalOld(false);
AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
if (assignmentPolicyEnforcement != AssignmentPolicyEnforcementType.NONE) {
LOGGER.trace("Projection {} legal: assigned (valid)", desc);
projectionContext.setLegal(true);
}
}
@Override
public void onUnchangedValid(ResourceShadowDiscriminator key, String desc) {
LensProjectionContext projectionContext = context.findProjectionContext(key);
if (projectionContext == null) {
if (processOnlyExistingProjCxts) {
return;
}
// The projection should exist before the change but it does not
// This happens during reconciliation if there is an inconsistency.
// Pretend that the assignment was just added. That should do.
projectionContext = LensUtil.getOrCreateProjectionContext(context, key);
}
LOGGER.trace("Projection {} legal: unchanged (valid)", desc);
projectionContext.setLegal(true);
projectionContext.setLegalOld(true);
projectionContext.setAssigned(true);
projectionContext.setAssignedOld(true);
}
@Override
public void onUnchangedInvalid(ResourceShadowDiscriminator rat, String desc) {
LensProjectionContext projectionContext = context.findProjectionContext(rat);
if (projectionContext == null) {
if (processOnlyExistingProjCxts) {
return;
}
// The projection should exist before the change but it does not
// This happens during reconciliation if there is an inconsistency.
// Pretend that the assignment was just added. That should do.
projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
}
LOGGER.trace("Projection {} illegal: unchanged (invalid)", desc);
projectionContext.setLegal(false);
projectionContext.setLegalOld(false);
projectionContext.setAssigned(false);
projectionContext.setAssignedOld(false);
}
@Override
public void onUnassigned(ResourceShadowDiscriminator rat, String desc) {
if (accountExists(context, rat)) {
LensProjectionContext projectionContext = context.findProjectionContext(rat);
if (projectionContext == null) {
if (processOnlyExistingProjCxts) {
return;
}
projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
}
projectionContext.setAssigned(false);
projectionContext.setAssignedOld(true);
projectionContext.setLegalOld(true);
AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
// TODO: check for MARK and LEGALIZE enforcement policies ....add delete laso for relative enforcemenet
if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.FULL || assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.RELATIVE) {
LOGGER.trace("Projection {} illegal: unassigned", desc);
projectionContext.setLegal(false);
} else {
LOGGER.trace("Projection {} legal: unassigned, but allowed by policy ({})", desc, assignmentPolicyEnforcement);
projectionContext.setLegal(true);
}
} else {
LOGGER.trace("Projection {} nothing: unassigned (valid->invalid) but not there", desc);
// We have to delete something that is not there. Nothing to do.
}
}
@Override
public void after(ResourceShadowDiscriminator rat, String desc, DeltaMapTriple<ResourceShadowDiscriminator, ConstructionPack<Construction<F>>> constructionMapTriple) {
PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> projectionConstructionDeltaSetTriple = new PrismValueDeltaSetTriple<>(getConstructions(constructionMapTriple.getZeroMap().get(rat), true), getConstructions(constructionMapTriple.getPlusMap().get(rat), true), getConstructions(constructionMapTriple.getMinusMap().get(rat), false));
LensProjectionContext projectionContext = context.findProjectionContext(rat);
if (projectionContext != null) {
// This can be null in a exotic case if we delete already deleted account
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Construction delta set triple for {}:\n{}", rat, projectionConstructionDeltaSetTriple.debugDump(1));
}
projectionContext.setConstructionDeltaSetTriple(projectionConstructionDeltaSetTriple);
if (isForceRecon(constructionMapTriple.getZeroMap().get(rat)) || isForceRecon(constructionMapTriple.getPlusMap().get(rat)) || isForceRecon(constructionMapTriple.getMinusMap().get(rat))) {
projectionContext.setDoReconciliation(true);
}
}
}
};
constructionProcessor.processConstructions(context, evaluatedAssignmentTriple, evaluatedAssignment -> evaluatedAssignment.getConstructionTriple(), construction -> getConstructionMapKey(context, construction, task, result), consumer, task, result);
removeIgnoredContexts(context);
finishLegalDecisions(context);
}
use of com.evolveum.midpoint.prism.PrismPropertyValue in project midpoint by Evolveum.
the class FocusProcessor method addIterationTokenDeltas.
/**
* Adds deltas for iteration and iterationToken to the focus if needed.
*/
private <F extends FocusType> void addIterationTokenDeltas(LensFocusContext<F> focusContext, int iteration, String iterationToken) throws SchemaException {
PrismObject<F> objectCurrent = focusContext.getObjectCurrent();
if (objectCurrent != null) {
Integer iterationOld = objectCurrent.asObjectable().getIteration();
String iterationTokenOld = objectCurrent.asObjectable().getIterationToken();
if (iterationOld != null && iterationOld == iteration && iterationTokenOld != null && iterationTokenOld.equals(iterationToken)) {
// Already stored
return;
}
}
PrismObjectDefinition<F> objDef = focusContext.getObjectDefinition();
PrismPropertyValue<Integer> iterationVal = new PrismPropertyValue<Integer>(iteration);
iterationVal.setOriginType(OriginType.USER_POLICY);
PropertyDelta<Integer> iterationDelta = PropertyDelta.createReplaceDelta(objDef, FocusType.F_ITERATION, iterationVal);
focusContext.swallowToSecondaryDelta(iterationDelta);
PrismPropertyValue<String> iterationTokenVal = new PrismPropertyValue<String>(iterationToken);
iterationTokenVal.setOriginType(OriginType.USER_POLICY);
PropertyDelta<String> iterationTokenDelta = PropertyDelta.createReplaceDelta(objDef, FocusType.F_ITERATION_TOKEN, iterationTokenVal);
focusContext.swallowToSecondaryDelta(iterationTokenDelta);
}
use of com.evolveum.midpoint.prism.PrismPropertyValue in project midpoint by Evolveum.
the class ItemDeltaItem method resolveStructuredDeltaSet.
private <X> Collection<PrismPropertyValue<X>> resolveStructuredDeltaSet(Collection<PrismPropertyValue<Structured>> set, ItemPath resolvePath) {
if (set == null) {
return null;
}
Collection<PrismPropertyValue<X>> outputSet = new ArrayList<PrismPropertyValue<X>>(set.size());
for (PrismPropertyValue<Structured> structuredPVal : set) {
Structured structured = structuredPVal.getValue();
X outputRval = (X) structured.resolve(resolvePath);
outputSet.add(new PrismPropertyValue<X>(outputRval));
}
return outputSet;
}
use of com.evolveum.midpoint.prism.PrismPropertyValue in project midpoint by Evolveum.
the class ShadowManager method extractRepoShadowChanges.
@SuppressWarnings("rawtypes")
private Collection<? extends ItemDelta> extractRepoShadowChanges(ProvisioningContext ctx, PrismObject<ShadowType> shadow, Collection<? extends ItemDelta> objectChange) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException {
RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition();
CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx);
Collection<ItemDelta> repoChanges = new ArrayList<ItemDelta>();
for (ItemDelta itemDelta : objectChange) {
if (new ItemPath(ShadowType.F_ATTRIBUTES).equivalent(itemDelta.getParentPath())) {
QName attrName = itemDelta.getElementName();
if (objectClassDefinition.isSecondaryIdentifier(attrName)) {
// Change of secondary identifier means object rename. We also need to change $shadow/name
// TODO: change this to displayName attribute later
String newName = null;
if (itemDelta.getValuesToReplace() != null && !itemDelta.getValuesToReplace().isEmpty()) {
newName = ((PrismPropertyValue) itemDelta.getValuesToReplace().iterator().next()).getValue().toString();
} else if (itemDelta.getValuesToAdd() != null && !itemDelta.getValuesToAdd().isEmpty()) {
newName = ((PrismPropertyValue) itemDelta.getValuesToAdd().iterator().next()).getValue().toString();
}
PropertyDelta<PolyString> nameDelta = PropertyDelta.createReplaceDelta(shadow.getDefinition(), ShadowType.F_NAME, new PolyString(newName));
repoChanges.add(nameDelta);
}
if (!ProvisioningUtil.shouldStoreAtributeInShadow(objectClassDefinition, attrName, cachingStrategy)) {
continue;
}
} else if (new ItemPath(ShadowType.F_ACTIVATION).equivalent(itemDelta.getParentPath())) {
if (!ProvisioningUtil.shouldStoreActivationItemInShadow(itemDelta.getElementName(), cachingStrategy)) {
continue;
}
} else if (new ItemPath(ShadowType.F_ACTIVATION).equivalent(itemDelta.getPath())) {
// should not occur, but for completeness...
for (PrismContainerValue<ActivationType> valueToAdd : ((ContainerDelta<ActivationType>) itemDelta).getValuesToAdd()) {
ProvisioningUtil.cleanupShadowActivation(valueToAdd.asContainerable());
}
for (PrismContainerValue<ActivationType> valueToReplace : ((ContainerDelta<ActivationType>) itemDelta).getValuesToReplace()) {
ProvisioningUtil.cleanupShadowActivation(valueToReplace.asContainerable());
}
} else if (SchemaConstants.PATH_PASSWORD.equivalent(itemDelta.getParentPath())) {
continue;
}
normalizeDelta(itemDelta, objectClassDefinition);
repoChanges.add(itemDelta);
}
return repoChanges;
}
use of com.evolveum.midpoint.prism.PrismPropertyValue in project midpoint by Evolveum.
the class ShadowManager method createSearchShadowQuery.
private ObjectQuery createSearchShadowQuery(ProvisioningContext ctx, PrismObject<ShadowType> resourceShadow, PrismContext prismContext, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(resourceShadow);
PrismProperty identifier = attributesContainer.getPrimaryIdentifier();
Collection<PrismPropertyValue<Object>> idValues = identifier.getValues();
// Only one value is supported for an identifier
if (idValues.size() > 1) {
// TODO: This should probably be switched to checked exception later
throw new IllegalArgumentException("More than one identifier value is not supported");
}
if (idValues.size() < 1) {
// TODO: This should probably be switched to checked exception later
throw new IllegalArgumentException("The identifier has no value");
}
// We have all the data, we can construct the filter now
try {
// TODO TODO TODO TODO: set matching rule instead of null
PrismPropertyDefinition def = identifier.getDefinition();
return QueryBuilder.queryFor(ShadowType.class, prismContext).itemWithDef(def, ShadowType.F_ATTRIBUTES, def.getName()).eq(getNormalizedValue(identifier, ctx.getObjectClassDefinition())).and().item(ShadowType.F_OBJECT_CLASS).eq(resourceShadow.getPropertyRealValue(ShadowType.F_OBJECT_CLASS, QName.class)).and().item(ShadowType.F_RESOURCE_REF).ref(ctx.getResourceOid()).build();
} catch (SchemaException e) {
throw new SchemaException("Schema error while creating search filter: " + e.getMessage(), e);
}
}
Aggregations