From b1c5ce24a7a14cbb938d7bbeba07f3325eb0abf3 Mon Sep 17 00:00:00 2001 From: Nigel Jones Date: Mon, 24 Sep 2018 08:02:58 +0100 Subject: [PATCH 1/4] #218 fix NPE for unclassified entity Signed-off-by: Nigel Jones --- .../OMRSRepositoryContentValidator.java | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/open-metadata-implementation/repository-services/repository-services-implementation/src/main/java/org/odpi/openmetadata/repositoryservices/localrepository/repositorycontentmanager/OMRSRepositoryContentValidator.java b/open-metadata-implementation/repository-services/repository-services-implementation/src/main/java/org/odpi/openmetadata/repositoryservices/localrepository/repositorycontentmanager/OMRSRepositoryContentValidator.java index 3aa042cbff9..48a9fb31b3e 100644 --- a/open-metadata-implementation/repository-services/repository-services-implementation/src/main/java/org/odpi/openmetadata/repositoryservices/localrepository/repositorycontentmanager/OMRSRepositoryContentValidator.java +++ b/open-metadata-implementation/repository-services/repository-services-implementation/src/main/java/org/odpi/openmetadata/repositoryservices/localrepository/repositorycontentmanager/OMRSRepositoryContentValidator.java @@ -2963,32 +2963,24 @@ public void validateRelationshipEnds(String sourceName, * @param entity entity to test. * @return boolean result */ - public boolean verifyEntityIsClassified(List requiredClassifications, - EntitySummary entity) - { - if (requiredClassifications != null) - { + public boolean verifyEntityIsClassified(List requiredClassifications, + EntitySummary entity) { + if (requiredClassifications != null) { List entityClassifications = entity.getClassifications(); - - for (String requiredClassification : requiredClassifications) - { - if (requiredClassification != null) - { - for (Classification entityClassification : entityClassifications) - { - if (entityClassification != null) - { - if (requiredClassification.equals(entityClassification.getName())) - { - return true; + if (entityClassifications != null) { + for (String requiredClassification : requiredClassifications) { + if (requiredClassification != null) { + for (Classification entityClassification : entityClassifications) { + if (entityClassification != null) { + if (requiredClassification.equals(entityClassification.getName())) { + return true; + } } } } } } - } - else - { + } else { return true; } From c351b0732818265d4cc9b0f26e2a73ef20167fd6 Mon Sep 17 00:00:00 2001 From: Nigel Jones Date: Tue, 25 Sep 2018 08:33:51 +0100 Subject: [PATCH 2/4] #216 further work on retrieving asset classifications Signed-off-by: Nigel Jones --- .../server/handlers/GovernedAssetHandler.java | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java index 5e0491a1c09..4008080b11b 100644 --- a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java +++ b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java @@ -11,6 +11,8 @@ import org.odpi.openmetadata.accessservices.governanceengine.api.objects.GovernedAsset; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.OMRSMetadataCollection; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.*; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.typedefs.TypeDef; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.typedefs.TypeDefCategory; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.repositoryconnector.OMRSRepositoryConnector; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.repositoryconnector.OMRSRepositoryHelper; import org.odpi.openmetadata.repositoryservices.ffdc.exception.*; @@ -118,15 +120,31 @@ public List getGovernedAssets(String userId, } private void addToAssetListByType(List assetsToReturn, String type, - Listclassification, String userId ) { + List classification, String userId) { - // We know the type, let's do this by classification now + // We know the type, let's do this by classification now if (classification == null) { - addToAssetListByClassification(assetsToReturn, type,null, userId); + List allClassifications = null; + //TypeDef classificationtypedef; + + try { + allClassifications = metadataCollection.findTypeDefsByCategory(userId, + TypeDefCategory.CLASSIFICATION_DEF); + } catch (org.odpi.openmetadata.repositoryservices.ffdc.exception.InvalidParameterException e) { + } catch (RepositoryErrorException e) { + } catch (org.odpi.openmetadata.repositoryservices.ffdc.exception.UserNotAuthorizedException e) { + } + + if (allClassifications != null) { + allClassifications.forEach((classificationTypedef) -> { + addToAssetListByClassification(assetsToReturn, type, classificationTypedef.getName(), userId); + }); + } + } else { classification.forEach((classificationsearch) -> { - addToAssetListByClassification(assetsToReturn, type,classificationsearch, userId); + addToAssetListByClassification(assetsToReturn, type, classificationsearch, userId); }); } @@ -141,14 +159,15 @@ private void addToAssetListByClassification(List assetsToReturn, String typeGuid = getTypeGuidFromTypeName(type,userId); - +// findEntitiesByClassification requires a specific type to be provided. try { + entities = metadataCollection.findEntitiesByClassification(userId, typeGuid, classification, - null, null, 0, + null, null,0, null, - null, null, null, 0); - + null, null, null, 0);//TODO Handle exceptions from findEntitiesByClassification + //TODO remove stack traces } catch (org.odpi.openmetadata.repositoryservices.ffdc.exception.InvalidParameterException e) { e.printStackTrace(); } catch (TypeErrorException e) { @@ -177,6 +196,7 @@ private void addToAssetListByClassification(List assetsToReturn, } } + private void addClassificationInfoToEntry(GovernedAsset entry, EntityDetail entity, String classification) { // Just add this classification info - the current methods are convoluted, but useful to prove out concept @@ -246,9 +266,9 @@ private GovernedAsset addEntityIfDoesntExist(List assetsToReturn, private String getTypeGuidFromTypeName(String type, String userId) { - String guid = new String(); + String guid = null; - // TODO Decided how to handle exceptions. For now we'll ensure an empty String is returned + // TODO Decided how to handle exceptions. For now we'll return null try { guid = metadataCollection.getTypeDefByName(userId, type).getGUID(); } catch (org.odpi.openmetadata.repositoryservices.ffdc.exception.InvalidParameterException e) { From 879cd243235fee654666775b752d472b02ace416 Mon Sep 17 00:00:00 2001 From: Nigel Jones Date: Tue, 25 Sep 2018 15:07:08 +0100 Subject: [PATCH 3/4] getAssets now correctly returns an asset & classification. #216 Signed-off-by: Nigel Jones --- .../server/handlers/GovernedAssetHandler.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java index 4008080b11b..8117f6bf36f 100644 --- a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java +++ b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java @@ -205,6 +205,8 @@ private void addClassificationInfoToEntry(GovernedAsset entry, EntityDetail enti // Get the current list of assigned classification List usageList = entry.getAssignedGovernanceClassifications(); + if (usageList == null) + usageList = new ArrayList(); // Add the new assignment locally (in case of copying) GovernanceClassificationUsage usage = new GovernanceClassificationUsage(); @@ -225,15 +227,19 @@ private void addClassificationInfoToEntry(GovernedAsset entry, EntityDetail enti // And now let's pull in the properties Map m = new HashMap<>(); - Map ip=entityClassification.getProperties().getInstanceProperties(); - - //mapping them to our map - ip.entrySet().stream().forEach(props -> { - // TODO Mapping of types between OMRS and Ranger should be abstracted - // TODO Mapping of alpha name is fragile - temporary for initial debug - m.put(props.getKey(),props.getValue().toString()); - }); + InstanceProperties ip2 = entityClassification.getProperties(); + if (ip2!=null) { + Map ip = ip2.getInstanceProperties(); + if (ip != null) { + //mapping them to our map + ip.entrySet().stream().forEach(props -> { + // TODO Mapping of types between OMRS and Ranger should be abstracted + // TODO Mapping of alpha name is fragile - temporary for initial debug + m.put(props.getKey(), props.getValue().toString()); + }); + } + } // And set them back usage.setAttributeValues(m); usageList.add(usage); From f64acacd47227834c7f38c911c03a63ae548d4c0 Mon Sep 17 00:00:00 2001 From: Nigel Jones Date: Wed, 26 Sep 2018 14:37:40 +0100 Subject: [PATCH 4/4] #246 Add type conversion for classification properties (primitives & enumerations) -> String Signed-off-by: Nigel Jones --- .../server/handlers/GovernedAssetHandler.java | 5 +- .../server/util/PropertyUtils.java | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/util/PropertyUtils.java diff --git a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java index 8117f6bf36f..846bea00aaf 100644 --- a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java +++ b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/handlers/GovernedAssetHandler.java @@ -9,6 +9,7 @@ import org.odpi.openmetadata.accessservices.governanceengine.api.ffdc.exceptions.*; import org.odpi.openmetadata.accessservices.governanceengine.api.objects.GovernanceClassificationUsage; import org.odpi.openmetadata.accessservices.governanceengine.api.objects.GovernedAsset; +import org.odpi.openmetadata.accessservices.governanceengine.server.util.PropertyUtils; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.OMRSMetadataCollection; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.*; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.typedefs.TypeDef; @@ -236,7 +237,9 @@ private void addClassificationInfoToEntry(GovernedAsset entry, EntityDetail enti ip.entrySet().stream().forEach(props -> { // TODO Mapping of types between OMRS and Ranger should be abstracted // TODO Mapping of alpha name is fragile - temporary for initial debug - m.put(props.getKey(), props.getValue().toString()); + //m.put(props.getKey(), props.getValue().toString()); + m.put(props.getKey(), PropertyUtils.getStringForPropertyValue(props.getValue())); + }); } } diff --git a/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/util/PropertyUtils.java b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/util/PropertyUtils.java new file mode 100644 index 00000000000..bba0cd9fdc0 --- /dev/null +++ b/open-metadata-implementation/access-services/governance-engine/governance-engine-server/src/main/java/org/odpi/openmetadata/accessservices/governanceengine/server/util/PropertyUtils.java @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +package org.odpi.openmetadata.accessservices.governanceengine.server.util; + + +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.EnumPropertyValue; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.InstancePropertyValue; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.PrimitivePropertyValue; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.typedefs.PrimitiveDefCategory; + +public class PropertyUtils { + + public static String getStringForPropertyValue(InstancePropertyValue ipv) { + + // First deal with primitive types + if (ipv instanceof PrimitivePropertyValue) { + PrimitiveDefCategory primtype = + ((PrimitivePropertyValue) ipv).getPrimitiveDefCategory(); + switch (primtype) { + // case may be unnecessary since all of these types we expect .toString() to work 'sensibly' but leaving + // for future decoding options + case OM_PRIMITIVE_TYPE_STRING: + return (String) ((PrimitivePropertyValue) ipv).getPrimitiveValue(); + case OM_PRIMITIVE_TYPE_INT: + case OM_PRIMITIVE_TYPE_BIGDECIMAL: + case OM_PRIMITIVE_TYPE_BIGINTEGER: + case OM_PRIMITIVE_TYPE_BOOLEAN: + case OM_PRIMITIVE_TYPE_BYTE: + case OM_PRIMITIVE_TYPE_CHAR: + case OM_PRIMITIVE_TYPE_DATE: + case OM_PRIMITIVE_TYPE_DOUBLE: + case OM_PRIMITIVE_TYPE_FLOAT: + case OM_PRIMITIVE_TYPE_LONG: + case OM_PRIMITIVE_TYPE_SHORT: + // For these primitive types we will just use tostring + return ((PrimitivePropertyValue)ipv).getPrimitiveValue().toString(); + case OM_PRIMITIVE_TYPE_UNKNOWN: + default: + // We don't know how to convert to string, so will ignore / leave as null + return ""; + } + + } else + { + if (ipv instanceof EnumPropertyValue) { + return ((EnumPropertyValue) ipv).getSymbolicName(); + } + else + { + // We WILL NOT decode ArrayPropertyValue, InstancePropertyValueMock, MapPropertyValue, + // StructPropertyValue + return ""; + } + } + + } + + +}