Skip to content

Commit

Permalink
Add more complex async tests in provisioning
Browse files Browse the repository at this point in the history
Plus a small fix in prism parsing.
  • Loading branch information
mederly committed Mar 11, 2019
1 parent 9a091d7 commit 362c778
Show file tree
Hide file tree
Showing 17 changed files with 440 additions and 85 deletions.
Expand Up @@ -217,11 +217,12 @@ private static <ID extends ItemDefinition> ID augmentWithClass(ID definition, Cl
return definition;
}
@SuppressWarnings("unchecked")
List<ID> defFromClass = schemaRegistry.findItemDefinitionsByCompileTimeClass((Class) clazz, (Class) definitionClass);
if (defFromClass.size() != 1) {
List<ID> defFromClass = schemaRegistry.findItemDefinitionsByCompileTimeClass(clazz, (Class) definitionClass);
ID singleDef = DefinitionStoreUtils.getOne(defFromClass, false, null);
if (singleDef == null) {
return definition;
} else {
return schemaRegistry.selectMoreSpecific(definition, defFromClass.get(0));
return schemaRegistry.selectMoreSpecific(definition, singleDef);
}
}

Expand Down
Expand Up @@ -10751,40 +10751,40 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="identifiers" type="tns:ShadowAttributesType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Identifiers of the object being changed.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objectClass" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Object class.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objectDelta" type="t:ObjectDeltaType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Delta describing the changes made to the shadow. E.g. if the change in the resource was
to add new account, delta will contain ADD modification with the object specified.
It may be null. If the object delta is null, the current object has to be specified.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="object" type="tns:ShadowType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Current state of the object. Either it or the delta has to be specified.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="objectClass" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Object class. Should be provided.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="identifiers" type="tns:ShadowAttributesType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Identifiers of the object being changed. Should be provided if not present in object or object delta.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objectDelta" type="t:ObjectDeltaType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Delta describing the changes made to the shadow. E.g. if the change in the resource was
to add new account, delta will contain ADD modification with the object specified.
It may be null. If the object delta is null, the current object has to be specified.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="object" type="tns:ShadowType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Current state of the object. Either it or the delta has to be specified.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:element name="ucfChange" type="tns:UcfChangeType"/>
<xsd:element name="ucfChange" type="tns:UcfChangeType"/>

<xsd:complexType name="ConnectorType">
<xsd:annotation>
Expand Down Expand Up @@ -11139,7 +11139,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objectClass" type="xsd:QName">
<xsd:element name="objectClass" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The reference to a type definition for this object. The reference should point
Expand All @@ -11148,6 +11148,9 @@
The attributes contained in the "attributes" element below are expected to
comply with the type definition specified in this element (with addition of
auxiliary object class definitions).

Formally, minOccurs is 0 here but unless a reasonable default is provided, the value
must be present.
</xsd:documentation>
<xsd:appinfo>
<a:displayName>ShadowType.objectClass</a:displayName>
Expand Down
Expand Up @@ -95,45 +95,43 @@ public void postProcessEntitlementsRead(ProvisioningContext subjectCtx,
LOGGER.trace("Starting postProcessEntitlementRead");
RefinedObjectClassDefinition objectClassDefinition = subjectCtx.getObjectClassDefinition();
Collection<RefinedAssociationDefinition> entitlementAssociationDefs = objectClassDefinition.getAssociationDefinitions();
if (entitlementAssociationDefs != null) {
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(resourceObject);
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(resourceObject);

PrismContainerDefinition<ShadowAssociationType> associationDef = resourceObject.getDefinition().findContainerDefinition(ShadowType.F_ASSOCIATION);
PrismContainer<ShadowAssociationType> associationContainer = associationDef.instantiate();
PrismContainerDefinition<ShadowAssociationType> associationDef = resourceObject.getDefinition().findContainerDefinition(ShadowType.F_ASSOCIATION);
PrismContainer<ShadowAssociationType> associationContainer = associationDef.instantiate();

for (RefinedAssociationDefinition assocDefType: entitlementAssociationDefs) {
ShadowKindType entitlementKind = assocDefType.getKind();
if (entitlementKind == null) {
entitlementKind = ShadowKindType.ENTITLEMENT;
for (RefinedAssociationDefinition assocDefType: entitlementAssociationDefs) {
ShadowKindType entitlementKind = assocDefType.getKind();
if (entitlementKind == null) {
entitlementKind = ShadowKindType.ENTITLEMENT;
}
for (String entitlementIntent: assocDefType.getIntents()) {
LOGGER.trace("Resolving association {} for kind {} and intent {}", assocDefType.getName(), entitlementKind, entitlementIntent);
ProvisioningContext entitlementCtx = subjectCtx.spawn(entitlementKind, entitlementIntent);
RefinedObjectClassDefinition entitlementDef = entitlementCtx.getObjectClassDefinition();
if (entitlementDef == null) {
throw new SchemaException("No definition for entitlement intent(s) '"+assocDefType.getIntents()+"' in "+resourceType);
}
for (String entitlementIntent: assocDefType.getIntents()) {
LOGGER.trace("Resolving association {} for kind {} and intent {}", assocDefType.getName(), entitlementKind, entitlementIntent);
ProvisioningContext entitlementCtx = subjectCtx.spawn(entitlementKind, entitlementIntent);
RefinedObjectClassDefinition entitlementDef = entitlementCtx.getObjectClassDefinition();
if (entitlementDef == null) {
throw new SchemaException("No definition for entitlement intent(s) '"+assocDefType.getIntents()+"' in "+resourceType);
}
ResourceObjectAssociationDirectionType direction = assocDefType.getResourceObjectAssociationType().getDirection();
if (direction == ResourceObjectAssociationDirectionType.SUBJECT_TO_OBJECT) {
postProcessEntitlementSubjectToEntitlement(resourceType, resourceObject, objectClassDefinition, assocDefType, entitlementDef, attributesContainer, associationContainer, parentResult);
} else if (direction == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) {
if (assocDefType.getResourceObjectAssociationType().getShortcutAssociationAttribute() != null) {
postProcessEntitlementSubjectToEntitlement(resourceType, resourceObject, objectClassDefinition,
assocDefType, entitlementDef, attributesContainer, associationContainer,
assocDefType.getResourceObjectAssociationType().getShortcutAssociationAttribute(),
assocDefType.getResourceObjectAssociationType().getShortcutValueAttribute(), parentResult);
} else {
postProcessEntitlementEntitlementToSubject(subjectCtx, resourceObject, assocDefType, entitlementCtx, attributesContainer, associationContainer, parentResult);
}
ResourceObjectAssociationDirectionType direction = assocDefType.getResourceObjectAssociationType().getDirection();
if (direction == ResourceObjectAssociationDirectionType.SUBJECT_TO_OBJECT) {
postProcessEntitlementSubjectToEntitlement(resourceType, resourceObject, objectClassDefinition, assocDefType, entitlementDef, attributesContainer, associationContainer, parentResult);
} else if (direction == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) {
if (assocDefType.getResourceObjectAssociationType().getShortcutAssociationAttribute() != null) {
postProcessEntitlementSubjectToEntitlement(resourceType, resourceObject, objectClassDefinition,
assocDefType, entitlementDef, attributesContainer, associationContainer,
assocDefType.getResourceObjectAssociationType().getShortcutAssociationAttribute(),
assocDefType.getResourceObjectAssociationType().getShortcutValueAttribute(), parentResult);
} else {
throw new IllegalArgumentException("Unknown entitlement direction "+direction+" in association "+assocDefType+" in "+resourceType);
postProcessEntitlementEntitlementToSubject(subjectCtx, resourceObject, assocDefType, entitlementCtx, attributesContainer, associationContainer, parentResult);
}
} else {
throw new IllegalArgumentException("Unknown entitlement direction "+direction+" in association "+assocDefType+" in "+resourceType);
}
}
}

if (!associationContainer.isEmpty()) {
resourceObject.add(associationContainer);
}
if (!associationContainer.isEmpty()) {
resourceObject.add(associationContainer);
}
}

Expand Down
Expand Up @@ -32,6 +32,7 @@
import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
import com.evolveum.midpoint.repo.cache.RepositoryCache;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalsConfig;
import com.evolveum.midpoint.schema.processor.*;
Expand Down Expand Up @@ -1870,6 +1871,7 @@ public void startListeningForAsyncUpdates(@NotNull ProvisioningContext ctx,
ChangeListener innerListener = change -> {
try {
LOGGER.trace("Start processing change:\n{}", change.debugDumpLazily());
setResourceOidIfMissing(change, ctx.getResourceOid());
ProvisioningContext shadowCtx = ctx;
PrismObject<ShadowType> currentShadow = change.getCurrentShadow();
ObjectClassComplexTypeDefinition changeObjectClassDefinition = change.getObjectClassDefinition();
Expand Down Expand Up @@ -1905,6 +1907,9 @@ public void startListeningForAsyncUpdates(@NotNull ProvisioningContext ctx,
// TODO: Maybe change to DELETE instead of this?
}
}
if (change.getCurrentShadow() != null) {
shadowCaretaker.applyAttributesDefinition(ctx, change.getCurrentShadow());
}
PrismObject<ShadowType> processedCurrentShadow = postProcessResourceObjectRead(shadowCtx,
currentShadow, true, parentResult);
change.setCurrentShadow(processedCurrentShadow);
Expand All @@ -1920,6 +1925,20 @@ public void startListeningForAsyncUpdates(@NotNull ProvisioningContext ctx,
LOGGER.trace("END start listening for async updates");
}

private void setResourceOidIfMissing(Change change, String resourceOid) {
setResourceOidIfMissing(change.getOldShadow(), resourceOid);
setResourceOidIfMissing(change.getCurrentShadow(), resourceOid);
if (change.getObjectDelta() != null) {
setResourceOidIfMissing(change.getObjectDelta().getObjectToAdd(), resourceOid);
}
}

private void setResourceOidIfMissing(PrismObject<ShadowType> object, String resourceOid) {
if (object != null && object.asObjectable().getResourceRef() == null && resourceOid != null) {
object.asObjectable().setResourceRef(ObjectTypeUtil.createObjectRef(resourceOid, ObjectTypes.RESOURCE));
}
}

public void stopListeningForAsyncUpdates(@NotNull ProvisioningContext ctx,
@NotNull OperationResult parentResult) throws SchemaException,
CommunicationException, ConfigurationException, ObjectNotFoundException, ExpressionEvaluationException {
Expand Down
Expand Up @@ -2469,7 +2469,7 @@ public void startListeningForAsyncUpdates(ResourceShadowDiscriminator shadowCoor
shadowCaretaker.applyAttributesDefinition(ctx, change.getOldShadow());
}
if (change.getCurrentShadow() != null) {
shadowCaretaker.applyAttributesDefinition(ctx, change.getCurrentShadow());
shadowCaretaker.applyAttributesDefinition(ctx, change.getCurrentShadow()); // maybe redundant
}

ProvisioningContext shadowCtx;
Expand Down
Expand Up @@ -1728,7 +1728,6 @@ public PrismObject<ShadowType> updateShadow(ProvisioningContext ctx, PrismObject
PrismContainer<Containerable> currentResourceAttributesContainer = currentResourceShadow.findContainer(ShadowType.F_ATTRIBUTES);
PrismContainer<Containerable> oldRepoAttributesContainer = oldRepoShadow.findContainer(ShadowType.F_ATTRIBUTES);
ShadowType oldRepoShadowType = oldRepoShadow.asObjectable();
ShadowType currentResourceShadowType = currentResourceShadow.asObjectable();

CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx);

Expand Down

0 comments on commit 362c778

Please sign in to comment.