use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType in project midpoint by Evolveum.
the class KindIntentFilterHelper method processEvent.
@Override
public boolean processEvent(Event event, EventHandlerType eventHandlerType, NotificationManager notificationManager, Task task, OperationResult result) {
if (eventHandlerType.getObjectKind().isEmpty() && eventHandlerType.getObjectIntent().isEmpty()) {
return true;
}
if (!(event instanceof ResourceObjectEvent)) {
// or should we return false?
return true;
}
ResourceObjectEvent resourceObjectEvent = (ResourceObjectEvent) event;
logStart(LOGGER, event, eventHandlerType, eventHandlerType.getStatus());
boolean retval = true;
if (!eventHandlerType.getObjectKind().isEmpty()) {
retval = false;
for (ShadowKindType shadowKindType : eventHandlerType.getObjectKind()) {
if (shadowKindType == null) {
LOGGER.warn("Filtering on null shadowKindType; filter = " + eventHandlerType);
} else if (resourceObjectEvent.isShadowKind(shadowKindType)) {
retval = true;
break;
}
}
}
if (retval) {
// now check the intent
if (!eventHandlerType.getObjectIntent().isEmpty()) {
retval = false;
for (String intent : eventHandlerType.getObjectIntent()) {
if (intent == null) {
LOGGER.warn("Filtering on null intent; filter = " + eventHandlerType);
} else if (resourceObjectEvent.isShadowIntent(intent)) {
retval = true;
break;
}
}
}
}
logEnd(LOGGER, event, eventHandlerType, retval);
return retval;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType in project midpoint by Evolveum.
the class EntitlementConverter method collectEntitlementAsObjectOperation.
private <TV, TA> PrismObject<ShadowType> collectEntitlementAsObjectOperation(ProvisioningContext subjectCtx, Map<ResourceObjectDiscriminator, ResourceObjectOperations> roMap, PrismContainerValue<ShadowAssociationType> associationCVal, PrismObject<ShadowType> subjectShadowBefore, PrismObject<ShadowType> subjectShadowAfter, ModificationType modificationType, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
ResourceType resource = subjectCtx.getResource();
ShadowAssociationType associationType = associationCVal.asContainerable();
QName associationName = associationType.getName();
if (associationName == null) {
throw new SchemaException("No name in entitlement association " + associationCVal);
}
RefinedAssociationDefinition assocDefType = subjectCtx.getObjectClassDefinition().findAssociationDefinition(associationName);
if (assocDefType == null) {
throw new SchemaException("No entitlement association with name " + assocDefType + " in schema of " + resource);
}
ResourceObjectAssociationDirectionType direction = assocDefType.getResourceObjectAssociationType().getDirection();
if (direction != ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) {
// Process just this one direction. The other direction was processed before
return subjectShadowAfter;
}
Collection<String> entitlementIntents = assocDefType.getIntents();
if (entitlementIntents == null || entitlementIntents.isEmpty()) {
throw new SchemaException("No entitlement intent specified in association " + associationCVal + " in " + resource);
}
ShadowKindType entitlementKind = assocDefType.getKind();
if (entitlementKind == null) {
entitlementKind = ShadowKindType.ENTITLEMENT;
}
for (String entitlementIntent : entitlementIntents) {
ProvisioningContext entitlementCtx = subjectCtx.spawn(entitlementKind, entitlementIntent);
RefinedObjectClassDefinition entitlementOcDef = entitlementCtx.getObjectClassDefinition();
if (entitlementOcDef == null) {
throw new SchemaException("No definition of entitlement intent(s) '" + entitlementIntents + "' specified in association " + associationCVal + " in " + resource);
}
QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute();
if (assocAttrName == null) {
throw new SchemaException("No association attribute defined in entitlement association in " + resource);
}
RefinedAttributeDefinition assocAttrDef = entitlementOcDef.findAttributeDefinition(assocAttrName);
if (assocAttrDef == null) {
throw new SchemaException("Association attribute '" + assocAttrName + "'defined in entitlement association was not found in entitlement intent(s) '" + entitlementIntents + "' in schema for " + resource);
}
ResourceAttributeContainer identifiersContainer = ShadowUtil.getAttributesContainer(associationCVal, ShadowAssociationType.F_IDENTIFIERS);
Collection<ResourceAttribute<?>> entitlementIdentifiersFromAssociation = identifiersContainer.getAttributes();
ResourceObjectDiscriminator disc = new ResourceObjectDiscriminator(entitlementOcDef.getTypeName(), entitlementIdentifiersFromAssociation);
ResourceObjectOperations operations = roMap.get(disc);
if (operations == null) {
operations = new ResourceObjectOperations();
operations.setResourceObjectContext(entitlementCtx);
roMap.put(disc, operations);
}
QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute();
if (valueAttrName == null) {
throw new SchemaException("No value attribute defined in entitlement association in " + resource);
}
// Which shadow would we use - shadowBefore or shadowAfter?
//
// If the operation is ADD or REPLACE, we use current version of the shadow (shadowAfter), because we want
// to ensure that we add most-recent data to the subject.
//
// If the operation is DELETE, we have two possibilities:
// - if the resource provides referential integrity, the subject has already
// new data (because the object operation was already carried out), so we use shadowAfter
// - if the resource does not provide referential integrity, the subject has OLD data
// so we use shadowBefore
PrismObject<ShadowType> subjectShadow;
if (modificationType != ModificationType.DELETE) {
subjectShadow = subjectShadowAfter;
} else {
if (assocDefType.requiresExplicitReferentialIntegrity()) {
// we must ensure the referential integrity
subjectShadow = subjectShadowBefore;
} else {
// i.e. resource has ref integrity assured by itself
subjectShadow = subjectShadowAfter;
}
}
ResourceAttribute<TV> valueAttr = ShadowUtil.getAttribute(subjectShadow, valueAttrName);
if (valueAttr == null) {
if (!ShadowUtil.isFullShadow(subjectShadow)) {
Collection<ResourceAttribute<?>> subjectIdentifiers = ShadowUtil.getAllIdentifiers(subjectShadow);
LOGGER.trace("Fetching {} ({})", subjectShadow, subjectIdentifiers);
subjectShadow = resourceObjectReferenceResolver.fetchResourceObject(subjectCtx, subjectIdentifiers, null, result);
subjectShadowAfter = subjectShadow;
valueAttr = ShadowUtil.getAttribute(subjectShadow, valueAttrName);
}
if (valueAttr == null) {
LOGGER.error("No value attribute {} in shadow\n{}", valueAttrName, subjectShadow.debugDump());
// TODO: check schema and try to fetch full shadow if necessary
throw new SchemaException("No value attribute " + valueAttrName + " in " + subjectShadow);
}
}
PropertyDelta<TA> attributeDelta = null;
for (Operation operation : operations.getOperations()) {
if (operation instanceof PropertyModificationOperation) {
PropertyModificationOperation propOp = (PropertyModificationOperation) operation;
if (propOp.getPropertyDelta().getElementName().equals(assocAttrName)) {
attributeDelta = propOp.getPropertyDelta();
}
}
}
if (attributeDelta == null) {
attributeDelta = assocAttrDef.createEmptyDelta(new ItemPath(ShadowType.F_ATTRIBUTES, assocAttrName));
}
PrismProperty<TA> changedAssocAttr = PrismUtil.convertProperty(valueAttr, assocAttrDef);
if (modificationType == ModificationType.ADD) {
attributeDelta.addValuesToAdd(changedAssocAttr.getClonedValues());
} else if (modificationType == ModificationType.DELETE) {
attributeDelta.addValuesToDelete(changedAssocAttr.getClonedValues());
} else if (modificationType == ModificationType.REPLACE) {
// TODO: check if already exists
attributeDelta.setValuesToReplace(changedAssocAttr.getClonedValues());
}
if (ResourceTypeUtil.isAvoidDuplicateValues(resource)) {
PrismObject<ShadowType> currentObjectShadow = operations.getCurrentShadow();
if (currentObjectShadow == null) {
LOGGER.trace("Fetching entitlement shadow {} to avoid value duplication (intent={})", entitlementIdentifiersFromAssociation, entitlementIntent);
currentObjectShadow = resourceObjectReferenceResolver.fetchResourceObject(entitlementCtx, entitlementIdentifiersFromAssociation, null, result);
operations.setCurrentShadow(currentObjectShadow);
}
// TODO it seems that duplicate values are checked twice: once here and the second time in ResourceObjectConverter.executeModify
// TODO check that and fix if necessary
PropertyDelta<TA> attributeDeltaAfterNarrow = ProvisioningUtil.narrowPropertyDelta(attributeDelta, currentObjectShadow, assocDefType.getMatchingRule(), matchingRuleRegistry);
if (LOGGER.isTraceEnabled() && (attributeDeltaAfterNarrow == null || attributeDeltaAfterNarrow.isEmpty())) {
LOGGER.trace("Not collecting entitlement object operations ({}) association {}: attribute delta is empty after narrow, orig delta: {}", modificationType, associationName.getLocalPart(), attributeDelta);
}
attributeDelta = attributeDeltaAfterNarrow;
}
if (attributeDelta != null && !attributeDelta.isEmpty()) {
PropertyModificationOperation attributeModification = new PropertyModificationOperation(attributeDelta);
attributeModification.setMatchingRuleQName(assocDefType.getMatchingRule());
LOGGER.trace("Collecting entitlement object operations ({}) association {}: {}", modificationType, associationName.getLocalPart(), attributeModification);
operations.add(attributeModification);
}
}
return subjectShadowAfter;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType in project midpoint by Evolveum.
the class EntitlementConverter method collectEntitlementsAsObjectOperationDelete.
/////////
// DELETE
/////////
/**
* This is somehow different that all the other methods. We are not following the content of a shadow or delta. We are following
* the definitions. This is to avoid the need to read the object that is going to be deleted. In fact, the object should not be there
* any more, but we still want to clean up entitlement membership based on the information from the shadow.
*/
public <T> void collectEntitlementsAsObjectOperationDelete(ProvisioningContext subjectCtx, final Map<ResourceObjectDiscriminator, ResourceObjectOperations> roMap, PrismObject<ShadowType> subjectShadow, OperationResult parentResult) throws SchemaException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
Collection<RefinedAssociationDefinition> entitlementAssociationDefs = subjectCtx.getObjectClassDefinition().getAssociationDefinitions();
if (entitlementAssociationDefs == null || entitlementAssociationDefs.isEmpty()) {
// Nothing to do
LOGGER.trace("No associations in deleted shadow");
return;
}
ResourceAttributeContainer subjectAttributesContainer = ShadowUtil.getAttributesContainer(subjectShadow);
for (final RefinedAssociationDefinition assocDefType : subjectCtx.getObjectClassDefinition().getAssociationDefinitions()) {
if (assocDefType.getResourceObjectAssociationType().getDirection() != ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) {
// We can ignore these. They will die together with the object. No need to explicitly delete them.
LOGGER.trace("Ignoring subject-to-object association in deleted shadow");
continue;
}
if (!assocDefType.requiresExplicitReferentialIntegrity()) {
// Referential integrity not required for this one
LOGGER.trace("Ignoring association in deleted shadow because it does not require explicit referential integrity assurance");
continue;
}
if (assocDefType.getAuxiliaryObjectClass() != null && !subjectCtx.getObjectClassDefinition().hasAuxiliaryObjectClass(assocDefType.getAuxiliaryObjectClass())) {
LOGGER.trace("Ignoring association in deleted shadow because subject does not have {} auxiliary object class", assocDefType.getAuxiliaryObjectClass());
continue;
}
QName associationName = assocDefType.getName();
if (associationName == null) {
throw new SchemaException("No name in entitlement association " + assocDefType + " in " + subjectCtx.getResource());
}
ShadowKindType entitlementKind = assocDefType.getKind();
if (entitlementKind == null) {
entitlementKind = ShadowKindType.ENTITLEMENT;
}
for (String entitlementIntent : assocDefType.getIntents()) {
final ProvisioningContext entitlementCtx = subjectCtx.spawn(entitlementKind, entitlementIntent);
final RefinedObjectClassDefinition entitlementOcDef = entitlementCtx.getObjectClassDefinition();
if (entitlementOcDef == null) {
throw new SchemaException("No definition for entitlement intent(s) '" + assocDefType.getIntents() + "' defined in entitlement association " + associationName + " in " + subjectCtx.getResource());
}
final QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute();
if (assocAttrName == null) {
throw new SchemaException("No association attribute defined in entitlement association '" + associationName + "' in " + subjectCtx.getResource());
}
final RefinedAttributeDefinition assocAttrDef = entitlementOcDef.findAttributeDefinition(assocAttrName);
if (assocAttrDef == null) {
throw new SchemaException("Association attribute '" + assocAttrName + "'defined in entitlement association '" + associationName + "' was not found in schema for " + subjectCtx.getResource());
}
QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute();
if (valueAttrName == null) {
throw new SchemaException("No value attribute defined in entitlement association '" + associationName + "' in " + subjectCtx.getResource());
}
final ResourceAttribute<T> valueAttr = subjectAttributesContainer.findAttribute(valueAttrName);
if (valueAttr == null || valueAttr.isEmpty()) {
// Although we cannot really remedy the situation now, we at least throw an error so the problem is detected.
throw new SchemaException("Value attribute " + valueAttrName + " has no value; attribute defined in entitlement association '" + associationName + "' in " + subjectCtx.getResource());
}
if (valueAttr.size() > 1) {
throw new SchemaException("Value attribute " + valueAttrName + " has no more than one value; attribute defined in entitlement association '" + associationName + "' in " + subjectCtx.getResource());
}
ObjectQuery query = createQuery(assocDefType, assocAttrDef, valueAttr);
AttributesToReturn attributesToReturn = ProvisioningUtil.createAttributesToReturn(entitlementCtx);
SearchHierarchyConstraints searchHierarchyConstraints = null;
ResourceObjectReferenceType baseContextRef = entitlementOcDef.getBaseContext();
if (baseContextRef != null) {
PrismObject<ShadowType> baseContextShadow = resourceObjectReferenceResolver.resolve(subjectCtx, baseContextRef, null, "base context specification in " + entitlementOcDef, 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) {
Collection<? extends ResourceAttribute<?>> primaryIdentifiers = ShadowUtil.getPrimaryIdentifiers(entitlementShadow);
ResourceObjectDiscriminator disc = new ResourceObjectDiscriminator(entitlementOcDef.getTypeName(), primaryIdentifiers);
ResourceObjectOperations operations = roMap.get(disc);
if (operations == null) {
operations = new ResourceObjectOperations();
roMap.put(disc, operations);
operations.setResourceObjectContext(entitlementCtx);
Collection<? extends ResourceAttribute<?>> allIdentifiers = ShadowUtil.getAllIdentifiers(entitlementShadow);
operations.setAllIdentifiers(allIdentifiers);
}
PropertyDelta<T> attributeDelta = null;
for (Operation operation : operations.getOperations()) {
if (operation instanceof PropertyModificationOperation) {
PropertyModificationOperation propOp = (PropertyModificationOperation) operation;
if (propOp.getPropertyDelta().getElementName().equals(assocAttrName)) {
attributeDelta = propOp.getPropertyDelta();
}
}
}
if (attributeDelta == null) {
attributeDelta = assocAttrDef.createEmptyDelta(new ItemPath(ShadowType.F_ATTRIBUTES, assocAttrName));
PropertyModificationOperation attributeModification = new PropertyModificationOperation(attributeDelta);
attributeModification.setMatchingRuleQName(assocDefType.getMatchingRule());
operations.add(attributeModification);
}
attributeDelta.addValuesToDelete(valueAttr.getClonedValues());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Association in deleted shadow delta:\n{}", attributeDelta.debugDump());
}
return true;
}
};
try {
LOGGER.trace("Searching for associations in deleted shadow, query: {}", query);
ConnectorInstance connector = subjectCtx.getConnector(ReadCapabilityType.class, parentResult);
connector.search(entitlementOcDef, query, handler, attributesToReturn, null, searchHierarchyConstraints, subjectCtx, parentResult);
} catch (TunnelException e) {
throw (SchemaException) e.getCause();
} catch (GenericFrameworkException e) {
throw new GenericConnectorException(e.getMessage(), e);
}
}
}
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType in project midpoint by Evolveum.
the class MidPointSchemaDefinitionFactory method createObjectClassDefinition.
private ComplexTypeDefinition createObjectClassDefinition(XSComplexType complexType, PrismContext prismContext, XSAnnotation annotation) throws SchemaException {
QName typeName = new QName(complexType.getTargetNamespace(), complexType.getName());
ObjectClassComplexTypeDefinitionImpl ocDef = new ObjectClassComplexTypeDefinitionImpl(typeName, prismContext);
// nativeObjectClass
Element nativeAttrElement = SchemaProcessorUtil.getAnnotationElement(annotation, MidPointConstants.RA_NATIVE_OBJECT_CLASS);
String nativeObjectClass = nativeAttrElement == null ? null : nativeAttrElement.getTextContent();
ocDef.setNativeObjectClass(nativeObjectClass);
ShadowKindType kind = null;
Element kindElement = SchemaProcessorUtil.getAnnotationElement(annotation, MidPointConstants.RA_KIND);
if (kindElement != null) {
String kindString = kindElement.getTextContent();
if (StringUtils.isEmpty(kindString)) {
throw new SchemaException("The definition of kind is empty in the annotation of object class " + typeName);
}
try {
kind = ShadowKindType.fromValue(kindString);
} catch (IllegalArgumentException e) {
throw new SchemaException("Definition of unknown kind '" + kindString + "' in the annotation of object class " + typeName);
}
ocDef.setKind(kind);
}
Boolean defaultInAKind = SchemaProcessorUtil.getAnnotationBooleanMarker(annotation, MidPointConstants.RA_DEFAULT);
if (defaultInAKind == null) {
ocDef.setDefaultInAKind(false);
} else {
ocDef.setDefaultInAKind(defaultInAKind);
}
Boolean auxiliary = SchemaProcessorUtil.getAnnotationBooleanMarker(annotation, MidPointConstants.RA_AUXILIARY);
if (auxiliary == null) {
ocDef.setAuxiliary(false);
} else {
ocDef.setAuxiliary(auxiliary);
}
String intent = null;
Element intentElement = SchemaProcessorUtil.getAnnotationElement(annotation, MidPointConstants.RA_INTENT);
if (intentElement != null) {
intent = intentElement.getTextContent();
if (StringUtils.isEmpty(intent)) {
throw new SchemaException("The definition of intent is empty in the annotation of object class " + typeName);
}
ocDef.setIntent(intent);
}
// accountType: DEPRECATED
if (isAccountObject(annotation)) {
if (kind != null && kind != ShadowKindType.ACCOUNT) {
throw new SchemaException("Conflicting definition of kind and legacy account annotation in the annotation of object class " + typeName);
}
ocDef.setKind(ShadowKindType.ACCOUNT);
Element account = SchemaProcessorUtil.getAnnotationElement(annotation, MidPointConstants.RA_ACCOUNT);
if (account != null && !defaultInAKind) {
String defaultValue = account.getAttribute("default");
// Compatibility (DEPRECATED)
if (defaultValue != null) {
ocDef.setDefaultInAKind(Boolean.parseBoolean(defaultValue));
}
}
Element accountTypeElement = SchemaProcessorUtil.getAnnotationElement(annotation, MidPointConstants.RA_ACCOUNT_TYPE);
if (accountTypeElement != null) {
String accountType = accountTypeElement.getTextContent();
if (intent != null && !intent.equals(accountType)) {
throw new SchemaException("Conflicting definition of intent and legacy accountType annotation in the annotation of object class " + typeName);
}
ocDef.setIntent(accountType);
}
}
return ocDef;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType in project midpoint by Evolveum.
the class ModelClientUtil method createConstructionAssignment.
public static AssignmentType createConstructionAssignment(String resourceOid, ShadowKindType kind, String intent) {
AssignmentType assignment = new AssignmentType();
ConstructionType construction = new ConstructionType();
ObjectReferenceType resourceRef = new ObjectReferenceType();
resourceRef.setOid(resourceOid);
construction.setResourceRef(resourceRef);
if (kind != null) {
construction.setKind(kind);
}
if (intent != null) {
construction.setIntent(intent);
}
assignment.setConstruction(construction);
return assignment;
}
Aggregations