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;
}
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();
}
}
Aggregations