From 7bbeedddc4bd51791ab952e8649193fc5f02f2ff Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Wed, 26 Jul 2023 10:56:40 -0400 Subject: [PATCH] fix(dataProduct) Show entity count excluding soft deleted entities (#8444) Co-authored-by: Joshua Eilers --- .../com/linkedin/datahub/graphql/GmsGraphQLEngine.java | 8 ++++++++ .../dataproduct/ListDataProductAssetsResolver.java | 5 ++++- datahub-graphql-core/src/main/resources/entity.graphql | 7 ++++++- .../src/app/entity/dataProduct/DataProductEntity.tsx | 6 +++--- datahub-web-react/src/graphql/dataProduct.graphql | 4 +++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java index f22568602d..d6dd2de6d3 100644 --- a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java @@ -645,6 +645,7 @@ public class GmsGraphQLEngine { configureOrganisationRoleResolvers(builder); configureGlossaryNodeResolvers(builder); configureDomainResolvers(builder); + configureDataProductResolvers(builder); configureAssertionResolvers(builder); configurePolicyResolvers(builder); configureDataProcessInstanceResolvers(builder); @@ -1679,6 +1680,13 @@ public class GmsGraphQLEngine { ); } + private void configureDataProductResolvers(final RuntimeWiring.Builder builder) { + builder.type("DataProduct", typeWiring -> typeWiring + .dataFetcher("entities", new ListDataProductAssetsResolver(this.entityClient)) + .dataFetcher("relationships", new EntityRelationshipsResultResolver(graphClient)) + ); + } + private void configureAssertionResolvers(final RuntimeWiring.Builder builder) { builder.type("Assertion", typeWiring -> typeWiring.dataFetcher("relationships", new EntityRelationshipsResultResolver(graphClient)) diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/dataproduct/ListDataProductAssetsResolver.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/dataproduct/ListDataProductAssetsResolver.java index c1c3786840..f7db6e5694 100644 --- a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/dataproduct/ListDataProductAssetsResolver.java +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/dataproduct/ListDataProductAssetsResolver.java @@ -5,6 +5,7 @@ import com.linkedin.common.urn.Urn; import com.linkedin.common.urn.UrnUtils; import com.linkedin.data.DataMap; import com.linkedin.datahub.graphql.QueryContext; +import com.linkedin.datahub.graphql.generated.DataProduct; import com.linkedin.datahub.graphql.generated.EntityType; import com.linkedin.datahub.graphql.generated.SearchAcrossEntitiesInput; import com.linkedin.datahub.graphql.generated.SearchResults; @@ -50,7 +51,9 @@ public class ListDataProductAssetsResolver implements DataFetcher get(DataFetchingEnvironment environment) { final QueryContext context = environment.getContext(); - final Urn dataProductUrn = UrnUtils.getUrn(environment.getArgument("urn")); + // get urn from either input or source (in the case of "entities" field) + final String urn = environment.getArgument("urn") != null ? environment.getArgument("urn") : ((DataProduct) environment.getSource()).getUrn(); + final Urn dataProductUrn = UrnUtils.getUrn(urn); final SearchAcrossEntitiesInput input = bindArgument(environment.getArgument("input"), SearchAcrossEntitiesInput.class); diff --git a/datahub-graphql-core/src/main/resources/entity.graphql b/datahub-graphql-core/src/main/resources/entity.graphql index 59e35d5bc3..d4745af33e 100644 --- a/datahub-graphql-core/src/main/resources/entity.graphql +++ b/datahub-graphql-core/src/main/resources/entity.graphql @@ -10890,6 +10890,11 @@ type DataProduct implements Entity { """ relationships(input: RelationshipsInput!): EntityRelationshipsResult + """ + Children entities inside of the DataProduct + """ + entities(input: SearchAcrossEntitiesInput): SearchResults + """ The structured glossary terms associated with the Data Product """ @@ -10926,7 +10931,7 @@ type DataProductProperties { externalUrl: String """ - Number of children entities inside of the Data Product + Number of children entities inside of the Data Product. This number includes soft deleted entities. """ numAssets: Int diff --git a/datahub-web-react/src/app/entity/dataProduct/DataProductEntity.tsx b/datahub-web-react/src/app/entity/dataProduct/DataProductEntity.tsx index a20aa017f2..faa254cce7 100644 --- a/datahub-web-react/src/app/entity/dataProduct/DataProductEntity.tsx +++ b/datahub-web-react/src/app/entity/dataProduct/DataProductEntity.tsx @@ -132,7 +132,7 @@ export class DataProductEntity implements Entity { globalTags={data.tags} glossaryTerms={data.glossaryTerms} domain={data.domain?.domain} - entityCount={data?.properties?.numAssets || undefined} + entityCount={data?.entities?.total || undefined} externalUrl={data.properties?.externalUrl} /> ); @@ -149,7 +149,7 @@ export class DataProductEntity implements Entity { globalTags={data.tags} glossaryTerms={data.glossaryTerms} domain={data.domain?.domain} - entityCount={data?.properties?.numAssets || undefined} + entityCount={data?.entities?.total || undefined} externalUrl={data.properties?.externalUrl} /> ); @@ -162,7 +162,7 @@ export class DataProductEntity implements Entity { getOverridePropertiesFromEntity = (data: DataProduct) => { const name = data?.properties?.name; const externalUrl = data?.properties?.externalUrl; - const entityCount = data?.properties?.numAssets || undefined; + const entityCount = data?.entities?.total || undefined; return { name, externalUrl, diff --git a/datahub-web-react/src/graphql/dataProduct.graphql b/datahub-web-react/src/graphql/dataProduct.graphql index 994f43a0e8..464ab7cc12 100644 --- a/datahub-web-react/src/graphql/dataProduct.graphql +++ b/datahub-web-react/src/graphql/dataProduct.graphql @@ -24,7 +24,6 @@ fragment dataProductSearchFields on DataProduct { name description externalUrl - numAssets } ownership { ...ownershipFields @@ -38,6 +37,9 @@ fragment dataProductSearchFields on DataProduct { domain { ...entityDomain } + entities(input: { start: 0, count: 0, query: "*" }) { + total + } } mutation createDataProduct($input: CreateDataProductInput!) {