fix(resolver): Allow users to add/remove related terms for children glossary terms (#9895)

This commit is contained in:
Pinaki Bhattacharjee 2024-03-22 20:14:43 +05:30 committed by GitHub
parent 27612bd3d6
commit d573acde7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 17 deletions

View File

@ -1183,9 +1183,11 @@ public class GmsGraphQLEngine {
new DeleteGlossaryEntityResolver(this.entityClient, this.entityService))
.dataFetcher(
"updateName", new UpdateNameResolver(this.entityService, this.entityClient))
.dataFetcher("addRelatedTerms", new AddRelatedTermsResolver(this.entityService))
.dataFetcher("addRelatedTerms", new AddRelatedTermsResolver(this.entityService,
this.entityClient))
.dataFetcher(
"removeRelatedTerms", new RemoveRelatedTermsResolver(this.entityService))
"removeRelatedTerms", new RemoveRelatedTermsResolver(this.entityService,
this.entityClient))
.dataFetcher(
"createNativeUserResetToken",
new CreateNativeUserResetTokenResolver(this.nativeUserService))

View File

@ -12,6 +12,7 @@ import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.RelatedTermsInput;
import com.linkedin.datahub.graphql.generated.TermRelationshipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.GlossaryUtils;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.glossary.GlossaryRelatedTerms;
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.entity.EntityService;
@ -30,6 +31,7 @@ import lombok.extern.slf4j.Slf4j;
public class AddRelatedTermsResolver implements DataFetcher<CompletableFuture<Boolean>> {
private final EntityService<?> _entityService;
private final EntityClient _entityClient;
@Override
public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throws Exception {
@ -37,10 +39,12 @@ public class AddRelatedTermsResolver implements DataFetcher<CompletableFuture<Bo
final QueryContext context = environment.getContext();
final RelatedTermsInput input =
bindArgument(environment.getArgument("input"), RelatedTermsInput.class);
final Urn urn = Urn.createFromString(input.getUrn());
return CompletableFuture.supplyAsync(
() -> {
if (GlossaryUtils.canManageGlossaries(context)) {
final Urn parentUrn = GlossaryUtils.getParentUrn(urn, context, _entityClient);
if (GlossaryUtils.canManageChildrenEntities(context, parentUrn, _entityClient)) {
try {
final TermRelationshipType relationshipType = input.getRelationshipType();
final Urn urn = Urn.createFromString(input.getUrn());

View File

@ -11,6 +11,7 @@ import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.RelatedTermsInput;
import com.linkedin.datahub.graphql.generated.TermRelationshipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.GlossaryUtils;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.glossary.GlossaryRelatedTerms;
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.entity.EntityService;
@ -28,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
public class RemoveRelatedTermsResolver implements DataFetcher<CompletableFuture<Boolean>> {
private final EntityService<?> _entityService;
private final EntityClient _entityClient;
@Override
public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throws Exception {
@ -35,13 +37,14 @@ public class RemoveRelatedTermsResolver implements DataFetcher<CompletableFuture
final QueryContext context = environment.getContext();
final RelatedTermsInput input =
bindArgument(environment.getArgument("input"), RelatedTermsInput.class);
final Urn urn = Urn.createFromString(input.getUrn());
return CompletableFuture.supplyAsync(
() -> {
if (GlossaryUtils.canManageGlossaries(context)) {
final Urn parentUrn = GlossaryUtils.getParentUrn(urn, context, _entityClient);
if (GlossaryUtils.canManageChildrenEntities(context, parentUrn, _entityClient)) {
try {
final TermRelationshipType relationshipType = input.getRelationshipType();
final Urn urn = Urn.createFromString(input.getUrn());
final List<Urn> termUrnsToRemove =
input.getTermUrns().stream().map(UrnUtils::getUrn).collect(Collectors.toList());

View File

@ -11,6 +11,7 @@ import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.RelatedTermsInput;
import com.linkedin.datahub.graphql.generated.TermRelationshipType;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.entity.EntityService;
import graphql.schema.DataFetchingEnvironment;
@ -39,6 +40,7 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetSuccessIsRelatedNonExistent() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
@ -47,7 +49,7 @@ public class AddRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_TERM_2_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -72,6 +74,7 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetSuccessHasRelatedNonExistent() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
@ -80,7 +83,7 @@ public class AddRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_TERM_2_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -105,11 +108,12 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetFailAddSelfAsRelatedTerm() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -126,11 +130,12 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetFailAddNonTermAsRelatedTerm() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -147,13 +152,14 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetFailAddNonExistentTermAsRelatedTerm() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_TERM_1_URN)), eq(true)))
.thenReturn(false);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -170,13 +176,14 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetFailAddToNonExistentUrn() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(false);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_TERM_1_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -193,13 +200,14 @@ public class AddRelatedTermsResolverTest {
@Test
public void testGetFailAddToNonTerm() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(DATASET_URN)), eq(true)))
.thenReturn(true);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_TERM_1_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -216,6 +224,7 @@ public class AddRelatedTermsResolverTest {
@Test
public void testFailNoPermissions() throws Exception {
EntityService mockService = setUpService();
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
@ -224,7 +233,7 @@ public class AddRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_TERM_2_URN)), eq(true)))
.thenReturn(true);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService);
AddRelatedTermsResolver resolver = new AddRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockDenyContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);

View File

@ -13,6 +13,7 @@ import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.RelatedTermsInput;
import com.linkedin.datahub.graphql.generated.TermRelationshipType;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.glossary.GlossaryRelatedTerms;
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.entity.EntityService;
@ -44,8 +45,9 @@ public class RemoveRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
EntityClient mockClient = Mockito.mock(EntityClient.class);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -77,8 +79,9 @@ public class RemoveRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
EntityClient mockClient = Mockito.mock(EntityClient.class);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -106,8 +109,9 @@ public class RemoveRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
EntityClient mockClient = Mockito.mock(EntityClient.class);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockAllowContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -137,8 +141,9 @@ public class RemoveRelatedTermsResolverTest {
Mockito.when(mockService.exists(eq(Urn.createFromString(TEST_ENTITY_URN)), eq(true)))
.thenReturn(true);
EntityClient mockClient = Mockito.mock(EntityClient.class);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService);
RemoveRelatedTermsResolver resolver = new RemoveRelatedTermsResolver(mockService, mockClient);
QueryContext mockContext = getMockDenyContext();
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);