From 29dc9cd6bd1262c98a30ed341e5f9807d52a0a59 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 30 Jun 2014 12:58:32 +0200 Subject: [PATCH 1/4] Allowing multiple intents in an association definition (fixes MID-1960). --- .../RefinedAssociationDefinition.java | 11 +++--- .../RefinedObjectClassDefinition.java | 5 ++- .../refinery/RefinedResourceSchema.java | 34 +++++++++++++++++-- .../xml/ns/public/common/common-3.xsd | 9 ++++- .../impl/EntitlementConverter.java | 18 +++++----- .../provisioning/impl/ShadowCache.java | 3 +- 6 files changed, 58 insertions(+), 22 deletions(-) diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java index a77ea19b87c..8f0aceb6c31 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedAssociationDefinition.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import java.io.Serializable; +import java.util.Collection; public class RefinedAssociationDefinition implements Serializable { @@ -56,11 +57,11 @@ public ShadowKindType getKind() { return resourceObjectAssociationType.getKind(); } - public String getIntent() { - return resourceObjectAssociationType.getIntent(); - } - - public MappingType getOutboundMappingType() { + public Collection getIntents() { + return resourceObjectAssociationType.getIntent(); + } + + public MappingType getOutboundMappingType() { return resourceObjectAssociationType.getOutbound(); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index daaa6a31586..0089103bfe7 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -561,12 +561,11 @@ private static RefinedObjectClassDefinition parseRefinedObjectClass(ResourceObje return rOcDef; } - public void parseAssociations(RefinedResourceSchema rSchema) { + public void parseAssociations(RefinedResourceSchema rSchema) throws SchemaException { for (ResourceObjectAssociationType resourceObjectAssociationType: schemaHandlingObjectTypeDefinitionType.getAssociation()) { RefinedAssociationDefinition rAssocDef = new RefinedAssociationDefinition(resourceObjectAssociationType); ShadowKindType assocKind = rAssocDef.getKind(); - String assocIntent = rAssocDef.getIntent(); - RefinedObjectClassDefinition assocTarget = rSchema.getRefinedDefinition(assocKind, assocIntent); + RefinedObjectClassDefinition assocTarget = rSchema.getRefinedDefinition(assocKind, rAssocDef.getIntents()); rAssocDef.setAssociationTarget(assocTarget); associations.add(rAssocDef); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java index 99baa7d1069..b70b593a929 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedResourceSchema.java @@ -114,8 +114,38 @@ public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, St } return null; } - - public RefinedObjectClassDefinition getRefinedDefinition(QName objectClassName) { + + /** + * If no intents are provided, default account definition is returned. + * We check whether there is only one relevant rOCD. + */ + public RefinedObjectClassDefinition getRefinedDefinition(ShadowKindType kind, Collection intents) throws SchemaException { + RefinedObjectClassDefinition found = null; + for (RefinedObjectClassDefinition acctDef: getRefinedDefinitions(kind)) { + RefinedObjectClassDefinition foundCurrent = null; + if (intents == null || intents.isEmpty()) { + if (acctDef.isDefault()) { + foundCurrent = acctDef; + } + } else { + if (intents.contains(acctDef.getIntent())) { + foundCurrent = acctDef; + } + } + if (foundCurrent != null) { + if (found != null) { + if (!QNameUtil.match(found.getTypeName(), foundCurrent.getTypeName())) { + throw new SchemaException("More than one ObjectClass found for kind " + kind + ", intents: " + intents + ": " + found.getTypeName() + ", " + foundCurrent.getTypeName()); + } + } else { + found = foundCurrent; + } + } + } + return found; + } + + public RefinedObjectClassDefinition getRefinedDefinition(QName objectClassName) { for (Definition def: definitions) { if ((def instanceof RefinedObjectClassDefinition) && (QNameUtil.match(def.getTypeName(), objectClassName))) { diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd index 4f87da6512d..24c63066bab 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd @@ -3906,7 +3906,14 @@ - + + + + A set of intents corresponding to this association type. + NOTE: All of them must point to the same resource ObjectClass! + + + diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java index 483aabf8f1d..ed4f8b97266 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java @@ -104,9 +104,9 @@ public void postProcessEntitlementsRead(ConnectorInstance connector, ResourceTyp PrismContainer associationContainer = associationDef.instantiate(); for (RefinedAssociationDefinition assocDefType: entitlementAssociationDefs) { - RefinedObjectClassDefinition entitlementDef = refinedSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, assocDefType.getIntent()); + RefinedObjectClassDefinition entitlementDef = refinedSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, assocDefType.getIntents()); if (entitlementDef == null) { - throw new SchemaException("No definition for entitlement intent '"+assocDefType.getIntent()+"' in "+resourceType); + throw new SchemaException("No definition for entitlement intent(s) '"+assocDefType.getIntents()+"' in "+resourceType); } ResourceObjectAssociationDirectionType direction = assocDefType.getResourceObjectAssociationType().getDirection(); if (direction == ResourceObjectAssociationDirectionType.SUBJECT_TO_OBJECT) { @@ -361,9 +361,9 @@ public void collectEntitlementsAsObjectOperationDelete(ConnectorInstance con if (associationName == null) { throw new SchemaException("No name in entitlement association "+assocDefType+" in "+resourceType); } - final RefinedObjectClassDefinition entitlementOcDef = refinedSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, assocDefType.getIntent()); + final RefinedObjectClassDefinition entitlementOcDef = refinedSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, assocDefType.getIntents()); if (entitlementOcDef == null) { - throw new SchemaException("No definition for entitlement intent '"+assocDefType.getIntent()+"' defined in entitlement association "+associationName+" in "+resourceType); + throw new SchemaException("No definition for entitlement intent(s) '"+assocDefType.getIntents()+"' defined in entitlement association "+associationName+" in "+resourceType); } final QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute(); @@ -552,13 +552,13 @@ private void collectEntitlementAsObjectOperation(Map entitlementIntents = assocDefType.getIntents(); + if (entitlementIntents == null || entitlementIntents.isEmpty()) { throw new SchemaException("No entitlement intent specified in association "+associationCVal+" in "+resource); } - RefinedObjectClassDefinition entitlementOcDef = rSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, entitlementIntent); + RefinedObjectClassDefinition entitlementOcDef = rSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, entitlementIntents); if (entitlementOcDef == null) { - throw new SchemaException("No definition of entitlement intent '"+entitlementIntent+"' specified in association "+associationCVal+" in "+resource); + throw new SchemaException("No definition of entitlement intent(s) '"+entitlementIntents+"' specified in association "+associationCVal+" in "+resource); } QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute(); @@ -568,7 +568,7 @@ private void collectEntitlementAsObjectOperation(Map completeShadow(ConnectorInstance connector, Pris ShadowAssociationType shadowAssociationType = associationCVal.asContainerable(); QName associationName = shadowAssociationType.getName(); RefinedAssociationDefinition rEntitlementAssociation = objectClassDefinition.findEntitlementAssociation(associationName); - String entitlementIntent = rEntitlementAssociation.getIntent(); - RefinedObjectClassDefinition entitlementObjectClassDef = refinedSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, entitlementIntent); + RefinedObjectClassDefinition entitlementObjectClassDef = refinedSchema.getRefinedDefinition(ShadowKindType.ENTITLEMENT, rEntitlementAssociation.getIntents()); PrismObject entitlementShadow = (PrismObject) identifierContainer.getUserData(ResourceObjectConverter.FULL_SHADOW_KEY); if (entitlementShadow == null) { From c28d50b4f60d9c7683097710942a7dfb2e33afb6 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 30 Jun 2014 16:36:20 +0200 Subject: [PATCH 2/4] REST authorization URL constant --- .../evolveum/midpoint/security/api/AuthorizationConstants.java | 1 + 1 file changed, 1 insertion(+) diff --git a/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java b/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java index 9e78a00173d..88c9c5414eb 100644 --- a/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java +++ b/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java @@ -30,6 +30,7 @@ public class AuthorizationConstants { public static final String NS_AUTHORIZATION = NS_SECURITY_PREFIX + "authorization-3"; public static final String NS_AUTHORIZATION_UI = NS_SECURITY_PREFIX + "authorization-ui-3"; public static final String NS_AUTHORIZATION_WS = NS_SECURITY_PREFIX + "authorization-ws-3"; + public static final String NS_AUTHORIZATION_REST = NS_SECURITY_PREFIX + "authorization-rest-3"; public static final String NS_AUTHORIZATION_MODEL = NS_SECURITY_PREFIX + "authorization-model-3"; public static final QName AUTZ_ALL_QNAME = new QName(NS_AUTHORIZATION, "all"); From f6c04112942d9b2bcaa4c26a87fc063d35bad913 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 30 Jun 2014 21:44:25 +0200 Subject: [PATCH 3/4] Fixed "single-account import" for non-default intent/kind/OC shadows. --- ...ImportAccountsFromResourceTaskHandler.java | 20 ++++--- .../midpoint/model/impl/util/Utils.java | 53 +++++++++++-------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java index 0eba7a9cc9e..ec1cd86ccec 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java @@ -23,11 +23,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.impl.ModelConstants; import com.evolveum.midpoint.model.impl.sync.SynchronizeAccountResultHandler; -import com.evolveum.midpoint.model.impl.util.AbstractSearchIterativeResultHandler; import com.evolveum.midpoint.model.impl.util.AbstractSearchIterativeTaskHandler; import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.PrismObject; @@ -180,11 +178,12 @@ protected SynchronizeAccountResultHandler createHandler(TaskRunResult runResult, return null; } - return createHandler(resource, runResult, task, opResult); + return createHandler(resource, null, runResult, task, opResult); } - - private SynchronizeAccountResultHandler createHandler(ResourceType resource, TaskRunResult runResult, Task task, - OperationResult opResult) { + + // shadowToImport - it is used to derive objectClass/intent/kind when importing a single shadow + private SynchronizeAccountResultHandler createHandler(ResourceType resource, PrismObject shadowToImport, + TaskRunResult runResult, Task task, OperationResult opResult) { RefinedResourceSchema refinedSchema; try { @@ -200,7 +199,12 @@ private SynchronizeAccountResultHandler createHandler(ResourceType resource, Tas LOGGER.trace("Refined schema:\n{}", refinedSchema.debugDump()); } - ObjectClassComplexTypeDefinition objectClass = Utils.determineObjectClass(refinedSchema, task); + ObjectClassComplexTypeDefinition objectClass; + if (shadowToImport != null) { + objectClass = Utils.determineObjectClass(refinedSchema, shadowToImport); + } else { + objectClass = Utils.determineObjectClass(refinedSchema, task); + } if (objectClass == null) { LOGGER.error("Import: No objectclass specified and no default can be determined."); opResult.recordFatalError("No objectclass specified and no default can be determined"); @@ -260,7 +264,7 @@ public boolean importSingleShadow(String shadowOid, Task task, OperationResult p // Create a result handler just for one object. Invoke the handle() method manually. TaskRunResult runResult = new TaskRunResult(); - SynchronizeAccountResultHandler resultHandler = createHandler(resource.asObjectable(), runResult, task, parentResult); + SynchronizeAccountResultHandler resultHandler = createHandler(resource.asObjectable(), shadow, runResult, task, parentResult); if (resultHandler == null) { return false; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java index 84de67662e4..ca06280b947 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/Utils.java @@ -280,27 +280,38 @@ private static void resolveRef(PrismReferenceValue refVal, RepositoryService rep refVal.setOid(oid); result.recordSuccessIfUnknown(); } - - public static ObjectClassComplexTypeDefinition determineObjectClass(RefinedResourceSchema refinedSchema, Task task) { + + public static ObjectClassComplexTypeDefinition determineObjectClass(RefinedResourceSchema refinedSchema, Task task) { + + QName objectclass = null; + PrismProperty objectclassProperty = task.getExtensionProperty(ModelConstants.OBJECTCLASS_PROPERTY_NAME); + if (objectclassProperty != null) { + objectclass = objectclassProperty.getValue().getValue(); + } + + ShadowKindType kind = null; + PrismProperty kindProperty = task.getExtensionProperty(ModelConstants.KIND_PROPERTY_NAME); + if (kindProperty != null) { + kind = kindProperty.getValue().getValue(); + } + + String intent = null; + PrismProperty intentProperty = task.getExtensionProperty(ModelConstants.INTENT_PROPERTY_NAME); + if (intentProperty != null) { + intent = intentProperty.getValue().getValue(); + } + + return determineObjectClassInternal(refinedSchema, objectclass, kind, intent, task); + } + + public static ObjectClassComplexTypeDefinition determineObjectClass(RefinedResourceSchema refinedSchema, PrismObject shadowToImport) { + ShadowType s = shadowToImport.asObjectable(); + return determineObjectClassInternal(refinedSchema, s.getObjectClass(), s.getKind(), s.getIntent(), s); + } + + private static ObjectClassComplexTypeDefinition determineObjectClassInternal( + RefinedResourceSchema refinedSchema, QName objectclass, ShadowKindType kind, String intent, Object source) { - QName objectclass = null; - PrismProperty objectclassProperty = task.getExtensionProperty(ModelConstants.OBJECTCLASS_PROPERTY_NAME); - if (objectclassProperty != null) { - objectclass = objectclassProperty.getValue().getValue(); - } - - ShadowKindType kind = null; - PrismProperty kindProperty = task.getExtensionProperty(ModelConstants.KIND_PROPERTY_NAME); - if (kindProperty != null) { - kind = kindProperty.getValue().getValue(); - } - - String intent = null; - PrismProperty intentProperty = task.getExtensionProperty(ModelConstants.INTENT_PROPERTY_NAME); - if (intentProperty != null) { - intent = intentProperty.getValue().getValue(); - } - if (kind == null && intent == null && objectclass != null) { // Return generic object class definition from resource schema. No kind/intent means that we want // to process all kinds and intents in the object class. @@ -320,7 +331,7 @@ public static ObjectClassComplexTypeDefinition determineObjectClass(RefinedResou new Object[]{refinedObjectClassDefinition, objectclass}); } else { if (LOGGER.isTraceEnabled()) { - LOGGER.debug("No kind or objectclass specified in the task {}, using default values", task); + LOGGER.debug("No kind or objectclass specified in {}, using default values", source); } refinedObjectClassDefinition = refinedSchema.getRefinedDefinition(ShadowKindType.ACCOUNT, (String)null); LOGGER.trace("Determined refined object class {} by using default ACCOUNT kind", From 7c584cb5ad9b38cdba2c0883e694971575ac05ab Mon Sep 17 00:00:00 2001 From: Viliam Repan Date: Mon, 30 Jun 2014 23:10:02 +0200 Subject: [PATCH 4/4] fix for postgres dialect warnings in repository. --- .../midpoint/repo/sql/SqlRepositoryConfiguration.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryConfiguration.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryConfiguration.java index d3d01b7d10c..d7ea83083c9 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryConfiguration.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryConfiguration.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.repo.api.RepositoryServiceFactoryException; import com.evolveum.midpoint.repo.sql.util.MidPointConnectionCustomizer; import com.evolveum.midpoint.repo.sql.util.MidPointMySQLDialect; +import com.evolveum.midpoint.repo.sql.util.MidPointPostgreSQLDialect; import com.evolveum.midpoint.repo.sql.util.UnicodeSQLServer2008Dialect; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -488,7 +489,8 @@ public boolean isUsingMySQL() { public boolean isUsingPostgreSQL() { return isUsingDialect(PostgresPlusDialect.class) - || isUsingDialect(PostgreSQLDialect.class); + || isUsingDialect(PostgreSQLDialect.class) + || isUsingDialect(MidPointPostgreSQLDialect.class); } public boolean isUsingSQLServer() {