diff --git a/open-metadata-implementation/access-services/asset-manager/asset-manager-server/src/main/java/org/odpi/openmetadata/accessservices/assetmanager/handlers/SchemaExchangeHandler.java b/open-metadata-implementation/access-services/asset-manager/asset-manager-server/src/main/java/org/odpi/openmetadata/accessservices/assetmanager/handlers/SchemaExchangeHandler.java index 28b3df20a90..7965d4b8a2b 100644 --- a/open-metadata-implementation/access-services/asset-manager/asset-manager-server/src/main/java/org/odpi/openmetadata/accessservices/assetmanager/handlers/SchemaExchangeHandler.java +++ b/open-metadata-implementation/access-services/asset-manager/asset-manager-server/src/main/java/org/odpi/openmetadata/accessservices/assetmanager/handlers/SchemaExchangeHandler.java @@ -19,6 +19,7 @@ import org.odpi.openmetadata.frameworks.connectors.ffdc.UserNotAuthorizedException; import org.odpi.openmetadata.frameworks.connectors.properties.beans.ElementHeader; import org.odpi.openmetadata.metadatasecurity.server.OpenMetadataServerSecurityVerifier; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.Classification; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.EntityDetail; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.InstanceProperties; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.Relationship; @@ -334,6 +335,7 @@ private SchemaTypeBuilder getSchemaTypeBuilder(SchemaTypeProperties schemaType, schemaType.getUsage(), schemaType.getEncodingStandard(), schemaType.getNamespace(), + schemaType.getFormula(), schemaType.getAdditionalProperties(), typeGUID, typeName, @@ -1527,7 +1529,8 @@ public void updateSchemaAttribute(String userId, invalidParameterHandler.validateGUID(schemaAttributeGUID, schemaAttributeGUIDParameterName, methodName); invalidParameterHandler.validateObject(schemaAttributeProperties, propertiesParameterName, methodName); invalidParameterHandler.validateName(schemaAttributeProperties.getQualifiedName(), qualifiedNameParameterName, methodName); - + SchemaTypeProperties schemaType = schemaAttributeProperties.getSchemaType(); + invalidParameterHandler.validateObject(schemaType,"displayName", methodName); this.validateExternalIdentifier(userId, schemaAttributeGUID, schemaAttributeGUIDParameterName, @@ -1547,11 +1550,13 @@ public void updateSchemaAttribute(String userId, getExternalSourceName(correlationProperties), schemaAttributeGUID, schemaAttributeGUIDParameterName, + schemaAttributeProperties.getQualifiedName(), + qualifiedNameParameterName, + schemaAttributeBuilder, + schemaAttributeProperties.getTypeName(), + isMergeUpdate, forLineage, forDuplicateProcessing, - supportedZones, - schemaAttributeBuilder.getInstanceProperties(methodName), - isMergeUpdate, effectiveTime, methodName); } diff --git a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeBuilder.java b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeBuilder.java index bb0cae83e0b..c53f58fddee 100644 --- a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeBuilder.java +++ b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeBuilder.java @@ -226,8 +226,8 @@ public SchemaTypeBuilder getSchemaTypeBuilder() * @param userId calling user * @param externalSourceGUID guid of the software capability entity that represented the external source - null for local * @param externalSourceName name of the software capability entity that represented the external source - * @param formula details of how this value is calculated - * @param methodName calling method + * @param formula details of how this value is calculated + * @param methodName calling method * @throws InvalidParameterException calculated value is not supported in the local repository, or any repository * connected by an open metadata repository cohort */ @@ -236,6 +236,26 @@ void setCalculatedValue(String userId, String externalSourceName, String formula, String methodName) throws InvalidParameterException + { + this.setCalculatedValue(userId, externalSourceGUID,externalSourceName, getCalculatedValueProperties(formula, methodName), methodName); + } + /** + * Set up the CalculatedValue classification for this entity. + * This method overrides any previously defined CalculatedValue classification for this entity. + * + * @param userId calling user + * @param externalSourceGUID guid of the software capability entity that represented the external source - null for local + * @param externalSourceName name of the software capability entity that represented the external source + * @param instanceProperties properties for the calculated vlaue classification + * @param methodName calling method + * @throws InvalidParameterException calculated value is not supported in the local repository, or any repository + * connected by an open metadata repository cohort + */ + void setCalculatedValue(String userId, + String externalSourceGUID, + String externalSourceName, + InstanceProperties instanceProperties, + String methodName) throws InvalidParameterException { try { @@ -247,15 +267,15 @@ void setCalculatedValue(String userId, } Classification classification = repositoryHelper.getNewClassification(serviceName, - externalSourceGUID, - externalSourceName, - instanceProvenanceType, - userId, - OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_NAME, - typeName, - ClassificationOrigin.ASSIGNED, - null, - getCalculatedValueProperties(formula, methodName)); + externalSourceGUID, + externalSourceName, + instanceProvenanceType, + userId, + OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_NAME, + typeName, + ClassificationOrigin.ASSIGNED, + null, + instanceProperties); newClassifications.put(classification.getName(), classification); } catch (TypeErrorException error) diff --git a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeHandler.java b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeHandler.java index 2e48c89bd83..0e7ed99558c 100644 --- a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeHandler.java +++ b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaAttributeHandler.java @@ -302,6 +302,23 @@ public String createNestedSchemaAttribute(String userId, { schemaAttributeBuilder.setAnchors(userId, anchorGUID, methodName); } + SchemaTypeBuilder schemaTypeBuilder = schemaAttributeBuilder.getSchemaTypeBuilder(); + + /* + * if there is a formula then set it into the schemaAttributeBuilder + */ + if (schemaTypeBuilder != null && schemaTypeBuilder.isDerived()) + { + String sourceName = "local"; + if (externalSourceName != null && externalSourceName.length() >0) + { + sourceName = externalSourceName; + } + InstanceProperties instanceProperties = schemaTypeBuilder.getCalculatedValueProperties(methodName); + String formula = repositoryHelper.getStringProperty(sourceName, OpenMetadataAPIMapper.FORMULA_PROPERTY_NAME, instanceProperties, methodName); + + schemaAttributeBuilder.setCalculatedValue(userId, externalSourceGUID, externalSourceName, formula, methodName); + } return this.createNestedSchemaAttribute(userId, externalSourceGUID, @@ -623,8 +640,8 @@ public String createNestedSchemaAttribute(String userId, invalidParameterHandler.validateName(qualifiedName, qualifiedNameParameterName, methodName); /* - * Now create the table itself along with its schema type. It also links the resulting table to the database schema type. - * The returned value is the guid of the table. + * Now create the nested schema attribute itself along with its schema type. + * The returned value is the guid of the nested attribute (e.g. table). */ String schemaAttributeGUID = this.createBeanInRepository(userId, externalSourceGUID, @@ -1865,6 +1882,173 @@ public void updateSchemaAttribute(String userId, } + /** + * Update the properties in a schema attribute. + * + * @param userId calling user + * @param externalSourceGUID unique identifier of software capability representing the caller + * @param externalSourceName unique name of software capability representing the caller + * @param schemaAttributeGUID unique identifier of the metadata element to connect the new schema attribute to + * @param schemaAttributeGUIDParameterName parameter name supplying schemaAttributeGUID + * @param qualifiedName unique identifier for this schema type + * @param qualifiedNameParameterName name of parameter supplying the qualified name + * @param schemaAttributeBuilder schema attribute builder + * @param typeName name of the type of this element - which defines the valid extended properties + * @param isMergeUpdate should the new properties be merged with existing properties (true) or completely replace them (false)? + * @param forLineage the request is to support lineage retrieval this means entities with the Memento classification can be returned + * @param forDuplicateProcessing the request is for duplicate processing and so must not deduplicate + * @param effectiveTime the time that the retrieved elements must be effective for (null for any time, new Date() for now) + * @param methodName calling method + * + * @throws InvalidParameterException one of the parameters is invalid + * @throws UserNotAuthorizedException the user is not authorized to issue this request + * @throws PropertyServerException there is a problem reported in the open metadata server(s) + */ + public void updateSchemaAttribute(String userId, + String externalSourceGUID, + String externalSourceName, + String schemaAttributeGUID, + String schemaAttributeGUIDParameterName, + String qualifiedName, + String qualifiedNameParameterName, + SchemaAttributeBuilder schemaAttributeBuilder, + String typeName, + boolean isMergeUpdate, + boolean forLineage, + boolean forDuplicateProcessing, + Date effectiveTime, + String methodName) throws InvalidParameterException, + UserNotAuthorizedException, + PropertyServerException + { + invalidParameterHandler.validateUserId(userId, methodName); + invalidParameterHandler.validateGUID(schemaAttributeGUID, schemaAttributeGUIDParameterName, methodName); + + if (! isMergeUpdate) + { + invalidParameterHandler.validateName(qualifiedName, qualifiedNameParameterName, methodName); + } + + /* + * Check that the type name requested is valid. + */ + String attributeTypeName = OpenMetadataAPIMapper.SCHEMA_ATTRIBUTE_TYPE_NAME; + + if (typeName != null) + { + attributeTypeName = typeName; + } + + EntityDetail schemaAttributeEntity = this.getEntityFromRepository(userId, + schemaAttributeGUID, + schemaAttributeGUIDParameterName, + attributeTypeName, + null, + null, + forLineage, + forDuplicateProcessing, + effectiveTime, + methodName); + + if (schemaAttributeEntity != null) + { + InstanceProperties instanceProperties = schemaAttributeBuilder.getInstanceProperties(methodName); + + this.updateBeanInRepository(userId, + externalSourceGUID, + externalSourceName, + schemaAttributeGUID, + schemaAttributeGUIDParameterName, + OpenMetadataAPIMapper.SCHEMA_ATTRIBUTE_TYPE_GUID, + OpenMetadataAPIMapper.SCHEMA_ATTRIBUTE_TYPE_NAME, + forLineage, + forDuplicateProcessing, + supportedZones, + instanceProperties, + true, + effectiveTime, + methodName); + + SchemaTypeBuilder schemaTypeBuilder = schemaAttributeBuilder.getSchemaTypeBuilder(); + if (schemaTypeBuilder != null) + { + + /* + * The formula is set if the schema attribute is derived. Need to test the merge semantics. + */ + InstanceProperties calculatedValueProperties = schemaTypeBuilder.getCalculatedValueProperties(methodName); + if (calculatedValueProperties == null) + { + /* + * if we have no formula requested and we are not a merge, any existing + * calculated value classification should be cleared + */ + if (!isMergeUpdate) + { + try { + String sourceName = "local"; + if (externalSourceName != null && externalSourceName.length() >0) + { + sourceName = externalSourceName; + } + + repositoryHelper.getClassificationFromEntity(sourceName, schemaAttributeEntity, OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_NAME, methodName); + removeClassificationFromRepository(userId, + externalSourceGUID, + externalSourceName, + schemaAttributeGUID, + schemaAttributeGUIDParameterName, + OpenMetadataAPIMapper.SCHEMA_ATTRIBUTE_TYPE_NAME, + OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_GUID, + OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_NAME, + forLineage, + forDuplicateProcessing, + effectiveTime, + methodName); + } catch (ClassificationErrorException e) + { + // there was no calculated value classification associated with the entity + } + } + } else + { + setClassificationInRepository(userId, + externalSourceGUID, + externalSourceName, + schemaAttributeEntity, + schemaAttributeGUIDParameterName, + attributeTypeName, + OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_GUID, + OpenMetadataAPIMapper.CALCULATED_VALUE_CLASSIFICATION_TYPE_NAME, + calculatedValueProperties, + isMergeUpdate, + forLineage, + forDuplicateProcessing, + supportedZones, + effectiveTime, + methodName); + + } + // todo this logic assumes the schema type is stored as a classification + setClassificationInRepository(userId, + externalSourceGUID,externalSourceName, + schemaAttributeEntity, + schemaAttributeGUIDParameterName, + attributeTypeName, + OpenMetadataAPIMapper.TYPE_EMBEDDED_ATTRIBUTE_CLASSIFICATION_TYPE_GUID, + OpenMetadataAPIMapper.TYPE_EMBEDDED_ATTRIBUTE_CLASSIFICATION_TYPE_NAME, + schemaTypeBuilder.getTypeEmbeddedInstanceProperties(methodName), + isMergeUpdate, + forLineage, + forDuplicateProcessing, + supportedZones, + effectiveTime, + methodName); + } + } + } + + /** * Update a schema attribute * diff --git a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaTypeBuilder.java b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaTypeBuilder.java index 0526ab6205d..6d6d184e27c 100644 --- a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaTypeBuilder.java +++ b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/SchemaTypeBuilder.java @@ -159,6 +159,63 @@ public SchemaTypeBuilder(String qualifiedName, this.encodingStandard = encodingStandard; this.namespace = namespace; } + /** + * Constructor supporting all common properties and formula. + * + * @param qualifiedName unique name of schema type itself + * @param displayName new value for the display name. + * @param description description of the schema type. + * @param versionNumber version of the schema type. + * @param isDeprecated is the schema type deprecated + * @param author name of the author + * @param usage guidance on how the schema should be used. + * @param encodingStandard format of the schema. + * @param namespace namespace where the schema is defined. + * @param formula formula for derived properties + * @param additionalProperties additional properties + * @param typeName unique name of schema sub type + * @param typeId unique identifier of the schema subtype + * @param extendedProperties properties from the subtype. + * @param repositoryHelper helper methods + * @param serviceName name of this OMAS + * @param serverName name of local server + */ + public SchemaTypeBuilder(String qualifiedName, + String displayName, + String description, + String versionNumber, + boolean isDeprecated, + String author, + String usage, + String encodingStandard, + String namespace, + String formula, + Map additionalProperties, + String typeId, + String typeName, + Map extendedProperties, + OMRSRepositoryHelper repositoryHelper, + String serviceName, + String serverName) + { + this(qualifiedName, + displayName, + description, + versionNumber, + isDeprecated, + author, + usage, + encodingStandard, + namespace, + additionalProperties, + typeId, + typeName, + extendedProperties, + repositoryHelper, + serviceName, + serverName); + setDerivedProperties(formula); + } /** @@ -358,6 +415,29 @@ public boolean isDerived() } + /** + * Return the schema type properties in an InstanceProperties object. + * + * @param methodName name of the calling method + * @return InstanceProperties object + */ + public InstanceProperties getCalculatedValueProperties(String methodName) + { + InstanceProperties properties = null; + + if (formula != null) + { + properties = repositoryHelper.addStringPropertyToInstance(serviceName, + null, + OpenMetadataAPIMapper.FORMULA_PROPERTY_NAME, + formula, + methodName); + } + + return properties; + } + + /** * Return the list of builders that each hold details of a schema Type to update. *