diff --git a/open-metadata-implementation/access-services/asset-consumer/asset-consumer-server/src/main/java/org/odpi/openmetadata/accessservices/assetconsumer/server/AssetConsumerRESTServices.java b/open-metadata-implementation/access-services/asset-consumer/asset-consumer-server/src/main/java/org/odpi/openmetadata/accessservices/assetconsumer/server/AssetConsumerRESTServices.java index 32ad779af3..a2206302fc 100644 --- a/open-metadata-implementation/access-services/asset-consumer/asset-consumer-server/src/main/java/org/odpi/openmetadata/accessservices/assetconsumer/server/AssetConsumerRESTServices.java +++ b/open-metadata-implementation/access-services/asset-consumer/asset-consumer-server/src/main/java/org/odpi/openmetadata/accessservices/assetconsumer/server/AssetConsumerRESTServices.java @@ -335,7 +335,7 @@ public AssetGraphResponse getAssetGraph(String serverName, /** - * constructing the mermaid graph for the retrieved asset. + * Constructing the mermaid graph for the retrieved asset. * * @param assetGraph retrieved asset graph * @return mermaid string @@ -450,7 +450,7 @@ private String removeSpaces(String currentQualifiedName) /** - * constructing the mermaid graph for the retrieved asset. + * Constructing the mermaid graph for the retrieved asset. * * @param assetLineageGraph retrieved asset graph * @return mermaid string @@ -559,6 +559,7 @@ private String getListLabel(List labelValues) return ""; } + /** * Return all the elements that are linked to an asset using lineage relationships. The relationships are * retrieved both from the asset, and the anchored schema elements diff --git a/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestopenmetadata/schema/HarvestOpenMetadataTable.java b/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestopenmetadata/schema/HarvestOpenMetadataTable.java index 76ee8a9a38..171d69a804 100644 --- a/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestopenmetadata/schema/HarvestOpenMetadataTable.java +++ b/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestopenmetadata/schema/HarvestOpenMetadataTable.java @@ -621,6 +621,7 @@ public String getTableDescription() * * @return list of columns */ + @Override public List getPrimaryKeys() { if (primaryKeys != null) @@ -702,6 +703,11 @@ public static List getTables() } + /** + * Standard toString method. + * + * @return JSON style description of variables. + */ @Override public String toString() { diff --git a/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/HarvestSurveysCatalogTargetProcessor.java b/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/HarvestSurveysCatalogTargetProcessor.java index e394734b5c..2994bd347a 100644 --- a/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/HarvestSurveysCatalogTargetProcessor.java +++ b/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/HarvestSurveysCatalogTargetProcessor.java @@ -500,7 +500,7 @@ private void processDataProfileLogAnnotations(String surve { Map measurementValues = new HashMap<>(); - for (int recordNumber = 0; recordNumber < csvFileStoreConnector.getRecordCount(); recordNumber ++) + for (long recordNumber = 0; recordNumber < csvFileStoreConnector.getRecordCount(); recordNumber ++) { List recordValues = csvFileStoreConnector.readRecord(recordNumber); @@ -964,7 +964,7 @@ private void processFileClassifiers(String surveyReportGUI if (connector instanceof CSVFileStoreConnector csvFileStoreConnector) { - for (int recordNumber = 0; recordNumber < csvFileStoreConnector.getRecordCount(); recordNumber ++) + for (long recordNumber = 0; recordNumber < csvFileStoreConnector.getRecordCount(); recordNumber ++) { List recordValues = csvFileStoreConnector.readRecord(recordNumber); diff --git a/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/schema/HarvestSurveysTable.java b/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/schema/HarvestSurveysTable.java index 715250fc55..d303f13e96 100644 --- a/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/schema/HarvestSurveysTable.java +++ b/open-metadata-implementation/adapters/open-connectors/nanny-connectors/src/main/java/org/odpi/openmetadata/adapters/connectors/nannyconnectors/harvestsurveys/schema/HarvestSurveysTable.java @@ -300,6 +300,7 @@ public String getTableDescription() * * @return list of columns */ + @Override public List getPrimaryKeys() { if (primaryKeys != null) @@ -381,6 +382,11 @@ public static List getTables() } + /** + * Standard toString method. + * + * @return JSON style description of variables. + */ @Override public String toString() { diff --git a/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/database/DatabaseStore.java b/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/database/DatabaseStore.java index 1d4f6411f5..1804d7e955 100644 --- a/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/database/DatabaseStore.java +++ b/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/database/DatabaseStore.java @@ -409,10 +409,13 @@ public List retrieveRelationships(QueryBuilder queryBuilder, { final String methodName = "retrieveRelationships"; + String sqQuery = queryBuilder.getPropertyJoinQuery(RepositoryTable.RELATIONSHIP.getTableName(), + RepositoryTable.RELATIONSHIP_ATTRIBUTE_VALUE.getTableName(), + "*") + + " where " + queryBuilder.getAsOfTimeWhereClause(); try { - List> relationshipRows = jdbcResourceConnector.getMatchingRows(RepositoryTable.RELATIONSHIP.getTableName(), - queryBuilder.getAsOfTimeWhereClause() + queryBuilder.getSequenceAndPaging(RepositoryTable.RELATIONSHIP.getTableName()), + List> relationshipRows = jdbcResourceConnector.getMatchingRows(sqQuery + queryBuilder.getSequenceAndPaging(RepositoryTable.RELATIONSHIP.getTableName()), RepositoryTable.RELATIONSHIP.getColumnNameTypeMap()); if (relationshipRows != null) diff --git a/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/schema/RepositoryTable.java b/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/schema/RepositoryTable.java index 300551efe7..1dbcfe28fc 100644 --- a/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/schema/RepositoryTable.java +++ b/open-metadata-implementation/adapters/open-connectors/repository-services-connectors/open-metadata-collection-store-connectors/postgres-repository-connector/src/main/java/org/odpi/openmetadata/adapters/repositoryservices/postgres/repositoryconnector/schema/RepositoryTable.java @@ -370,6 +370,11 @@ public static List getTables() } + /** + * Standard toString method. + * + * @return JSON style description of variables. + */ @Override public String toString() { diff --git a/open-metadata-implementation/admin-services/admin-services-api/src/main/java/org/odpi/openmetadata/adminservices/configuration/registration/ViewServiceRegistrationEntry.java b/open-metadata-implementation/admin-services/admin-services-api/src/main/java/org/odpi/openmetadata/adminservices/configuration/registration/ViewServiceRegistrationEntry.java index 66faff0cdc..b7e5ca0394 100644 --- a/open-metadata-implementation/admin-services/admin-services-api/src/main/java/org/odpi/openmetadata/adminservices/configuration/registration/ViewServiceRegistrationEntry.java +++ b/open-metadata-implementation/admin-services/admin-services-api/src/main/java/org/odpi/openmetadata/adminservices/configuration/registration/ViewServiceRegistrationEntry.java @@ -312,4 +312,27 @@ public void setViewServiceAdminClassName(String viewServiceAdminClassName) { this.viewServiceAdminClassName = viewServiceAdminClassName; } + + + /** + * Standard toString method. + * + * @return JSON style description of variables. + */ + @Override + public String toString() + { + return "ViewServiceRegistrationEntry{" + + "viewServiceCode=" + viewServiceCode + + ", viewServiceDevelopmentStatus=" + viewServiceDevelopmentStatus + + ", viewServiceName='" + viewServiceName + '\'' + + ", viewServiceFullName='" + viewServiceFullName + '\'' + + ", viewServiceURLMarker='" + viewServiceURLMarker + '\'' + + ", viewServiceDescription='" + viewServiceDescription + '\'' + + ", viewServiceWiki='" + viewServiceWiki + '\'' + + ", viewServicePartnerService='" + viewServicePartnerService + '\'' + + ", viewServiceOperationalStatus=" + viewServiceOperationalStatus + + ", viewServiceAdminClassName='" + viewServiceAdminClassName + '\'' + + '}'; + } } diff --git a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/OpenMetadataAPIGenericHandler.java b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/OpenMetadataAPIGenericHandler.java index 2436c28735..4ecb4597cb 100644 --- a/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/OpenMetadataAPIGenericHandler.java +++ b/open-metadata-implementation/common-services/generic-handlers/src/main/java/org/odpi/openmetadata/commonservices/generichandlers/OpenMetadataAPIGenericHandler.java @@ -9301,6 +9301,7 @@ public B getBeanFromRepository(String userId, forLineage, forDuplicateProcessing, serviceSupportedZones, + asOfTime, effectiveTime, methodName); diff --git a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-api/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/rest/OpenMetadataGraphResponse.java b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-api/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/rest/OpenMetadataGraphResponse.java new file mode 100644 index 0000000000..eddcb6c719 --- /dev/null +++ b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-api/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/rest/OpenMetadataGraphResponse.java @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright Contributors to the ODPi Egeria project. */ + +package org.odpi.openmetadata.frameworkservices.gaf.rest; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import org.odpi.openmetadata.commonservices.ffdc.rest.FFDCResponseBase; +import org.odpi.openmetadata.frameworks.governanceaction.properties.OpenMetadataElementGraph; +import org.odpi.openmetadata.frameworks.openmetadata.metadataelements.AssetGraph; + +import java.util.Objects; + +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY; + + +/** + * OpenMetadataGraphResponse is the response structure used on the Governance Action Framework REST API calls + * that returns an OpenMetadataElementGraph object as a response. + */ +@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown=true) +public class OpenMetadataGraphResponse extends FFDCResponseBase +{ + private OpenMetadataElementGraph elementGraph = null; + + /** + * Default constructor + */ + public OpenMetadataGraphResponse() + { + super(); + } + + + /** + * Copy/clone constructor + * + * @param template object to copy + */ + public OpenMetadataGraphResponse(OpenMetadataGraphResponse template) + { + super(template); + + if (template != null) + { + this.elementGraph = template.getElementGraph(); + } + } + + + /** + * Return the graph object. + * + * @return graph object + */ + public OpenMetadataElementGraph getElementGraph() + { + return elementGraph; + } + + + /** + * Set up the graph object. + * + * @param elementGraph - graph object + */ + public void setElementGraph(OpenMetadataElementGraph elementGraph) + { + this.elementGraph = elementGraph; + } + + + /** + * JSON-style toString + * + * @return return string containing the property names and values + */ + @Override + public String toString() + { + return "OpenMetadataGraphResponse{" + + "elementGraph=" + elementGraph + + "} " + super.toString(); + } + + + /** + * Return comparison result based on the content of the properties. + * + * @param objectToCompare test object + * @return result of comparison + */ + @Override + public boolean equals(Object objectToCompare) + { + if (this == objectToCompare) + { + return true; + } + if (!(objectToCompare instanceof OpenMetadataGraphResponse that)) + { + return false; + } + if (!super.equals(objectToCompare)) + { + return false; + } + return Objects.equals(getElementGraph(), that.getElementGraph()); + } + + + /** + * Return hash code for this object + * + * @return int hash code + */ + @Override + public int hashCode() + { + if (elementGraph == null) + { + return super.hashCode(); + } + else + { + return elementGraph.hashCode(); + } + } +} diff --git a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/OpenMetadataClientBase.java b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/OpenMetadataClientBase.java index e94adfcb85..f2746ff6da 100644 --- a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/OpenMetadataClientBase.java +++ b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/OpenMetadataClientBase.java @@ -973,6 +973,62 @@ public List getRelatedMetadataElements(String } + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param userId name of the server instances for this request + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param asOfTime Requests a historical query of the entity. Null means return the present values. + * @param effectiveTime only return the element if it is effective at this time. Null means anytime. Use "new Date()" for now. + * + * @return graph of elements + * + * @throws InvalidParameterException the unique identifier is null or not known; the relationship type is invalid + * @throws UserNotAuthorizedException the userId is not permitted to perform this operation + * @throws PropertyServerException there is a problem accessing the metadata store + */ + @Override + public OpenMetadataElementGraph getAnchoredElementsGraph(String userId, + String elementGUID, + boolean forLineage, + boolean forDuplicateProcessing, + int startFrom, + int pageSize, + Date asOfTime, + Date effectiveTime) throws InvalidParameterException, + UserNotAuthorizedException, + PropertyServerException + { + final String methodName = "getAnchoredElementsGraph"; + final String guidParameterName = "elementGUID"; + final String urlTemplate = serverPlatformURLRoot + "/servers/{0}/open-metadata/framework-services/{1}/open-metadata-store/users/{2}/metadata-elements/{3}/with-anchored-elements?forLineage={4}&forDuplicateProcessing={5}&startFrom={6}&pageSize={7}"; + + invalidParameterHandler.validateUserId(userId, methodName); + invalidParameterHandler.validateGUID(elementGUID, guidParameterName, methodName); + + AnyTimeRequestBody requestBody = new AnyTimeRequestBody(); + requestBody.setAsOfTime(asOfTime); + requestBody.setEffectiveTime(effectiveTime); + OpenMetadataGraphResponse restResult = restClient.callOpenMetadataGraphPostRESTCall(methodName, + urlTemplate, + requestBody, + serverName, + serviceURLMarker, + userId, + elementGUID, + forLineage, + forDuplicateProcessing, + startFrom, + pageSize); + + return restResult.getElementGraph(); + } + + /** * Retrieve the metadata element connected to the supplied element for a relationship type that only allows one * relationship to be attached. diff --git a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/rest/GAFRESTClient.java b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/rest/GAFRESTClient.java index 17f017904f..f1134ca8d8 100644 --- a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/rest/GAFRESTClient.java +++ b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-client/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/client/rest/GAFRESTClient.java @@ -354,6 +354,39 @@ public OpenMetadataElementResponse callOpenMetadataElementPostRESTCall(String } + + /** + * Issue a POST REST call that returns a OpenMetadataGraphResponse object. + * + * @param methodName name of the method being called. + * @param urlTemplate template of the URL for the REST API call, with place-holders for the parameters. + * @param requestBody object that passes additional parameters + * @param params a list of parameters that are slotted into the url template. + * + * @return response object + * @throws InvalidParameterException one of the parameters is invalid. + * @throws UserNotAuthorizedException the user is not authorized to make this request. + * @throws PropertyServerException the repository is not available or not working properly. + */ + public OpenMetadataGraphResponse callOpenMetadataGraphPostRESTCall(String methodName, + String urlTemplate, + Object requestBody, + Object... params) throws InvalidParameterException, + UserNotAuthorizedException, + PropertyServerException + { + OpenMetadataGraphResponse restResult = this.callPostRESTCall(methodName, + OpenMetadataGraphResponse.class, + urlTemplate, + requestBody, + params); + + exceptionHandler.detectAndThrowStandardExceptions(methodName, restResult); + + return restResult; + } + + /** * Issue a GET REST call that returns a OpenMetadataElementResponse object. * diff --git a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-server/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/OpenMetadataStoreRESTServices.java b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-server/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/OpenMetadataStoreRESTServices.java index 31b90b0de8..45d0d6b84a 100644 --- a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-server/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/OpenMetadataStoreRESTServices.java +++ b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-server/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/OpenMetadataStoreRESTServices.java @@ -13,6 +13,8 @@ import org.odpi.openmetadata.frameworks.connectors.ffdc.InvalidParameterException; import org.odpi.openmetadata.frameworks.connectors.ffdc.PropertyServerException; import org.odpi.openmetadata.frameworks.connectors.ffdc.UserNotAuthorizedException; +import org.odpi.openmetadata.frameworks.governanceaction.search.ElementProperties; +import org.odpi.openmetadata.frameworks.governanceaction.search.PropertyHelper; import org.odpi.openmetadata.frameworks.openmetadata.enums.ElementStatus; import org.odpi.openmetadata.frameworks.openmetadata.types.OpenMetadataProperty; import org.odpi.openmetadata.frameworks.openmetadata.types.OpenMetadataType; @@ -26,17 +28,18 @@ import org.odpi.openmetadata.frameworkservices.gaf.rest.TemplateRequestBody; import org.odpi.openmetadata.frameworkservices.gaf.rest.UpdateRequestBody; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.HistorySequencingOrder; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.MatchCriteria; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.SequencingOrder; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.EntityDetail; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.InstanceStatus; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.PrimitivePropertyValue; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.Relationship; +import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.search.*; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.typedefs.*; import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.repositoryconnector.OMRSRepositoryHelper; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; import static org.odpi.openmetadata.frameworks.openmetadata.mapper.OpenMetadataValidValues.constructValidValueCategory; import static org.odpi.openmetadata.frameworks.openmetadata.mapper.OpenMetadataValidValues.constructValidValueQualifiedName; @@ -55,6 +58,8 @@ public class OpenMetadataStoreRESTServices private final static RESTCallLogger restCallLogger = new RESTCallLogger(LoggerFactory.getLogger(OpenMetadataStoreRESTServices.class), instanceHandler.getServiceName()); + private final PropertyHelper propertyHelper = new PropertyHelper(); + private final InvalidParameterHandler invalidParameterHandler = new InvalidParameterHandler(); private final String propertyNameParameter = "propertyName"; private final String preferredValueParameter = "preferredValue"; @@ -1425,6 +1430,398 @@ public OpenMetadataElementsResponse findMetadataElements(String serverN } + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param serverName name of the server instances for this request + * @param serviceURLMarker the identifier of the access service (for example asset-owner for the Asset Owner OMAS) + * @param userId the userId of the requesting user + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param requestBody effective time and asOfTime + * + * @return graph of elements or + * InvalidParameterException - one of the parameters is null or invalid or + * PropertyServerException - there is a problem retrieving the connected asset properties from the property server or + * UserNotAuthorizedException - the requesting user is not authorized to issue this request. + */ + public OpenMetadataGraphResponse getAnchoredElementsGraph(String serverName, + String serviceURLMarker, + String userId, + String elementGUID, + boolean forLineage, + boolean forDuplicateProcessing, + int startFrom, + int pageSize, + AnyTimeRequestBody requestBody) + { + final String parameterName = "elementGUID"; + final String methodName = "getAnchoredElementsGraph"; + + RESTCallToken token = restCallLogger.logRESTCall(serverName, userId, methodName); + + OpenMetadataGraphResponse response = new OpenMetadataGraphResponse(); + AuditLog auditLog = null; + + try + { + MetadataElementHandler handler = instanceHandler.getMetadataElementHandler(userId, serverName, methodName); + + auditLog = instanceHandler.getAuditLog(userId, serverName, methodName); + + OpenMetadataElement anchorElement = handler.getBeanFromRepository(userId, + elementGUID, + parameterName, + OpenMetadataType.OPEN_METADATA_ROOT.typeName, + false, + false, + null, + null, + null, + methodName); + + if (anchorElement != null) + { + OpenMetadataElementGraph elementGraph = new OpenMetadataElementGraph(anchorElement); + + Map receivedRelationships = new HashMap<>(); + + List relationships = handler.getAllAttachmentLinks(userId, + anchorElement.getElementGUID(), + parameterName, + anchorElement.getType().getTypeName(), + null, + null, + SequencingOrder.CREATION_DATE_RECENT, + null, + false, + false, + new Date(), + methodName); + if (relationships != null) + { + for (Relationship relationship : relationships) + { + if (relationship != null) + { + receivedRelationships.put(relationship.getGUID(), relationship); + } + } + } + + SearchClassifications searchClassifications = new SearchClassifications(); + List classificationConditions = new ArrayList<>(); + ClassificationCondition classificationCondition = new ClassificationCondition(); + SearchProperties searchProperties = new SearchProperties(); + List propertyConditions = new ArrayList<>(); + PropertyCondition propertyCondition = new PropertyCondition(); + PrimitivePropertyValue primitivePropertyValue = new PrimitivePropertyValue(); + + primitivePropertyValue.setPrimitiveDefCategory(PrimitiveDefCategory.OM_PRIMITIVE_TYPE_STRING); + primitivePropertyValue.setPrimitiveValue(anchorElement.getElementGUID()); + primitivePropertyValue.setTypeName(PrimitiveDefCategory.OM_PRIMITIVE_TYPE_STRING.getName()); + primitivePropertyValue.setTypeGUID(PrimitiveDefCategory.OM_PRIMITIVE_TYPE_STRING.getGUID()); + + propertyCondition.setProperty(OpenMetadataProperty.ANCHOR_GUID.name); + propertyCondition.setOperator(PropertyComparisonOperator.EQ); + propertyCondition.setValue(primitivePropertyValue); + propertyConditions.add(propertyCondition); + searchProperties.setMatchCriteria(MatchCriteria.ALL); + searchProperties.setConditions(propertyConditions); + + classificationCondition.setName(OpenMetadataType.ANCHORS_CLASSIFICATION.typeName); + classificationCondition.setMatchProperties(searchProperties); + classificationConditions.add(classificationCondition); + searchClassifications.setMatchCriteria(MatchCriteria.ALL); + searchClassifications.setConditions(classificationConditions); + + List anchoredElements = handler.findBeans(userId, + null, + null, + null, + null, + searchClassifications, + null, + null, + SequencingOrder.CREATION_DATE_RECENT, + false, + false, + startFrom, + pageSize, + instanceHandler.getSupportedZones(userId, serverName, serviceURLMarker, methodName), + new Date(), + methodName); + + elementGraph.setAnchoredElements(anchoredElements); + + if (anchoredElements != null) + { + final String anchoredElementParameterName = "anchoredElement.getGUID"; + + for (OpenMetadataElement metadataElement : anchoredElements) + { + if (metadataElement != null) + { + relationships = handler.getAllAttachmentLinks(userId, + metadataElement.getElementGUID(), + anchoredElementParameterName, + metadataElement.getType().getTypeName(), + null, + null, + SequencingOrder.CREATION_DATE_RECENT, + null, + false, + false, + new Date(), + methodName); + if (relationships != null) + { + for (Relationship relationship : relationships) + { + if (relationship != null) + { + receivedRelationships.put(relationship.getGUID(), relationship); + } + } + } + } + } + } + + if (! receivedRelationships.isEmpty()) + { + RelatedElementsConverter converter = new RelatedElementsConverter<>(handler.getRepositoryHelper(), + handler.getServiceName(), + serverName); + + List metadataRelationships = new ArrayList<>(); + + for (Relationship relationship: receivedRelationships.values()) + { + if (relationship != null) + { + OpenMetadataRelationship metadataRelationship = converter.getNewRelationshipBean(OpenMetadataRelationship.class, + relationship, + methodName); + + metadataRelationships.add(metadataRelationship); + } + } + + elementGraph.setRelationships(metadataRelationships); + } + + elementGraph.setMermaidGraph(this.getElementGraphMermaidGraph(elementGraph)); + response.setElementGraph(elementGraph); + } + } + catch (Exception error) + { + restExceptionHandler.captureExceptions(response, error, methodName, auditLog); + } + + restCallLogger.logRESTCallReturn(token, response.toString()); + return response; + } + + + /** + * Constructing the mermaid graph for the retrieved element. + * + * @param elementGraph retrieved graph + * @return mermaid string + */ + private String getElementGraphMermaidGraph(OpenMetadataElementGraph elementGraph) + { + final String methodName = "getElementGraphMermaidGraph"; + + StringBuilder mermaidGraph = new StringBuilder(); + + mermaidGraph.append("---\n"); + mermaidGraph.append("title: Asset - "); + mermaidGraph.append(this.getDisplayName(elementGraph.getElementProperties(), elementGraph.getType().getTypeName())); + mermaidGraph.append(" ["); + mermaidGraph.append(elementGraph.getElementGUID()); + mermaidGraph.append("]\n---\nflowchart LR\n%%{init: {\"flowchart\": {\"htmlLabels\": false}} }%%\n\n"); + + List usedQualifiedNames = new ArrayList<>(); + + String currentQualifiedName = propertyHelper.getStringProperty(instanceHandler.getServiceName(), + OpenMetadataProperty.QUALIFIED_NAME.name, + elementGraph.getElementProperties(), + methodName); + String currentDisplayName = this.getDisplayName(elementGraph.getElementProperties(), elementGraph.getType().getTypeName()); + + appendMermaidNode(mermaidGraph, + currentQualifiedName, + currentDisplayName, + elementGraph.getType().getTypeName()); + + usedQualifiedNames.add(currentQualifiedName); + + if (elementGraph.getAnchoredElements() != null) + { + for (OpenMetadataElement node : elementGraph.getAnchoredElements()) + { + if (node != null) + { + currentQualifiedName = propertyHelper.getStringProperty(instanceHandler.getServiceName(), + OpenMetadataProperty.QUALIFIED_NAME.name, + node.getElementProperties(), + methodName);; + currentDisplayName = this.getDisplayName(node.getElementProperties(), node.getType().getTypeName()); + + + if (!usedQualifiedNames.contains(currentQualifiedName)) + { + appendMermaidNode(mermaidGraph, + currentQualifiedName, + currentDisplayName, + node.getType().getTypeName()); + + usedQualifiedNames.add(currentQualifiedName); + } + } + } + + for (OpenMetadataRelationship line : elementGraph.getRelationships()) + { + if (line != null) + { + mermaidGraph.append(this.removeSpaces(line.getElementAtEnd1().getUniqueName())); + mermaidGraph.append("-->|"); + mermaidGraph.append(line.getType().getTypeName()); + mermaidGraph.append("|"); + mermaidGraph.append(this.removeSpaces(line.getElementAtEnd2().getUniqueName())); + mermaidGraph.append("\n"); + } + } + } + + return mermaidGraph.toString(); + } + + + /** + * Extract a display name from a variety of properties. + * + * @param elementProperties properties from the element + * @param typeName type name as a last resource + * @return display name to use + */ + private String getDisplayName(ElementProperties elementProperties, + String typeName) + { + final String methodName = "getDisplayName"; + + String currentDisplayName = propertyHelper.getStringProperty(instanceHandler.getServiceName(), + OpenMetadataProperty.NAME.name, + elementProperties, + methodName); + if (currentDisplayName == null) + { + currentDisplayName = propertyHelper.getStringProperty(instanceHandler.getServiceName(), + OpenMetadataProperty.DISPLAY_NAME.name, + elementProperties, + methodName); + } + + if (currentDisplayName == null) + { + currentDisplayName = propertyHelper.getStringProperty(instanceHandler.getServiceName(), + OpenMetadataProperty.RESOURCE_NAME.name, + elementProperties, + methodName); + } + + if (currentDisplayName == null) + { + currentDisplayName = propertyHelper.getStringProperty(instanceHandler.getServiceName(), + OpenMetadataProperty.QUALIFIED_NAME.name, + elementProperties, + methodName); + } + + if (currentDisplayName == null) + { + currentDisplayName = typeName; + } + + return currentDisplayName; + } + + + /** + * Create a node in the mermaid graph. + * + * @param mermaidGraph current state of the graph + * @param currentNodeName unique name/identifier + * @param currentDisplayName display name + * @param currentType type of element + */ + private void appendMermaidNode(StringBuilder mermaidGraph, + String currentNodeName, + String currentDisplayName, + String currentType) + { + mermaidGraph.append(this.removeSpaces(currentNodeName)); + mermaidGraph.append("(\"`*"); + mermaidGraph.append(currentType); + mermaidGraph.append("*\n**"); + mermaidGraph.append(currentDisplayName); + mermaidGraph.append("**`\")\n"); + } + + + /** + * Remove all the spaces from the qualifiedName along with the curly braces - found in the templates. + * + * @param currentQualifiedName qualifiedName + * @return qualified name without spaces + */ + private String removeSpaces(String currentQualifiedName) + { + String noSpaces = currentQualifiedName.replaceAll("\\s+",""); + return noSpaces.replaceAll("[\\[\\](){}]", ""); + } + + + + /** + * Convert an array into a comma separated string. + * + * @param labelValues array of labels + * @return string value without square brackets (Mermaid does not allow them) + */ + private String getListLabel(List labelValues) + { + if (labelValues != null) + { + StringBuilder stringBuilder = new StringBuilder(); + boolean firstValue = true; + + for (String labelValue : labelValues) + { + if (! firstValue) + { + stringBuilder.append(","); + } + + firstValue = false; + stringBuilder.append(labelValue); + } + + return stringBuilder.toString(); + } + + return ""; + } + + + /** * Return a list of relationships that match the requested conditions. The results can be received as a series of pages. * diff --git a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-spring/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/spring/OpenMetadataStoreResource.java b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-spring/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/spring/OpenMetadataStoreResource.java index 5132894c8a..72666801a1 100644 --- a/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-spring/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/spring/OpenMetadataStoreResource.java +++ b/open-metadata-implementation/framework-services/gaf-metadata-management/gaf-metadata-spring/src/main/java/org/odpi/openmetadata/frameworkservices/gaf/server/spring/OpenMetadataStoreResource.java @@ -1077,6 +1077,45 @@ public OpenMetadataElementsResponse findMetadataElements(@PathVariable String } + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param serverName name of the server instances for this request + * @param serviceURLMarker the identifier of the access service (for example asset-owner for the Asset Owner OMAS) + * @param userId the userId of the requesting user + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param requestBody effective time and asOfTime + * + * @return graph of elements or + * InvalidParameterException - one of the parameters is null or invalid or + * PropertyServerException - there is a problem retrieving the connected asset properties from the property server or + * UserNotAuthorizedException - the requesting user is not authorized to issue this request. + */ + @PostMapping(path = "/metadata-elements/{elementGUID}/with-anchored-elements") + + public OpenMetadataGraphResponse getAnchoredElementsGraph(@PathVariable String serverName, + @PathVariable String serviceURLMarker, + @PathVariable String userId, + @PathVariable String elementGUID, + @RequestParam(required = false, defaultValue = "false") + boolean forLineage, + @RequestParam(required = false, defaultValue = "false") + boolean forDuplicateProcessing, + @RequestParam(required = false, defaultValue = "0") + int startFrom, + @RequestParam(required = false, defaultValue = "0") + int pageSize, + @RequestBody (required = false) + AnyTimeRequestBody requestBody) + { + return restAPI.getAnchoredElementsGraph(serverName, serviceURLMarker, userId, elementGUID, forLineage, forDuplicateProcessing, startFrom, pageSize, requestBody); + } + + /** * Return a list of relationships that match the requested conditions. The results can be received as a series of pages. * diff --git a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/OpenMetadataStore.java b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/OpenMetadataStore.java index 5cd4b61319..353c37ed68 100644 --- a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/OpenMetadataStore.java +++ b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/OpenMetadataStore.java @@ -577,6 +577,29 @@ public List getRelatedMetadataElements(String elementGU } + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param elementGUID unique identifier for the element + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * + * @return graph of elements + * + * @throws InvalidParameterException the unique identifier is null or not known; the relationship type is invalid + * @throws UserNotAuthorizedException the userId is not permitted to perform this operation + * @throws PropertyServerException there is a problem accessing the metadata store + */ + public OpenMetadataElementGraph getAnchoredElementsGraph(String elementGUID, + int startFrom, + int pageSize) throws InvalidParameterException, + UserNotAuthorizedException, + PropertyServerException + { + return openMetadataClient.getAnchoredElementsGraph(userId, elementGUID, forLineage, forDuplicateProcessing, startFrom, pageSize, null, getEffectiveTime()); + } + + /** * Retrieve the metadata element connected to the supplied element for a relationship type that only allows one * relationship to be attached. diff --git a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/MetadataElementInterface.java b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/MetadataElementInterface.java index b5f0284917..ea11b6906b 100644 --- a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/MetadataElementInterface.java +++ b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/MetadataElementInterface.java @@ -5,6 +5,7 @@ import org.odpi.openmetadata.frameworks.connectors.ffdc.InvalidParameterException; import org.odpi.openmetadata.frameworks.connectors.ffdc.PropertyServerException; import org.odpi.openmetadata.frameworks.connectors.ffdc.UserNotAuthorizedException; +import org.odpi.openmetadata.frameworks.governanceaction.properties.OpenMetadataElementGraph; import org.odpi.openmetadata.frameworks.openmetadata.enums.ElementStatus; import org.odpi.openmetadata.frameworks.governanceaction.properties.OpenMetadataElement; import org.odpi.openmetadata.frameworks.governanceaction.properties.RelatedMetadataElement; @@ -241,6 +242,36 @@ List getRelatedMetadataElements(String user PropertyServerException; + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param userId name of the server instances for this request + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param asOfTime Requests a historical query of the entity. Null means return the present values. + * @param effectiveTime only return the element if it is effective at this time. Null means anytime. Use "new Date()" for now. + * + * @return graph of elements + * + * @throws InvalidParameterException the unique identifier is null or not known; the relationship type is invalid + * @throws UserNotAuthorizedException the userId is not permitted to perform this operation + * @throws PropertyServerException there is a problem accessing the metadata store + */ + OpenMetadataElementGraph getAnchoredElementsGraph(String userId, + String elementGUID, + boolean forLineage, + boolean forDuplicateProcessing, + int startFrom, + int pageSize, + Date asOfTime, + Date effectiveTime) throws InvalidParameterException, + UserNotAuthorizedException, + PropertyServerException; + + /** * Retrieve the metadata element connected to the supplied element for a relationship type that only allows one * relationship to be attached. diff --git a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/OpenMetadataClient.java b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/OpenMetadataClient.java index 880fe3b487..5181c19f00 100644 --- a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/OpenMetadataClient.java +++ b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/client/OpenMetadataClient.java @@ -474,6 +474,37 @@ public abstract List getRelatedMetadataElements(String PropertyServerException; + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param userId name of the server instances for this request + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param asOfTime Requests a historical query of the entity. Null means return the present values. + * @param effectiveTime only return the element if it is effective at this time. Null means anytime. Use "new Date()" for now. + * + * @return graph of elements + * + * @throws InvalidParameterException the unique identifier is null or not known; the relationship type is invalid + * @throws UserNotAuthorizedException the userId is not permitted to perform this operation + * @throws PropertyServerException there is a problem accessing the metadata store + */ + @Override + public abstract OpenMetadataElementGraph getAnchoredElementsGraph(String userId, + String elementGUID, + boolean forLineage, + boolean forDuplicateProcessing, + int startFrom, + int pageSize, + Date asOfTime, + Date effectiveTime) throws InvalidParameterException, + UserNotAuthorizedException, + PropertyServerException; + + /** * Retrieve the metadata element connected to the supplied element for a relationship type that only allows one * relationship to be attached. diff --git a/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/properties/OpenMetadataElementGraph.java b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/properties/OpenMetadataElementGraph.java new file mode 100644 index 0000000000..709e02f3a4 --- /dev/null +++ b/open-metadata-implementation/frameworks/governance-action-framework/src/main/java/org/odpi/openmetadata/frameworks/governanceaction/properties/OpenMetadataElementGraph.java @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright Contributors to the ODPi Egeria project. */ + +package org.odpi.openmetadata.frameworks.governanceaction.properties; + + +import org.odpi.openmetadata.frameworks.openmetadata.metadataelements.AssetElement; +import org.odpi.openmetadata.frameworks.openmetadata.metadataelements.MetadataElementSummary; +import org.odpi.openmetadata.frameworks.openmetadata.metadataelements.MetadataRelationship; + +import java.util.List; +import java.util.Objects; + +/** + * OpenMetadataElementGraph is used to return an open metadata element along with all of its anchored elements + * and the relationships that they have between one another and to other elements. + */ +public class OpenMetadataElementGraph extends OpenMetadataElement +{ + private List anchoredElements = null; + private List relationships = null; + private String mermaidGraph = null; + + /** + * Default constructor + */ + public OpenMetadataElementGraph() + { + } + + + /** + * Copy/clone constructor. Note, this is a deep copy + * + * @param template template values for asset + */ + public OpenMetadataElementGraph(OpenMetadataElement template) + { + super(template); + } + + + /** + * Copy/clone constructor. Note, this is a deep copy + * + * @param template template values for asset graph + */ + public OpenMetadataElementGraph(OpenMetadataElementGraph template) + { + super(template); + + if (template != null) + { + anchoredElements = template.getAnchoredElements(); + relationships = template.getRelationships(); + mermaidGraph = getMermaidGraph(); + } + } + + + /** + * Return the list of elements that are anchored to the asset. + * + * @return anchored elements + */ + public List getAnchoredElements() + { + return anchoredElements; + } + + + /** + * Set up the list of elements that are anchored to the asset. + * + * @param anchoredElements anchored elements + */ + public void setAnchoredElements(List anchoredElements) + { + this.anchoredElements = anchoredElements; + } + + + /** + * Return the relationships that connect the anchored elements to the asset, to each other, + * and to other open metadata elements. + * + * @return relationships + */ + public List getRelationships() + { + return relationships; + } + + + /** + * Set up the relationships that connect the anchored elements to the asset, to each other, + * and to other open metadata elements. + * + * @param relationships relationships + */ + public void setRelationships(List relationships) + { + this.relationships = relationships; + } + + + /** + * Return the mermaid string used to render a graph. + * + * @return string in Mermaid markdown + */ + public String getMermaidGraph() + { + return mermaidGraph; + } + + + /** + * Set up mermaid string used to render a graph. + * + * @param mermaidGraph string in Mermaid markdown + */ + public void setMermaidGraph(String mermaidGraph) + { + this.mermaidGraph = mermaidGraph; + } + + + /** + * Standard toString method. + * + * @return print out of variables in a JSON-style + */ + @Override + public String toString() + { + return "OpenMetadataElementGraph{" + + "anchoredElements=" + anchoredElements + + ", relationships=" + relationships + + ", mermaidGraph=" + mermaidGraph + + "} " + super.toString(); + } + + + /** + * Compare the values of the supplied object with those stored in the current object. + * + * @param objectToCompare supplied object + * @return boolean result of comparison + */ + @Override + public boolean equals(Object objectToCompare) + { + if (this == objectToCompare) return true; + if (objectToCompare == null || getClass() != objectToCompare.getClass()) return false; + if (!super.equals(objectToCompare)) return false; + OpenMetadataElementGraph that = (OpenMetadataElementGraph) objectToCompare; + return Objects.equals(anchoredElements, that.anchoredElements) && + Objects.equals(relationships, that.relationships) && + Objects.equals(mermaidGraph, that.mermaidGraph); + } + + + /** + * Return hash code based on properties. + * + * @return int + */ + @Override + public int hashCode() + { + return Objects.hash(super.hashCode(), anchoredElements, relationships, mermaidGraph); + } +} diff --git a/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-server/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/MetadataExplorerRESTServices.java b/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-server/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/MetadataExplorerRESTServices.java index c86d6f3bcb..dba620aa26 100644 --- a/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-server/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/MetadataExplorerRESTServices.java +++ b/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-server/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/MetadataExplorerRESTServices.java @@ -6,7 +6,10 @@ import org.odpi.openmetadata.commonservices.ffdc.RESTCallLogger; import org.odpi.openmetadata.commonservices.ffdc.RESTCallToken; import org.odpi.openmetadata.commonservices.ffdc.RESTExceptionHandler; -import org.odpi.openmetadata.commonservices.ffdc.rest.*; +import org.odpi.openmetadata.commonservices.ffdc.rest.GUIDResponse; +import org.odpi.openmetadata.commonservices.ffdc.rest.NameRequestBody; +import org.odpi.openmetadata.commonservices.ffdc.rest.ResultsRequestBody; +import org.odpi.openmetadata.commonservices.ffdc.rest.SearchStringRequestBody; import org.odpi.openmetadata.frameworks.auditlog.AuditLog; import org.odpi.openmetadata.frameworks.openmetadata.enums.SequencingOrder; import org.odpi.openmetadata.frameworkservices.gaf.rest.*; @@ -473,6 +476,83 @@ public RelatedMetadataElementListResponse getRelatedMetadataElements(String } + + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param serverName name of the server instances for this request + * @param viewServiceURLMarker the identifier of the access service (for example asset-owner for the Asset Owner OMAS) + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param requestBody effective time and asOfTime + * + * @return graph of elements or + * InvalidParameterException - one of the parameters is null or invalid or + * PropertyServerException - there is a problem retrieving the connected asset properties from the property server or + * UserNotAuthorizedException - the requesting user is not authorized to issue this request. + */ + public OpenMetadataGraphResponse getAnchoredElementsGraph(String serverName, + String viewServiceURLMarker, + String elementGUID, + boolean forLineage, + boolean forDuplicateProcessing, + int startFrom, + int pageSize, + AnyTimeRequestBody requestBody) + { + final String methodName = "getAnchoredElementsGraph"; + + RESTCallToken token = restCallLogger.logRESTCall(serverName, methodName); + + OpenMetadataGraphResponse response = new OpenMetadataGraphResponse(); + AuditLog auditLog = null; + + try + { + String userId = super.getUser(instanceHandler.getServiceName(), methodName); + + restCallLogger.setUserId(token, userId); + + auditLog = instanceHandler.getAuditLog(userId, serverName, methodName); + + OpenMetadataHandler handler = instanceHandler.getOpenMetadataHandler(userId, serverName, viewServiceURLMarker, methodName); + + if (requestBody != null) + { + response.setElementGraph(handler.getAnchoredElementsGraph(userId, + elementGUID, + forLineage, + forDuplicateProcessing, + startFrom, + pageSize, + requestBody.getAsOfTime(), + requestBody.getEffectiveTime())); + } + else + { + response.setElementGraph(handler.getAnchoredElementsGraph(userId, + elementGUID, + forLineage, + forDuplicateProcessing, + startFrom, + pageSize, + null, + new Date())); + } + } + catch (Exception error) + { + restExceptionHandler.captureExceptions(response, error, methodName, auditLog); + } + + restCallLogger.logRESTCallReturn(token, response.toString()); + return response; + } + + /** * Retrieve the relationships linking to the supplied elements. * @@ -524,8 +604,8 @@ public OpenMetadataRelationshipListResponse getMetadataElementRelationships(Stri { response.setElementList(handler.getMetadataElementRelationships(userId, metadataElementAtEnd1GUID, - relationshipTypeName, metadataElementAtEnd2GUID, + relationshipTypeName, requestBody.getLimitResultsByStatus(), requestBody.getAsOfTime(), requestBody.getSequencingProperty(), @@ -540,8 +620,8 @@ public OpenMetadataRelationshipListResponse getMetadataElementRelationships(Stri { response.setElementList(handler.getMetadataElementRelationships(userId, metadataElementAtEnd1GUID, - relationshipTypeName, metadataElementAtEnd2GUID, + relationshipTypeName, null, null, null, @@ -751,21 +831,21 @@ public OpenMetadataRelationshipResponse getRelationshipByGUID(String if (requestBody != null) { - handler.getRelationshipByGUID(userId, - relationshipGUID, - forLineage, - forDuplicateProcessing, - requestBody.getAsOfTime(), - requestBody.getEffectiveTime()); + response.setElement(handler.getRelationshipByGUID(userId, + relationshipGUID, + forLineage, + forDuplicateProcessing, + requestBody.getAsOfTime(), + requestBody.getEffectiveTime())); } else { - handler.getRelationshipByGUID(userId, - relationshipGUID, - forLineage, - forDuplicateProcessing, - null, - new Date()); + response.setElement(handler.getRelationshipByGUID(userId, + relationshipGUID, + forLineage, + forDuplicateProcessing, + null, + new Date())); } } catch (Exception error) @@ -859,5 +939,4 @@ public OpenMetadataRelationshipListResponse getRelationshipHistory(String restCallLogger.logRESTCallReturn(token, response.toString()); return response; } - } diff --git a/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-spring/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/spring/MetadataExplorerResource.java b/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-spring/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/spring/MetadataExplorerResource.java index 700527dd70..3ca42c6f98 100644 --- a/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-spring/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/spring/MetadataExplorerResource.java +++ b/open-metadata-implementation/view-server-generic-services/metadata-explorer/metadata-explorer-spring/src/main/java/org/odpi/openmetadata/viewservices/metadataexplorer/server/spring/MetadataExplorerResource.java @@ -374,8 +374,8 @@ public OpenMetadataRelationshipListResponse getAllMetadataElementRelationships(@ return restAPI.getMetadataElementRelationships(serverName, metadataElementAtEnd1GUID, null, - urlMarker, metadataElementAtEnd2GUID, + urlMarker, forLineage, forDuplicateProcessing, startFrom, @@ -384,6 +384,44 @@ public OpenMetadataRelationshipListResponse getAllMetadataElementRelationships(@ } + /** + * Return all the elements that are anchored to an asset plus relationships between these elements and to other elements. + * + * @param serverName name of the server instances for this request + * @param urlMarker the identifier of the view service (for example runtime-manager for the Runtime Manager OMVS) + * @param elementGUID unique identifier for the element + * @param forLineage the retrieved element is for lineage processing so include archived elements + * @param forDuplicateProcessing the retrieved elements are for duplicate processing so do not combine results from known duplicates. + * @param startFrom starting element (used in paging through large result sets) + * @param pageSize maximum number of results to return + * @param requestBody effective time and asOfTime + * + * @return graph of elements or + * InvalidParameterException - one of the parameters is null or invalid or + * PropertyServerException - there is a problem retrieving the connected asset properties from the property server or + * UserNotAuthorizedException - the requesting user is not authorized to issue this request. + */ + @PostMapping(path = "/metadata-elements/{elementGUID}/with-anchored-elements") + + public OpenMetadataGraphResponse getAnchoredElementsGraph(@PathVariable String serverName, + @PathVariable String urlMarker, + @PathVariable String elementGUID, + @RequestParam(required = false, defaultValue = "false") + boolean forLineage, + @RequestParam(required = false, defaultValue = "false") + boolean forDuplicateProcessing, + @RequestParam(required = false, defaultValue = "0") + int startFrom, + @RequestParam(required = false, defaultValue = "0") + int pageSize, + @RequestBody (required = false) + AnyTimeRequestBody requestBody) + { + return restAPI.getAnchoredElementsGraph(serverName, urlMarker, elementGUID, forLineage, forDuplicateProcessing, startFrom, pageSize, requestBody); + } + + + /** * Retrieve the relationships linking the supplied elements via a specific type of relationship. *