From 10608f8e37e9ef25552e802cc53901615ddd923b Mon Sep 17 00:00:00 2001 From: "Katarina Valalikova (katkav)" Date: Tue, 29 Jul 2014 16:35:43 +0200 Subject: [PATCH] fixing test..imroving rename operation.. --- .../impl/ResourceObjectConverter.java | 128 ++++++++++++++++-- .../provisioning/impl/ShadowCache.java | 78 +++++------ .../provisioning/impl/ShadowManager.java | 43 ++++++ .../api/PropertyModificationOperation.java | 4 +- .../provisioning/util/ProvisioningUtil.java | 4 + 5 files changed, 208 insertions(+), 49 deletions(-) diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java index 04f1d9310cf..7969ad97f16 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java @@ -62,6 +62,7 @@ import com.evolveum.midpoint.provisioning.ucf.api.Operation; import com.evolveum.midpoint.provisioning.ucf.api.PropertyModificationOperation; import com.evolveum.midpoint.provisioning.ucf.api.ResultHandler; +import com.evolveum.midpoint.provisioning.ucf.impl.ConnectorFactoryIcfImpl; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; @@ -71,9 +72,10 @@ import com.evolveum.midpoint.schema.processor.ResourceSchema; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.SchemaDebugUtil; +import com.evolveum.midpoint.schema.util.ShadowUtil; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.Holder; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -130,7 +132,7 @@ public class ResourceObjectConverter { @Autowired(required=true) private PrismContext prismContext; - private PrismObjectDefinition shadowTypeDefinition; +// private PrismObjectDefinition shadowTypeDefinition; private static final Trace LOGGER = TraceManager.getTrace(ResourceObjectConverter.class); @@ -432,8 +434,17 @@ public Collection modifyResourceObject( "Unable to modify account in the resource. Probably it has not been created yet because of previous unavailability of the resource."); } +// PrismObject currentShadow = null; + if (avoidDuplicateValues(resource) || isRename(operations)) { + // We need to filter out the deltas that add duplicate values or remove values that are not there + shadow = fetchResourceObject(connector, resource, objectClassDefinition, identifiers, null, parentResult); + } + // Execute primary ICF operation on this shadow - sideEffectChanges = executeModify(connector, resource, objectClassDefinition, identifiers, operations, parentResult); + sideEffectChanges = executeModify(connector, resource, shadow, objectClassDefinition, identifiers, operations, parentResult); + + + } /* @@ -444,6 +455,11 @@ public Collection modifyResourceObject( for (ItemDelta itemDelta : itemDeltas) { itemDelta.applyTo(shadowAfter); } + + if (isRename(operations)){ + Collection renameOperations = distillRenameDeltas(itemDeltas, shadowAfter, objectClassDefinition); + sideEffectChanges.addAll(renameOperations); + } // Execute entitlement modification on other objects (if needed) executeEntitlementChangesModify(connector, resource, objectClassDefinition, shadowBefore, shadowAfter, scripts, itemDeltas, parentResult); @@ -452,7 +468,7 @@ public Collection modifyResourceObject( return sideEffectChanges; } - private Collection executeModify(ConnectorInstance connector, ResourceType resource, + private Collection executeModify(ConnectorInstance connector, ResourceType resource, PrismObject currentShadow, RefinedObjectClassDefinition objectClassDefinition, Collection> identifiers, Collection operations, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException { Collection sideEffectChanges = null; @@ -464,10 +480,14 @@ private Collection executeModify(ConnectorInstanc // Invoke ICF try { - if (avoidDuplicateValues(resource)) { - // We need to filter out the deltas that add duplicate values or remove values that are not there + + + if (avoidDuplicateValues(resource)){ + + if (currentShadow == null){ + currentShadow = fetchResourceObject(connector, resource, objectClassDefinition, identifiers, null, parentResult); + } - PrismObject currentShadow = fetchResourceObject(connector, resource, objectClassDefinition, identifiers, null, parentResult); Collection filteredOperations = new ArrayList(operations.size()); for (Operation origOperation: operations) { if (origOperation instanceof PropertyModificationOperation) { @@ -506,7 +526,8 @@ private Collection executeModify(ConnectorInstanc sideEffectChanges = connector.modifyObject(objectClassDefinition, identifiers, operations, parentResult); - + + LOGGER.debug("PROVISIONING MODIFY successful, side-effect changes {}", SchemaDebugUtil.debugDump(sideEffectChanges)); @@ -540,6 +561,95 @@ private Collection executeModify(ConnectorInstanc return sideEffectChanges; } + private boolean isRename(Collection modifications){ + for (Operation op : modifications){ + if (!(op instanceof PropertyModificationOperation)){ + continue; + } + + if (((PropertyModificationOperation)op).getPropertyDelta().getPath().equals(new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME))){ + return true; + } + } + return false; +// return ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class) != null; + } + +// private Collection distillRenameDeltas(Collection modifications, +// PrismObject shadow, RefinedObjectClassDefinition objectClassDefinition) throws SchemaException { +// +// PropertyModificationOperation nameDelta =null; +// +// for (Operation op : modifications){ +// +// if (!(op instanceof PropertyModificationOperation)){ +// continue; +// } +// +// if (((PropertyModificationOperation)op).getPropertyDelta().getPath().equals(new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME))){ +// nameDelta = (PropertyModificationOperation) op; +// } +// } +// +// PropertyDelta namePropertyDelta = nameDelta.getPropertyDelta(); +// +// PrismProperty name = namePropertyDelta.getPropertyNew(); +// String newName = name.getRealValue(); +// +// Collection deltas = new ArrayList(); +// +// // $shadow/attributes/icfs:name +//// String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName())); +// PropertyDelta cloneNameDelta = namePropertyDelta.clone(); +// cloneNameDelta.clearValuesToReplace(); +// cloneNameDelta.setValueToReplace(new PrismPropertyValue(newName)); +// PropertyModificationOperation operation = new PropertyModificationOperation(cloneNameDelta); +// deltas.add(operation); +// +// // $shadow/name +// if (!newName.equals(shadow.asObjectable().getName().getOrig())){ +// +// PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, shadow.getDefinition(), +// ProvisioningUtil.determineShadowName(shadow)); +// operation = new PropertyModificationOperation(shadowNameDelta); +// deltas.add(operation); +// } +// +// return deltas; +//} + private Collection distillRenameDeltas(Collection modifications, + PrismObject shadow, RefinedObjectClassDefinition objectClassDefinition) throws SchemaException { + + PropertyDelta nameDelta = (PropertyDelta) ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class); + if (nameDelta == null){ + return null; + } + + PrismProperty name = nameDelta.getPropertyNew(); + String newName = name.getRealValue(); + + Collection deltas = new ArrayList(); + + // $shadow/attributes/icfs:name +// String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName())); + PropertyDelta cloneNameDelta = nameDelta.clone(); + cloneNameDelta.clearValuesToReplace(); + cloneNameDelta.setValueToReplace(new PrismPropertyValue(newName)); + PropertyModificationOperation operation = new PropertyModificationOperation(cloneNameDelta); + deltas.add(operation); + + // $shadow/name +// if (!newName.equals(shadow.asObjectable().getName().getOrig())){ + + PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, shadow.getDefinition(), + ProvisioningUtil.determineShadowName(shadow)); + operation = new PropertyModificationOperation(shadowNameDelta); + deltas.add(operation); +// } + + return deltas; + } + private void executeEntitlementChangesAdd(ConnectorInstance connector, ResourceType resource, RefinedObjectClassDefinition objectClassDefinition, PrismObject shadow, OperationProvisioningScriptsType scripts, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException { @@ -613,7 +723,7 @@ private void executeEntitlements(ConnectorInstance connector, ResourceType resou // TODO: better handling of result, partial failures, etc. - executeModify(connector, resource, ocDef, identifiers, operations, parentResult); + executeModify(connector, resource, null, ocDef, identifiers, operations, parentResult); } } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 0aeab11ab51..254a64b2c29 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import com.evolveum.midpoint.common.Utils; import com.evolveum.midpoint.common.monitor.InternalMonitor; import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; @@ -445,15 +446,16 @@ public String modifyShadow(PrismObject shadow, ResourceType resource afterModifyOnResource(shadow, modifications, parentResult); - Collection> renameDeltas = distillRenameDeltas(modifications, shadow, objectClassDefinition, task, parentResult); +// Collection> renameDeltas = distillRenameDeltas(modifications, shadow, objectClassDefinition, task, parentResult); - Collection sideEffectDelta = convertToPropertyDelta(sideEffectChanges); - if (renameDeltas != null) { - ((Collection) sideEffectDelta).addAll(renameDeltas); - } + Collection> sideEffectDelta = convertToPropertyDelta(sideEffectChanges); +// shadowManager. +// if (renameDeltas != null) { +// ((Collection) sideEffectDelta).addAll(renameDeltas); +// } if (!sideEffectDelta.isEmpty()) { try { - + shadowManager.normalizeDeltas(sideEffectDelta, objectClassDefinition); repositoryService.modifyObject(shadow.getCompileTimeClass(), oid, sideEffectDelta, parentResult); } catch (ObjectAlreadyExistsException ex) { @@ -471,40 +473,40 @@ public String modifyShadow(PrismObject shadow, ResourceType resource return oid; } - private Collection> distillRenameDeltas(Collection modifications, - PrismObject shadow, RefinedObjectClassDefinition objectClassDefinition, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { - PropertyDelta nameDelta = (PropertyDelta) ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class); - if (nameDelta == null){ - return null; - } - - PrismProperty name = nameDelta.getPropertyNew(); - String newName = name.getRealValue(); - - Collection> deltas = new ArrayList>(); - - // $shadow/attributes/icfs:name - String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName())); - PropertyDelta cloneNameDelta = nameDelta.clone(); - cloneNameDelta.clearValuesToReplace(); - cloneNameDelta.setValueToReplace(new PrismPropertyValue(normalizedNewName)); - deltas.add(cloneNameDelta); - - // $shadow/name - if (!newName.equals(shadow.asObjectable().getName().getOrig())){ - - PrismObject fullShadow = getShadow(shadow.getOid(), shadow, null, task, parentResult); - PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, shadow.getDefinition(), - ProvisioningUtil.determineShadowName(fullShadow)); - deltas.add(shadowNameDelta); - } - - return deltas; - } +// private Collection> distillRenameDeltas(Collection modifications, +// PrismObject shadow, RefinedObjectClassDefinition objectClassDefinition, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { +// PropertyDelta nameDelta = (PropertyDelta) ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class); +// if (nameDelta == null){ +// return null; +// } +// +// PrismProperty name = nameDelta.getPropertyNew(); +// String newName = name.getRealValue(); +// +// Collection> deltas = new ArrayList>(); +// +// // $shadow/attributes/icfs:name +// String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName())); +// PropertyDelta cloneNameDelta = nameDelta.clone(); +// cloneNameDelta.clearValuesToReplace(); +// cloneNameDelta.setValueToReplace(new PrismPropertyValue(normalizedNewName)); +// deltas.add(cloneNameDelta); +// +// // $shadow/name +// if (!newName.equals(shadow.asObjectable().getName().getOrig())){ +// +// PrismObject fullShadow = getShadow(shadow.getOid(), shadow, null, task, parentResult); +// PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, shadow.getDefinition(), +// ProvisioningUtil.determineShadowName(fullShadow)); +// deltas.add(shadowNameDelta); +// } +// +// return deltas; +// } - private Collection convertToPropertyDelta( + private Collection> convertToPropertyDelta( Collection sideEffectChanges) { - Collection sideEffectDelta = new ArrayList(); + Collection> sideEffectDelta = new ArrayList>(); if (sideEffectChanges != null) { for (PropertyModificationOperation mod : sideEffectChanges){ sideEffectDelta.add(mod.getPropertyDelta()); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 2666e8b6356..81cb4394dc2 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -23,6 +23,7 @@ import javax.xml.namespace.QName; +import org.aspectj.weaver.patterns.NamePattern; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -640,6 +641,46 @@ private void normalizeAttribute(ResourceAttribute attribute, RefinedAttri } } + public void normalizeDeltas(Collection>> deltas, + RefinedObjectClassDefinition objectClassDefinition) throws SchemaException { + // TODO Auto-generated method stub + for (ItemDelta> delta : deltas){ + if (!ShadowType.F_ATTRIBUTES.equals(ItemPath.getName(delta.getPath().first()))){ + continue; + } + RefinedAttributeDefinition rAttrDef = objectClassDefinition.findAttributeDefinition(delta.getElementName()); + if (rAttrDef == null){ + throw new SchemaException("Failed to normalize attribute: " + delta.getElementName()+ ". Definition for this attribute doesn't exist."); + } + normalizeDelta(delta, rAttrDef); + } + + + } + + private void normalizeDelta(ItemDelta> delta, RefinedAttributeDefinition rAttrDef) throws SchemaException{ + MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(rAttrDef.getMatchingRuleQName(), rAttrDef.getTypeName()); + if (matchingRule != null) { + if (delta.getValuesToReplace() != null){ + normalizeValues(delta.getValuesToReplace(), matchingRule); + } + if (delta.getValuesToAdd() != null){ + normalizeValues(delta.getValuesToAdd(), matchingRule); + } + + if (delta.getValuesToDelete() != null){ + normalizeValues(delta.getValuesToDelete(), matchingRule); + } + } + } + + private void normalizeValues(Collection> values, MatchingRule matchingRule){ + for (PrismPropertyValue pval: values) { + T normalizedRealValue = matchingRule.normalize(pval.getValue()); + pval.setValue(normalizedRealValue); + } + } + T getNormalizedAttributeValue(PrismPropertyValue pval, RefinedAttributeDefinition rAttrDef) throws SchemaException { MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(rAttrDef.getMatchingRuleQName(), rAttrDef.getTypeName()); if (matchingRule != null) { @@ -671,4 +712,6 @@ public boolean compareAttribute(RefinedObjectClassDefinition refinedObjectCl return MiscUtil.unorderedCollectionEquals(valuesA, Arrays.asList(valuesB)); } + + } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PropertyModificationOperation.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PropertyModificationOperation.java index 7192728f2cc..22716292d81 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PropertyModificationOperation.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PropertyModificationOperation.java @@ -30,7 +30,7 @@ public PropertyModificationOperation(PropertyDelta propertyDelta) { super(); this.propertyDelta = propertyDelta; } - + public PropertyDelta getPropertyDelta() { return propertyDelta; } @@ -47,5 +47,5 @@ public String debugDump(int indent) { sb.append(propertyDelta.debugDump(indent+1)); return sb.toString(); } - + } \ No newline at end of file diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java index ba5a463e04c..ac1f0a995b5 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java @@ -120,6 +120,10 @@ public static void normalizeShadow(T shadow, OperationRes } + public static PolyString determineShadowName(ShadowType shadow) throws SchemaException { + return determineShadowName(shadow.asPrismObject()); + } + public static PolyString determineShadowName(PrismObject shadow) throws SchemaException { String stringName = determineShadowStringName(shadow); if (stringName == null) {