fix(tags) Add creator of tag as the owner of it (#5787)

This commit is contained in:
Chris Collins 2022-08-31 13:21:51 -04:00 committed by GitHub
parent c0a69eb2eb
commit 23275a14d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 7 deletions

View File

@ -704,7 +704,7 @@ public class GmsGraphQLEngine {
builder.type("Mutation", typeWiring -> typeWiring
.dataFetcher("updateDataset", new MutableTypeResolver<>(datasetType))
.dataFetcher("updateDatasets", new MutableTypeBatchResolver<>(datasetType))
.dataFetcher("createTag", new CreateTagResolver(this.entityClient))
.dataFetcher("createTag", new CreateTagResolver(this.entityClient, this.entityService))
.dataFetcher("updateTag", new MutableTypeResolver<>(tagType))
.dataFetcher("setTagColor", new SetTagColorResolver(entityClient, entityService))
.dataFetcher("deleteTag", new DeleteTagResolver(entityClient))

View File

@ -1,13 +1,22 @@
package com.linkedin.datahub.graphql.resolvers.tag;
import com.google.common.collect.ImmutableList;
import com.linkedin.common.urn.CorpuserUrn;
import com.linkedin.common.urn.Urn;
import com.linkedin.data.template.SetMode;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.CreateTagInput;
import com.linkedin.datahub.graphql.generated.OwnerEntityType;
import com.linkedin.datahub.graphql.generated.OwnerInput;
import com.linkedin.datahub.graphql.generated.OwnershipType;
import com.linkedin.datahub.graphql.generated.ResourceRefInput;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.events.metadata.ChangeType;
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.entity.EntityService;
import com.linkedin.metadata.key.TagKey;
import com.linkedin.metadata.utils.EntityKeyUtils;
import com.linkedin.metadata.utils.GenericRecordUtils;
@ -30,6 +39,7 @@ import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.*;
public class CreateTagResolver implements DataFetcher<CompletableFuture<String>> {
private final EntityClient _entityClient;
private final EntityService _entityService;
@Override
public CompletableFuture<String> get(DataFetchingEnvironment environment) throws Exception {
@ -62,10 +72,13 @@ public class CreateTagResolver implements DataFetcher<CompletableFuture<String>>
proposal.setAspectName(Constants.TAG_PROPERTIES_ASPECT_NAME);
proposal.setAspect(GenericRecordUtils.serializeAspect(mapTagProperties(input)));
proposal.setChangeType(ChangeType.UPSERT);
return _entityClient.ingestProposal(proposal, context.getAuthentication());
String tagUrn = _entityClient.ingestProposal(proposal, context.getAuthentication());
addCreatorAsOwner(context, tagUrn);
return tagUrn;
} catch (Exception e) {
log.error("Failed to create Domain with id: {}, name: {}: {}", input.getId(), input.getName(), e.getMessage());
throw new RuntimeException(String.format("Failed to create Domain with id: %s, name: %s", input.getId(), input.getName()), e);
log.error("Failed to create Tag with id: {}, name: {}: {}", input.getId(), input.getName(), e.getMessage());
throw new RuntimeException(String.format("Failed to create Tag with id: %s, name: %s", input.getId(), input.getName()), e);
}
});
}
@ -76,4 +89,18 @@ public class CreateTagResolver implements DataFetcher<CompletableFuture<String>>
result.setDescription(input.getDescription(), SetMode.IGNORE_NULL);
return result;
}
private void addCreatorAsOwner(QueryContext context, String tagUrn) {
try {
Urn actorUrn = CorpuserUrn.createFromString(context.getActorUrn());
OwnerUtils.addOwnersToResources(
ImmutableList.of(new OwnerInput(actorUrn.toString(), OwnerEntityType.CORP_USER, OwnershipType.TECHNICAL_OWNER)),
ImmutableList.of(new ResourceRefInput(tagUrn, null, null)),
actorUrn,
_entityService
);
} catch (Exception e) {
log.error(String.format("Failed to add creator as owner of tag %s", tagUrn), e);
}
}
}

View File

@ -4,6 +4,7 @@ import com.datahub.authentication.Authentication;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.CreateTagInput;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.metadata.entity.EntityService;
import com.linkedin.tag.TagProperties;
import com.linkedin.events.metadata.ChangeType;
import com.linkedin.metadata.Constants;
@ -12,6 +13,7 @@ import com.linkedin.metadata.utils.GenericRecordUtils;
import com.linkedin.mxe.MetadataChangeProposal;
import graphql.schema.DataFetchingEnvironment;
import java.util.concurrent.CompletionException;
import org.mockito.Mockito;
import org.testng.annotations.Test;
@ -30,10 +32,11 @@ public class CreateTagResolverTest {
@Test
public void testGetSuccess() throws Exception {
// Create resolver
EntityService mockService = Mockito.mock(EntityService.class);
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.when(mockClient.ingestProposal(Mockito.any(MetadataChangeProposal.class), Mockito.any(Authentication.class)))
.thenReturn(String.format("urn:li:tag:%s", TEST_INPUT.getId()));
CreateTagResolver resolver = new CreateTagResolver(mockClient);
CreateTagResolver resolver = new CreateTagResolver(mockClient, mockService);
// Execute resolver
QueryContext mockContext = getMockAllowContext();
@ -65,8 +68,9 @@ public class CreateTagResolverTest {
@Test
public void testGetUnauthorized() throws Exception {
// Create resolver
EntityService mockService = Mockito.mock(EntityService.class);
EntityClient mockClient = Mockito.mock(EntityClient.class);
CreateTagResolver resolver = new CreateTagResolver(mockClient);
CreateTagResolver resolver = new CreateTagResolver(mockClient, mockService);
// Execute resolver
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);
@ -83,11 +87,12 @@ public class CreateTagResolverTest {
@Test
public void testGetEntityClientException() throws Exception {
// Create resolver
EntityService mockService = Mockito.mock(EntityService.class);
EntityClient mockClient = Mockito.mock(EntityClient.class);
Mockito.doThrow(RuntimeException.class).when(mockClient).ingestProposal(
Mockito.any(),
Mockito.any(Authentication.class));
CreateTagResolver resolver = new CreateTagResolver(mockClient);
CreateTagResolver resolver = new CreateTagResolver(mockClient, mockService);
// Execute resolver
DataFetchingEnvironment mockEnv = Mockito.mock(DataFetchingEnvironment.class);