Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jul 29, 2014
2 parents 7e10e5c + 10608f8 commit 2c8b7f9
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 49 deletions.
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -130,7 +132,7 @@ public class ResourceObjectConverter {
@Autowired(required=true)
private PrismContext prismContext;

private PrismObjectDefinition<ShadowType> shadowTypeDefinition;
// private PrismObjectDefinition<ShadowType> shadowTypeDefinition;

private static final Trace LOGGER = TraceManager.getTrace(ResourceObjectConverter.class);

Expand Down Expand Up @@ -432,8 +434,17 @@ public Collection<PropertyModificationOperation> modifyResourceObject(
"Unable to modify account in the resource. Probably it has not been created yet because of previous unavailability of the resource.");
}

// PrismObject<ShadowType> 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);



}

/*
Expand All @@ -444,6 +455,11 @@ public Collection<PropertyModificationOperation> modifyResourceObject(
for (ItemDelta itemDelta : itemDeltas) {
itemDelta.applyTo(shadowAfter);
}

if (isRename(operations)){
Collection<PropertyModificationOperation> 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);
Expand All @@ -452,7 +468,7 @@ public Collection<PropertyModificationOperation> modifyResourceObject(
return sideEffectChanges;
}

private Collection<PropertyModificationOperation> executeModify(ConnectorInstance connector, ResourceType resource,
private Collection<PropertyModificationOperation> executeModify(ConnectorInstance connector, ResourceType resource, PrismObject<ShadowType> currentShadow,
RefinedObjectClassDefinition objectClassDefinition, Collection<? extends ResourceAttribute<?>> identifiers,
Collection<Operation> operations, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException {
Collection<PropertyModificationOperation> sideEffectChanges = null;
Expand All @@ -464,10 +480,14 @@ private Collection<PropertyModificationOperation> 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<ShadowType> currentShadow = fetchResourceObject(connector, resource, objectClassDefinition, identifiers, null, parentResult);
Collection<Operation> filteredOperations = new ArrayList(operations.size());
for (Operation origOperation: operations) {
if (origOperation instanceof PropertyModificationOperation) {
Expand Down Expand Up @@ -506,7 +526,8 @@ private Collection<PropertyModificationOperation> executeModify(ConnectorInstanc

sideEffectChanges = connector.modifyObject(objectClassDefinition, identifiers, operations,
parentResult);



LOGGER.debug("PROVISIONING MODIFY successful, side-effect changes {}",
SchemaDebugUtil.debugDump(sideEffectChanges));

Expand Down Expand Up @@ -540,6 +561,95 @@ private Collection<PropertyModificationOperation> executeModify(ConnectorInstanc
return sideEffectChanges;
}

private boolean isRename(Collection<Operation> 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<PropertyModificationOperation> distillRenameDeltas(Collection<Operation> modifications,
// PrismObject<ShadowType> 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<String> namePropertyDelta = nameDelta.getPropertyDelta();
//
// PrismProperty<String> name = namePropertyDelta.getPropertyNew();
// String newName = name.getRealValue();
//
// Collection<PropertyModificationOperation> deltas = new ArrayList<PropertyModificationOperation>();
//
// // $shadow/attributes/icfs:name
//// String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName()));
// PropertyDelta<String> cloneNameDelta = namePropertyDelta.clone();
// cloneNameDelta.clearValuesToReplace();
// cloneNameDelta.setValueToReplace(new PrismPropertyValue<String>(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<PropertyModificationOperation> distillRenameDeltas(Collection<? extends ItemDelta> modifications,
PrismObject<ShadowType> shadow, RefinedObjectClassDefinition objectClassDefinition) throws SchemaException {

PropertyDelta<String> nameDelta = (PropertyDelta<String>) ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class);
if (nameDelta == null){
return null;
}

PrismProperty<String> name = nameDelta.getPropertyNew();
String newName = name.getRealValue();

Collection<PropertyModificationOperation> deltas = new ArrayList<PropertyModificationOperation>();

// $shadow/attributes/icfs:name
// String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName()));
PropertyDelta<String> cloneNameDelta = nameDelta.clone();
cloneNameDelta.clearValuesToReplace();
cloneNameDelta.setValueToReplace(new PrismPropertyValue<String>(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<ShadowType> shadow, OperationProvisioningScriptsType scripts,
OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException {
Expand Down Expand Up @@ -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);

}
}
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -445,15 +446,16 @@ public String modifyShadow(PrismObject<ShadowType> shadow, ResourceType resource

afterModifyOnResource(shadow, modifications, parentResult);

Collection<PropertyDelta<?>> renameDeltas = distillRenameDeltas(modifications, shadow, objectClassDefinition, task, parentResult);
// Collection<PropertyDelta<?>> renameDeltas = distillRenameDeltas(modifications, shadow, objectClassDefinition, task, parentResult);

Collection<? extends ItemDelta> sideEffectDelta = convertToPropertyDelta(sideEffectChanges);
if (renameDeltas != null) {
((Collection) sideEffectDelta).addAll(renameDeltas);
}
Collection<PropertyDelta<PrismPropertyValue>> 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) {
Expand All @@ -471,40 +473,40 @@ public String modifyShadow(PrismObject<ShadowType> shadow, ResourceType resource
return oid;
}

private Collection<PropertyDelta<?>> distillRenameDeltas(Collection<? extends ItemDelta> modifications,
PrismObject<ShadowType> shadow, RefinedObjectClassDefinition objectClassDefinition, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
PropertyDelta<String> nameDelta = (PropertyDelta<String>) ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class);
if (nameDelta == null){
return null;
}

PrismProperty<String> name = nameDelta.getPropertyNew();
String newName = name.getRealValue();

Collection<PropertyDelta<?>> deltas = new ArrayList<PropertyDelta<?>>();

// $shadow/attributes/icfs:name
String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName()));
PropertyDelta<String> cloneNameDelta = nameDelta.clone();
cloneNameDelta.clearValuesToReplace();
cloneNameDelta.setValueToReplace(new PrismPropertyValue<String>(normalizedNewName));
deltas.add(cloneNameDelta);

// $shadow/name
if (!newName.equals(shadow.asObjectable().getName().getOrig())){

PrismObject<ShadowType> 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<PropertyDelta<?>> distillRenameDeltas(Collection<? extends ItemDelta> modifications,
// PrismObject<ShadowType> shadow, RefinedObjectClassDefinition objectClassDefinition, Task task, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
// PropertyDelta<String> nameDelta = (PropertyDelta<String>) ItemDelta.findItemDelta(modifications, new ItemPath(ShadowType.F_ATTRIBUTES, ConnectorFactoryIcfImpl.ICFS_NAME), ItemDelta.class);
// if (nameDelta == null){
// return null;
// }
//
// PrismProperty<String> name = nameDelta.getPropertyNew();
// String newName = name.getRealValue();
//
// Collection<PropertyDelta<?>> deltas = new ArrayList<PropertyDelta<?>>();
//
// // $shadow/attributes/icfs:name
// String normalizedNewName = shadowManager.getNormalizedAttributeValue(name.getValue(), objectClassDefinition.findAttributeDefinition(name.getElementName()));
// PropertyDelta<String> cloneNameDelta = nameDelta.clone();
// cloneNameDelta.clearValuesToReplace();
// cloneNameDelta.setValueToReplace(new PrismPropertyValue<String>(normalizedNewName));
// deltas.add(cloneNameDelta);
//
// // $shadow/name
// if (!newName.equals(shadow.asObjectable().getName().getOrig())){
//
// PrismObject<ShadowType> 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<? extends ItemDelta> convertToPropertyDelta(
private Collection<PropertyDelta<PrismPropertyValue>> convertToPropertyDelta(
Collection<PropertyModificationOperation> sideEffectChanges) {
Collection<PropertyDelta> sideEffectDelta = new ArrayList<PropertyDelta>();
Collection<PropertyDelta<PrismPropertyValue>> sideEffectDelta = new ArrayList<PropertyDelta<PrismPropertyValue>>();
if (sideEffectChanges != null) {
for (PropertyModificationOperation mod : sideEffectChanges){
sideEffectDelta.add(mod.getPropertyDelta());
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -640,6 +641,46 @@ private <T> void normalizeAttribute(ResourceAttribute<T> attribute, RefinedAttri
}
}

public <T> void normalizeDeltas(Collection<? extends ItemDelta<PrismPropertyValue<T>>> deltas,
RefinedObjectClassDefinition objectClassDefinition) throws SchemaException {
// TODO Auto-generated method stub
for (ItemDelta<PrismPropertyValue<T>> 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 <T> void normalizeDelta(ItemDelta<PrismPropertyValue<T>> delta, RefinedAttributeDefinition rAttrDef) throws SchemaException{
MatchingRule<T> 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 <T> void normalizeValues(Collection<PrismPropertyValue<T>> values, MatchingRule<T> matchingRule){
for (PrismPropertyValue<T> pval: values) {
T normalizedRealValue = matchingRule.normalize(pval.getValue());
pval.setValue(normalizedRealValue);
}
}

<T> T getNormalizedAttributeValue(PrismPropertyValue<T> pval, RefinedAttributeDefinition rAttrDef) throws SchemaException {
MatchingRule<T> matchingRule = matchingRuleRegistry.getMatchingRule(rAttrDef.getMatchingRuleQName(), rAttrDef.getTypeName());
if (matchingRule != null) {
Expand Down Expand Up @@ -671,4 +712,6 @@ public <T> boolean compareAttribute(RefinedObjectClassDefinition refinedObjectCl
return MiscUtil.unorderedCollectionEquals(valuesA, Arrays.asList(valuesB));
}



}
Expand Up @@ -30,7 +30,7 @@ public PropertyModificationOperation(PropertyDelta propertyDelta) {
super();
this.propertyDelta = propertyDelta;
}

public PropertyDelta getPropertyDelta() {
return propertyDelta;
}
Expand All @@ -47,5 +47,5 @@ public String debugDump(int indent) {
sb.append(propertyDelta.debugDump(indent+1));
return sb.toString();
}

}
Expand Up @@ -120,6 +120,10 @@ public static <T extends ShadowType> void normalizeShadow(T shadow, OperationRes

}

public static <T extends ShadowType> PolyString determineShadowName(ShadowType shadow) throws SchemaException {
return determineShadowName(shadow.asPrismObject());
}

public static <T extends ShadowType> PolyString determineShadowName(PrismObject<T> shadow) throws SchemaException {
String stringName = determineShadowStringName(shadow);
if (stringName == null) {
Expand Down

0 comments on commit 2c8b7f9

Please sign in to comment.