Search in sources :

Example 1 with ComplexConstructionConsumer

use of com.evolveum.midpoint.model.impl.lens.projector.ComplexConstructionConsumer in project midpoint by Evolveum.

the class PersonaProcessor method processPersonaChangesFocus.

public <F extends FocusType> HookOperationMode processPersonaChangesFocus(LensContext<F> context, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException {
    DeltaSetTriple<EvaluatedAssignmentImpl<F>> evaluatedAssignmentTriple = (DeltaSetTriple) context.getEvaluatedAssignmentTriple();
    if (evaluatedAssignmentTriple == null || evaluatedAssignmentTriple.isEmpty()) {
        return HookOperationMode.FOREGROUND;
    }
    DeltaSetTriple<PersonaKey> activePersonaKeyTriple = new DeltaSetTriple<>();
    ComplexConstructionConsumer<PersonaKey, PersonaConstruction<F>> consumer = new ComplexConstructionConsumer<PersonaKey, PersonaConstruction<F>>() {

        @Override
        public boolean before(PersonaKey key) {
            return true;
        }

        @Override
        public void onAssigned(PersonaKey key, String desc) {
            activePersonaKeyTriple.addToPlusSet(key);
        }

        @Override
        public void onUnchangedValid(PersonaKey key, String desc) {
            activePersonaKeyTriple.addToZeroSet(key);
        }

        @Override
        public void onUnchangedInvalid(PersonaKey key, String desc) {
        }

        @Override
        public void onUnassigned(PersonaKey key, String desc) {
            activePersonaKeyTriple.addToMinusSet(key);
        }

        @Override
        public void after(PersonaKey key, String desc, DeltaMapTriple<PersonaKey, ConstructionPack<PersonaConstruction<F>>> constructionMapTriple) {
        }
    };
    DeltaMapTriple<PersonaKey, ConstructionPack<PersonaConstruction<F>>> constructionMapTriple = constructionProcessor.processConstructions(context, evaluatedAssignmentTriple, evaluatedAssignment -> evaluatedAssignment.getPersonaConstructionTriple(), construction -> new PersonaKey(construction.getConstructionType()), consumer, task, result);
    LOGGER.trace("activePersonaKeyTriple:\n{}", activePersonaKeyTriple.debugDumpLazily());
    List<FocusType> existingPersonas = readExistingPersonas(context, task, result);
    LOGGER.trace("existingPersonas:\n{}", existingPersonas);
    for (PersonaKey key : activePersonaKeyTriple.getNonNegativeValues()) {
        FocusType existingPersona = findPersona(existingPersonas, key);
        LOGGER.trace("existingPersona: {}", existingPersona);
        // TODO: add ability to merge several constructions
        ConstructionPack<PersonaConstruction<F>> pack = constructionMapTriple.getPlusMap().get(key);
        if (pack == null) {
            pack = constructionMapTriple.getZeroMap().get(key);
        }
        Collection<PrismPropertyValue<PersonaConstruction<F>>> constructions = pack.getConstructions();
        if (constructions.isEmpty()) {
            continue;
        }
        if (constructions.size() > 1) {
            throw new UnsupportedOperationException("Merging of multiple persona constructions is not supported yet");
        }
        PersonaConstruction<F> construction = constructions.iterator().next().getValue();
        LOGGER.trace("construction:\n{}", construction.debugDumpLazily());
        if (existingPersona == null) {
            personaAdd(context, key, construction, task, result);
        } else {
            personaModify(context, key, construction, existingPersona.asPrismObject(), task, result);
        }
    }
    for (PersonaKey key : activePersonaKeyTriple.getMinusSet()) {
        FocusType existingPersona = findPersona(existingPersonas, key);
        if (existingPersona != null) {
            personaDelete(context, key, existingPersona, task, result);
        }
    }
    return HookOperationMode.FOREGROUND;
}
Also used : DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) ComplexConstructionConsumer(com.evolveum.midpoint.model.impl.lens.projector.ComplexConstructionConsumer) DeltaMapTriple(com.evolveum.midpoint.prism.delta.DeltaMapTriple) FocusType(com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue)

Example 2 with ComplexConstructionConsumer

use of com.evolveum.midpoint.model.impl.lens.projector.ComplexConstructionConsumer in project midpoint by Evolveum.

the class AssignmentProcessor method distributeConstructions.

private <AH extends AssignmentHolderType> void distributeConstructions(LensContext<AH> context, DeltaSetTriple<EvaluatedAssignmentImpl<AH>> evaluatedAssignmentTriple, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    ComplexConstructionConsumer<ResourceShadowDiscriminator, EvaluatedAssignedResourceObjectConstructionImpl<AH>> consumer = new ComplexConstructionConsumer<>() {

        private boolean processOnlyExistingProjContexts;

        @Override
        public boolean before(ResourceShadowDiscriminator rsd) {
            if (rsd.getResourceOid() == null) {
                throw new IllegalStateException("Resource OID null in ResourceShadowDiscriminator during assignment processing");
            }
            if (rsd.getIntent() == null) {
                throw new IllegalStateException("Resource object intent is null in ResourceShadowDiscriminator during assignment processing");
            }
            processOnlyExistingProjContexts = false;
            if (ModelExecuteOptions.isLimitPropagation(context.getOptions())) {
                if (context.getTriggeringResourceOid() != null && !rsd.getResourceOid().equals(context.getTriggeringResourceOid())) {
                    LOGGER.trace("Skipping processing construction for shadow identified by {} because of limitation to propagate changes only for resource {}", rsd, context.getTriggeringResourceOid());
                    return false;
                }
                if (context.getChannel() != null && SchemaConstants.CHANNEL_DISCOVERY.equals(QNameUtil.uriToQName(context.getChannel()))) {
                    LOGGER.trace("Processing of shadow identified by {} will be skipped because of limitation for discovery channel.", // TODO is this message OK? [med]
                    context.getChannel());
                    processOnlyExistingProjContexts = true;
                }
            }
            return true;
        }

        @Override
        public void onAssigned(ResourceShadowDiscriminator rsd, String desc) throws SchemaException {
            LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd).context;
            projectionContext.setAssigned(true);
            projectionContext.setAssignedOldIfUnknown(false);
            projectionContext.setLegalOldIfUnknown(false);
            if (projectionContext.getAssignmentPolicyEnforcementType() != AssignmentPolicyEnforcementType.NONE) {
                LOGGER.trace("Projection {} legal: assigned (valid)", desc);
                projectionContext.setLegal(true);
            } else {
                LOGGER.trace("Projection {} skip: assigned (valid), NONE enforcement", desc);
            }
        }

        @Override
        public void onUnchangedValid(ResourceShadowDiscriminator key, String desc) throws SchemaException {
            LensProjectionContext projectionContext = context.findProjectionContext(key);
            if (projectionContext == null) {
                if (processOnlyExistingProjContexts) {
                    LOGGER.trace("Projection {} skip: unchanged (valid), processOnlyExistingProjCxts", desc);
                    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).context;
            }
            LOGGER.trace("Projection {} legal: unchanged (valid)", desc);
            projectionContext.setAssigned(true);
            projectionContext.setAssignedOldIfUnknown(true);
            if (projectionContext.getAssignmentPolicyEnforcementType() == AssignmentPolicyEnforcementType.NONE) {
                projectionContext.setLegalOld(null);
                projectionContext.setLegal(null);
            } else {
                projectionContext.setLegalOldIfUnknown(true);
                projectionContext.setLegal(true);
            }
        }

        @Override
        public void onUnchangedInvalid(ResourceShadowDiscriminator rsd, String desc) throws SchemaException {
            LensProjectionContext projectionContext = context.findProjectionContext(rsd);
            if (projectionContext == null) {
                if (processOnlyExistingProjContexts) {
                    LOGGER.trace("Projection {} skip: unchanged (invalid), processOnlyExistingProjContexts", desc);
                } else {
                    LOGGER.trace("Projection {} skip: unchanged (invalid) and does not exist in current lens context", desc);
                }
                return;
            }
            LOGGER.trace("Projection {} illegal: unchanged (invalid)", desc);
            projectionContext.setLegal(false);
            projectionContext.setLegalOldIfUnknown(false);
            projectionContext.setAssigned(false);
            projectionContext.setAssignedOldIfUnknown(false);
            if (projectionContext.getAssignmentPolicyEnforcementType() == AssignmentPolicyEnforcementType.NONE || projectionContext.getAssignmentPolicyEnforcementType() == AssignmentPolicyEnforcementType.POSITIVE) {
                projectionContext.setLegalOld(null);
                projectionContext.setLegal(null);
            } else {
                projectionContext.setLegalOldIfUnknown(false);
                projectionContext.setLegal(false);
            }
        }

        @Override
        public void onUnassigned(ResourceShadowDiscriminator rsd, String desc) throws SchemaException {
            if (accountExists(context, rsd)) {
                LensProjectionContext projectionContext = context.findProjectionContext(rsd);
                if (projectionContext == null) {
                    if (processOnlyExistingProjContexts) {
                        LOGGER.trace("Projection {} skip: unassigned, processOnlyExistingProjContexts", desc);
                        return;
                    }
                    projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd).context;
                }
                projectionContext.setAssigned(false);
                projectionContext.setAssignedOldIfUnknown(true);
                projectionContext.setLegalOldIfUnknown(true);
                AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
                // TODO: check for MARK and LEGALIZE enforcement policies ....add delete also for relative enforcement
                if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.FULL || assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.RELATIVE) {
                    LOGGER.trace("Projection {} illegal: unassigned", desc);
                    projectionContext.setLegal(false);
                } else if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.POSITIVE) {
                    LOGGER.trace("Projection {} legal: unassigned, but allowed by policy ({})", desc, assignmentPolicyEnforcement);
                    projectionContext.setLegal(true);
                } else {
                    LOGGER.trace("Projection {} legal: unassigned, policy decision postponed ({})", desc, assignmentPolicyEnforcement);
                    projectionContext.setLegal(null);
                }
            } 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 rsd, String desc, DeltaMapTriple<ResourceShadowDiscriminator, EvaluatedConstructionPack<EvaluatedAssignedResourceObjectConstructionImpl<AH>>> constructionMapTriple) {
            DeltaSetTriple<EvaluatedAssignedResourceObjectConstructionImpl<AH>> projectionEvaluatedConstructionDeltaSetTriple = prismContext.deltaFactory().createDeltaSetTriple(getConstructions(constructionMapTriple.getZeroMap().get(rsd), true), getConstructions(constructionMapTriple.getPlusMap().get(rsd), true), getConstructions(constructionMapTriple.getMinusMap().get(rsd), false));
            LensProjectionContext projectionContext = context.findProjectionContext(rsd);
            if (projectionContext != null) {
                // This can be null in a exotic case if we delete already deleted account
                LOGGER.trace("Construction delta set triple for {}:\n{}", rsd, projectionEvaluatedConstructionDeltaSetTriple.debugDumpLazily(1));
                projectionContext.setEvaluatedAssignedConstructionDeltaSetTriple(projectionEvaluatedConstructionDeltaSetTriple);
                if (isForceRecon(constructionMapTriple.getZeroMap().get(rsd)) || isForceRecon(constructionMapTriple.getPlusMap().get(rsd)) || isForceRecon(constructionMapTriple.getMinusMap().get(rsd))) {
                    projectionContext.setDoReconciliation(true);
                }
            }
        }
    };
    OperationResult result = parentResult.createMinorSubresult(OP_DISTRIBUTE_CONSTRUCTIONS);
    try {
        LOGGER.trace("Starting construction distribution");
        constructionProcessor.distributeConstructions(evaluatedAssignmentTriple, EvaluatedAssignmentImpl::getConstructionTriple, construction -> getConstructionMapKey(context, construction, task, result), consumer);
        LOGGER.trace("Finished construction distribution");
    } catch (Throwable t) {
        result.recordFatalError(t);
        throw t;
    } finally {
        result.computeStatusIfUnknown();
    }
}
Also used : ComplexConstructionConsumer(com.evolveum.midpoint.model.impl.lens.projector.ComplexConstructionConsumer) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) EvaluatedAssignmentImpl(com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) EvaluatedAssignedResourceObjectConstructionImpl(com.evolveum.midpoint.model.impl.lens.construction.EvaluatedAssignedResourceObjectConstructionImpl)

Aggregations

ComplexConstructionConsumer (com.evolveum.midpoint.model.impl.lens.projector.ComplexConstructionConsumer)2 LensProjectionContext (com.evolveum.midpoint.model.impl.lens.LensProjectionContext)1 EvaluatedAssignmentImpl (com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl)1 EvaluatedAssignedResourceObjectConstructionImpl (com.evolveum.midpoint.model.impl.lens.construction.EvaluatedAssignedResourceObjectConstructionImpl)1 PrismPropertyValue (com.evolveum.midpoint.prism.PrismPropertyValue)1 DeltaMapTriple (com.evolveum.midpoint.prism.delta.DeltaMapTriple)1 DeltaSetTriple (com.evolveum.midpoint.prism.delta.DeltaSetTriple)1 ResourceShadowDiscriminator (com.evolveum.midpoint.schema.ResourceShadowDiscriminator)1 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)1 FocusType (com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType)1