use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType in project midpoint by Evolveum.
the class OutboundProcessor method processOutbound.
public <F extends FocusType> void processOutbound(LensContext<F> context, LensProjectionContext projCtx, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
ObjectDelta<ShadowType> projectionDelta = projCtx.getDelta();
if (projectionDelta != null && projectionDelta.getChangeType() == ChangeType.DELETE) {
LOGGER.trace("Processing outbound expressions for {} skipped, DELETE account delta", discr);
// No point in evaluating outbound
return;
}
LOGGER.trace("Processing outbound expressions for {} starting", discr);
RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition();
if (rOcDef == null) {
LOGGER.error("Definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump());
throw new IllegalStateException("Definition for " + discr + " not found in the context, but it should be there");
}
ObjectDeltaObject<F> focusOdo = context.getFocusContext().getObjectDeltaObject();
ObjectDeltaObject<ShadowType> projectionOdo = projCtx.getObjectDeltaObject();
Construction<F> outboundConstruction = new Construction<>(null, projCtx.getResource());
outboundConstruction.setRefinedObjectClassDefinition(rOcDef);
Collection<RefinedObjectClassDefinition> auxiliaryObjectClassDefinitions = rOcDef.getAuxiliaryObjectClassDefinitions();
if (auxiliaryObjectClassDefinitions != null) {
for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : auxiliaryObjectClassDefinitions) {
outboundConstruction.addAuxiliaryObjectClassDefinition(auxiliaryObjectClassDefinition);
}
}
String operation = projCtx.getOperation().getValue();
for (QName attributeName : rOcDef.getNamesOfAttributesWithOutboundExpressions()) {
RefinedAttributeDefinition<?> refinedAttributeDefinition = rOcDef.findAttributeDefinition(attributeName);
final MappingType outboundMappingType = refinedAttributeDefinition.getOutboundMappingType();
if (outboundMappingType == null) {
continue;
}
if (refinedAttributeDefinition.isIgnored(LayerType.MODEL)) {
LOGGER.trace("Skipping processing outbound mapping for attribute {} because it is ignored", attributeName);
continue;
}
Mapping.Builder<PrismPropertyValue<?>, RefinedAttributeDefinition<?>> builder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(refinedAttributeDefinition.getName()) + " in " + rOcDef.getResourceType());
builder = builder.originObject(rOcDef.getResourceType()).originType(OriginType.OUTBOUND);
Mapping<PrismPropertyValue<?>, RefinedAttributeDefinition<?>> evaluatedMapping = evaluateMapping(builder, attributeName, refinedAttributeDefinition, focusOdo, projectionOdo, operation, rOcDef, null, context, projCtx, task, result);
if (evaluatedMapping != null) {
outboundConstruction.addAttributeMapping(evaluatedMapping);
}
}
for (QName assocName : rOcDef.getNamesOfAssociationsWithOutboundExpressions()) {
RefinedAssociationDefinition associationDefinition = rOcDef.findAssociationDefinition(assocName);
final MappingType outboundMappingType = associationDefinition.getOutboundMappingType();
if (outboundMappingType == null) {
continue;
}
// if (associationDefinition.isIgnored(LayerType.MODEL)) {
// LOGGER.trace("Skipping processing outbound mapping for attribute {} because it is ignored", assocName);
// continue;
// }
Mapping.Builder<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> mappingBuilder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(associationDefinition.getName()) + " in " + rOcDef.getResourceType());
PrismContainerDefinition<ShadowAssociationType> outputDefinition = getAssociationContainerDefinition();
Mapping<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> evaluatedMapping = (Mapping) evaluateMapping(mappingBuilder, assocName, outputDefinition, focusOdo, projectionOdo, operation, rOcDef, associationDefinition.getAssociationTarget(), context, projCtx, task, result);
if (evaluatedMapping != null) {
outboundConstruction.addAssociationMapping(evaluatedMapping);
}
}
projCtx.setOutboundConstruction(outboundConstruction);
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType in project midpoint by Evolveum.
the class ReconciliationProcessor method getIdentifiersForAssociationTarget.
@NotNull
private ResourceAttributeContainer getIdentifiersForAssociationTarget(PrismContainerValue<ShadowAssociationType> isCValue, Task task, OperationResult result) throws CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ObjectNotFoundException, ExpressionEvaluationException {
ResourceAttributeContainer identifiersContainer = ShadowUtil.getAttributesContainer(isCValue, ShadowAssociationType.F_IDENTIFIERS);
if (identifiersContainer != null) {
return identifiersContainer;
}
String oid = isCValue.asContainerable().getShadowRef() != null ? isCValue.asContainerable().getShadowRef().getOid() : null;
if (oid == null) {
// TODO maybe warn/error log would suffice?
throw new IllegalStateException("Couldn't evaluate tolerant/intolerant values for association " + isCValue + ", because there are no identifiers and no shadow reference present");
}
PrismObject<ShadowType> target;
try {
GetOperationOptions rootOpt = GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE);
rootOpt.setNoFetch(true);
target = provisioningService.getObject(ShadowType.class, oid, SelectorOptions.createCollection(rootOpt), task, result);
} catch (ObjectNotFoundException e) {
// TODO maybe warn/error log would suffice (also for other exceptions?)
throw new ObjectNotFoundException("Couldn't evaluate tolerant/intolerant values for association " + isCValue + ", because the association target object does not exist: " + e.getMessage(), e);
}
identifiersContainer = ShadowUtil.getAttributesContainer(target);
if (identifiersContainer == null) {
// TODO maybe warn/error log would suffice?
throw new IllegalStateException("Couldn't evaluate tolerant/intolerant values for association " + isCValue + ", because there are no identifiers present, even in the repository object for association target");
}
return identifiersContainer;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType in project midpoint by Evolveum.
the class ReconciliationProcessor method processReconciliationFocus.
private <F extends ObjectType> void processReconciliationFocus(LensContext<F> context, LensProjectionContext projCtx, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
OperationResult subResult = result.createMinorSubresult(PROCESS_RECONCILIATION);
try {
// reconciliation is cheap if the shadow is already fetched therefore just do it
if (!projCtx.isDoReconciliation() && !projCtx.isFullShadow()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Skipping reconciliation of {}: no doReconciliation and no full shadow", projCtx.getHumanReadableName());
}
return;
}
SynchronizationPolicyDecision policyDecision = projCtx.getSynchronizationPolicyDecision();
if (policyDecision != null && (policyDecision == SynchronizationPolicyDecision.DELETE || policyDecision == SynchronizationPolicyDecision.UNLINK)) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Skipping reconciliation of {}: decision={}", projCtx.getHumanReadableName(), policyDecision);
}
return;
}
if (projCtx.getObjectCurrent() == null) {
LOGGER.warn("Can't do reconciliation. Account context doesn't contain current version of account.");
return;
}
if (!projCtx.isFullShadow()) {
// We need to load the object
GetOperationOptions rootOps = GetOperationOptions.createDoNotDiscovery();
rootOps.setPointInTimeType(PointInTimeType.FUTURE);
PrismObject<ShadowType> objectOld = provisioningService.getObject(ShadowType.class, projCtx.getOid(), SelectorOptions.createCollection(rootOps), task, result);
ShadowType oldShadow = objectOld.asObjectable();
projCtx.determineFullShadowFlag(oldShadow.getFetchResult());
projCtx.setLoadedObject(objectOld);
projCtx.recompute();
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Starting reconciliation of {}", projCtx.getHumanReadableName());
}
reconcileAuxiliaryObjectClasses(projCtx);
RefinedObjectClassDefinition rOcDef = projCtx.getCompositeObjectClassDefinition();
Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> squeezedAttributes = projCtx.getSqueezedAttributes();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Attribute reconciliation processing {}", projCtx.getHumanReadableName());
}
reconcileProjectionAttributes(projCtx, squeezedAttributes, rOcDef);
Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> squeezedAssociations = projCtx.getSqueezedAssociations();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Association reconciliation processing {}", projCtx.getHumanReadableName());
}
reconcileProjectionAssociations(projCtx, squeezedAssociations, rOcDef, task, result);
reconcileMissingAuxiliaryObjectClassAttributes(projCtx);
} catch (RuntimeException | SchemaException e) {
subResult.recordFatalError(e);
throw e;
} finally {
subResult.computeStatus();
}
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType in project midpoint by Evolveum.
the class ShadowCacheReconciler method beforeModifyOnResource.
@Override
public Collection<? extends ItemDelta> beforeModifyOnResource(PrismObject<ShadowType> shadow, ProvisioningOperationOptions options, Collection<? extends ItemDelta> modifications) throws SchemaException {
ObjectDeltaType shadowDelta = shadow.asObjectable().getObjectChange();
//TODO: error handling
if (shadowDelta != null) {
modifications = DeltaConvertor.toModifications(shadowDelta.getItemDelta(), shadow.getDefinition());
}
// for the older versions
ObjectDelta<? extends ObjectType> objectDelta = ObjectDelta.createModifyDelta(shadow.getOid(), modifications, ShadowType.class, getPrismContext());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Storing delta to shadow:\n{}", objectDelta.debugDump());
}
ContainerDelta<ShadowAssociationType> associationDelta = objectDelta.findContainerDelta(ShadowType.F_ASSOCIATION);
if (associationDelta != null) {
normalizeAssociationDeltasBeforeSave(associationDelta.getValuesToAdd());
normalizeAssociationDeltasBeforeSave(associationDelta.getValuesToReplace());
normalizeAssociationDeltasBeforeSave(associationDelta.getValuesToDelete());
}
if (modifications == null) {
modifications = new ArrayList<ItemDelta>();
}
return modifications;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType in project midpoint by Evolveum.
the class EntitlementConverter method postProcessEntitlementEntitlementToSubject.
private <S extends ShadowType, T> void postProcessEntitlementEntitlementToSubject(ProvisioningContext subjectCtx, final PrismObject<S> resourceObject, RefinedAssociationDefinition assocDefType, final ProvisioningContext entitlementCtx, ResourceAttributeContainer attributesContainer, final PrismContainer<ShadowAssociationType> associationContainer, OperationResult parentResult) throws SchemaException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
ResourceType resourceType = subjectCtx.getResource();
final QName associationName = assocDefType.getName();
final RefinedObjectClassDefinition entitlementDef = entitlementCtx.getObjectClassDefinition();
if (associationName == null) {
throw new SchemaException("No name in entitlement association " + assocDefType + " in " + resourceType);
}
QName associationAuxiliaryObjectClass = assocDefType.getAuxiliaryObjectClass();
if (associationAuxiliaryObjectClass != null && associationAuxiliaryObjectClass.getNamespaceURI() != null && !associationAuxiliaryObjectClass.getNamespaceURI().equals(ResourceTypeUtil.getResourceNamespace(resourceType))) {
LOGGER.warn("Auxiliary object class {} in association {} does not have namespace that matches {}", associationAuxiliaryObjectClass, assocDefType.getName(), resourceType);
}
if (associationAuxiliaryObjectClass != null && !subjectCtx.getObjectClassDefinition().hasAuxiliaryObjectClass(associationAuxiliaryObjectClass)) {
LOGGER.trace("Ignoring association {} because subject does not have auxiliary object class {}, it has {}", associationName, associationAuxiliaryObjectClass, subjectCtx.getObjectClassDefinition().getAuxiliaryObjectClassDefinitions());
return;
}
QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute();
if (assocAttrName == null) {
throw new SchemaException("No association attribute defined in entitlement association '" + associationName + "' in " + resourceType);
}
RefinedAttributeDefinition assocAttrDef = entitlementDef.findAttributeDefinition(assocAttrName);
if (assocAttrDef == null) {
throw new SchemaException("Association attribute '" + assocAttrName + "'defined in entitlement association '" + associationName + "' was not found in schema for " + resourceType);
}
QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute();
if (valueAttrName == null) {
throw new SchemaException("No value attribute defined in entitlement association '" + associationName + "' in " + resourceType);
}
ResourceAttribute<T> valueAttr = attributesContainer.findAttribute(valueAttrName);
if (valueAttr == null || valueAttr.isEmpty()) {
LOGGER.trace("Ignoring association {} because subject does not have any value in attribute {}", associationName, valueAttrName);
return;
}
if (valueAttr.size() > 1) {
throw new SchemaException("Value attribute " + valueAttrName + " has no more than one value; attribute defined in entitlement association '" + associationName + "' in " + resourceType);
}
ObjectQuery query = createQuery(assocDefType, assocAttrDef, valueAttr);
AttributesToReturn attributesToReturn = ProvisioningUtil.createAttributesToReturn(entitlementCtx);
SearchHierarchyConstraints searchHierarchyConstraints = null;
ResourceObjectReferenceType baseContextRef = entitlementDef.getBaseContext();
if (baseContextRef != null) {
// TODO: this should be done once per search. Not in every run of postProcessEntitlementEntitlementToSubject
// this has to go outside of this method
PrismObject<ShadowType> baseContextShadow = resourceObjectReferenceResolver.resolve(subjectCtx, baseContextRef, null, "base context specification in " + entitlementDef, parentResult);
RefinedObjectClassDefinition baseContextObjectClassDefinition = subjectCtx.getRefinedSchema().determineCompositeObjectClassDefinition(baseContextShadow);
ResourceObjectIdentification baseContextIdentification = ShadowUtil.getResourceObjectIdentification(baseContextShadow, baseContextObjectClassDefinition);
searchHierarchyConstraints = new SearchHierarchyConstraints(baseContextIdentification, null);
}
ResultHandler<ShadowType> handler = new ResultHandler<ShadowType>() {
@Override
public boolean handle(PrismObject<ShadowType> entitlementShadow) {
PrismContainerValue<ShadowAssociationType> associationCVal = associationContainer.createNewValue();
associationCVal.asContainerable().setName(associationName);
Collection<ResourceAttribute<?>> entitlementIdentifiers = ShadowUtil.getAllIdentifiers(entitlementShadow);
try {
ResourceAttributeContainer identifiersContainer = new ResourceAttributeContainer(ShadowAssociationType.F_IDENTIFIERS, entitlementDef.toResourceAttributeContainerDefinition(), prismContext);
associationCVal.add(identifiersContainer);
identifiersContainer.getValue().addAll(ResourceAttribute.cloneCollection(entitlementIdentifiers));
// Remember the full shadow in user data. This is used later as an optimization to create the shadow in repo
identifiersContainer.setUserData(ResourceObjectConverter.FULL_SHADOW_KEY, entitlementShadow);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processed entitlement-to-subject association for account {} and entitlement {}", ShadowUtil.getHumanReadableName(resourceObject), ShadowUtil.getHumanReadableName(entitlementShadow));
}
} catch (SchemaException e) {
throw new TunnelException(e);
}
return true;
}
};
ConnectorInstance connector = subjectCtx.getConnector(ReadCapabilityType.class, parentResult);
try {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processed entitlement-to-subject association for account {}: query {}", ShadowUtil.getHumanReadableName(resourceObject), query);
}
try {
connector.search(entitlementDef, query, handler, attributesToReturn, null, searchHierarchyConstraints, subjectCtx, parentResult);
} catch (GenericFrameworkException e) {
throw new GenericConnectorException("Generic error in the connector " + connector + ". Reason: " + e.getMessage(), e);
}
} catch (TunnelException e) {
throw (SchemaException) e.getCause();
}
}
Aggregations