diff --git a/metadata-service/openapi-servlet/build.gradle b/metadata-service/openapi-servlet/build.gradle index f5cdfe42cbff68..08f019bed70fb2 100644 --- a/metadata-service/openapi-servlet/build.gradle +++ b/metadata-service/openapi-servlet/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'java' dependencies { + compile project(':metadata-service:auth-api') compile project(':metadata-service:factories') compile externalDependency.reflections diff --git a/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/entities/EntitiesController.java b/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/entities/EntitiesController.java index fd73553e0e58cd..2209180bb47e6a 100644 --- a/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/entities/EntitiesController.java +++ b/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/entities/EntitiesController.java @@ -2,6 +2,8 @@ import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; +import com.datahub.authentication.Authentication; +import com.datahub.authentication.AuthenticationContext; import com.fasterxml.jackson.databind.ObjectMapper; import com.linkedin.common.urn.Urn; import com.linkedin.common.urn.UrnUtils; @@ -104,9 +106,12 @@ public ResponseEntity> postEntities( @RequestBody @Nonnull List aspectRequests) { log.info("INGEST PROPOSAL proposal: {}", aspectRequests); + Authentication authentication = AuthenticationContext.getAuthentication(); + String actorUrnStr = authentication.getActor().toUrnStr(); + List> responses = aspectRequests.stream() .map(MappingUtil::mapToProposal) - .map(proposal -> MappingUtil.ingestProposal(proposal, _entityService, _objectMapper)) + .map(proposal -> MappingUtil.ingestProposal(proposal, actorUrnStr, _entityService, _objectMapper)) .collect(Collectors.toList()); if (responses.stream().anyMatch(Pair::getSecond)) { return ResponseEntity.status(HttpStatus.CREATED) @@ -140,10 +145,14 @@ public ResponseEntity> deleteEntities( List deleteRequests = entityUrns.stream() .map(entityUrn -> MappingUtil.createStatusRemoval(entityUrn, _entityService)) .collect(Collectors.toList()); + + Authentication authentication = AuthenticationContext.getAuthentication(); + String actorUrnStr = authentication.getActor().toUrnStr(); + return ResponseEntity.ok(Collections.singletonList(RollbackRunResultDto.builder() .rowsRolledBack(deleteRequests.stream() .map(MappingUtil::mapToProposal) - .map(proposal -> MappingUtil.ingestProposal(proposal, _entityService, _objectMapper)) + .map(proposal -> MappingUtil.ingestProposal(proposal, actorUrnStr, _entityService, _objectMapper)) .filter(Pair::getSecond) .map(Pair::getFirst) .map(urnString -> new AspectRowSummary().urn(urnString)) diff --git a/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/platform/entities/PlatformEntitiesController.java b/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/platform/entities/PlatformEntitiesController.java index 0d7ed888c8f8b9..5f968a56ee215f 100644 --- a/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/platform/entities/PlatformEntitiesController.java +++ b/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/platform/entities/PlatformEntitiesController.java @@ -1,5 +1,7 @@ package io.datahubproject.openapi.platform.entities; +import com.datahub.authentication.Authentication; +import com.datahub.authentication.AuthenticationContext; import com.fasterxml.jackson.databind.ObjectMapper; import com.linkedin.metadata.entity.EntityService; import com.linkedin.util.Pair; @@ -44,8 +46,11 @@ public ResponseEntity> postEntities( @RequestBody @Nonnull List metadataChangeProposals) { log.info("INGEST PROPOSAL proposal: {}", metadataChangeProposals); + Authentication authentication = AuthenticationContext.getAuthentication(); + String actorUrnStr = authentication.getActor().toUrnStr(); + List> responses = metadataChangeProposals.stream() - .map(proposal -> MappingUtil.ingestProposal(proposal, _entityService, _objectMapper)) + .map(proposal -> MappingUtil.ingestProposal(proposal, actorUrnStr, _entityService, _objectMapper)) .collect(Collectors.toList()); if (responses.stream().anyMatch(Pair::getSecond)) { return ResponseEntity.status(HttpStatus.CREATED) diff --git a/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/util/MappingUtil.java b/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/util/MappingUtil.java index 8d071965353229..15a90afa3612b7 100644 --- a/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/util/MappingUtil.java +++ b/metadata-service/openapi-servlet/src/main/java/io/datahubproject/openapi/util/MappingUtil.java @@ -14,7 +14,6 @@ import com.linkedin.data.template.RecordTemplate; import com.linkedin.entity.Aspect; import com.linkedin.events.metadata.ChangeType; -import com.linkedin.metadata.Constants; import com.linkedin.metadata.entity.EntityService; import com.linkedin.metadata.entity.RollbackRunResult; import com.linkedin.metadata.entity.ValidationException; @@ -246,13 +245,13 @@ public static GenericAspect convertGenericAspect(@Nonnull io.datahubproject.open } } - public static Pair ingestProposal(MetadataChangeProposal metadataChangeProposal, EntityService entityService, + public static Pair ingestProposal(MetadataChangeProposal metadataChangeProposal, String actorUrn, EntityService entityService, ObjectMapper objectMapper) { // TODO: Use the actor present in the IC. Timer.Context context = MetricUtils.timer("postEntity").time(); final com.linkedin.common.AuditStamp auditStamp = new com.linkedin.common.AuditStamp().setTime(System.currentTimeMillis()) - .setActor(UrnUtils.getUrn(Constants.UNKNOWN_ACTOR)); + .setActor(UrnUtils.getUrn(actorUrn)); io.datahubproject.openapi.generated.KafkaAuditHeader auditHeader = metadataChangeProposal.getAuditHeader(); com.linkedin.mxe.MetadataChangeProposal serviceProposal = diff --git a/metadata-service/openapi-servlet/src/test/java/entities/EntitiesControllerTest.java b/metadata-service/openapi-servlet/src/test/java/entities/EntitiesControllerTest.java index d81069f07efd6a..b158c4ca6ad00e 100644 --- a/metadata-service/openapi-servlet/src/test/java/entities/EntitiesControllerTest.java +++ b/metadata-service/openapi-servlet/src/test/java/entities/EntitiesControllerTest.java @@ -1,5 +1,9 @@ package entities; +import com.datahub.authentication.Actor; +import com.datahub.authentication.ActorType; +import com.datahub.authentication.Authentication; +import com.datahub.authentication.AuthenticationContext; import com.fasterxml.jackson.databind.ObjectMapper; import com.linkedin.metadata.entity.AspectDao; import com.linkedin.metadata.event.EventProducer; @@ -34,6 +38,7 @@ import org.testng.annotations.Test; import static com.linkedin.metadata.Constants.*; +import static org.mockito.Mockito.when; public class EntitiesControllerTest { @@ -53,6 +58,9 @@ public void setup() EventProducer mockEntityEventProducer = Mockito.mock(EventProducer.class); MockEntityService mockEntityService = new MockEntityService(aspectDao, mockEntityEventProducer, mockEntityRegistry); _entitiesController = new EntitiesController(mockEntityService, new ObjectMapper()); + Authentication authentication = Mockito.mock(Authentication.class); + when(authentication.getActor()).thenReturn(new Actor(ActorType.USER, "datahub")); + AuthenticationContext.setAuthentication(authentication); } EntitiesController _entitiesController; diff --git a/metadata-service/restli-servlet-impl/build.gradle b/metadata-service/restli-servlet-impl/build.gradle index eafe43f74e8e34..0d66373e8c127e 100644 --- a/metadata-service/restli-servlet-impl/build.gradle +++ b/metadata-service/restli-servlet-impl/build.gradle @@ -33,6 +33,7 @@ dependencies { } compile project(':metadata-service:restli-api') + compile project(':metadata-service:auth-api') compile project(path: ':metadata-service:restli-api', configuration: 'dataTemplate') compile project(':li-utils') compile project(':metadata-models') diff --git a/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/AspectResource.java b/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/AspectResource.java index 3305f48b5c0442..e65269d244eb28 100644 --- a/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/AspectResource.java +++ b/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/AspectResource.java @@ -1,10 +1,11 @@ package com.linkedin.metadata.resources.entity; import com.codahale.metrics.MetricRegistry; +import com.datahub.authentication.Authentication; +import com.datahub.authentication.AuthenticationContext; import com.linkedin.aspect.GetTimeseriesAspectValuesResponse; import com.linkedin.common.AuditStamp; import com.linkedin.common.urn.Urn; -import com.linkedin.metadata.Constants; import com.linkedin.metadata.aspect.EnvelopedAspectArray; import com.linkedin.metadata.aspect.VersionedAspect; import com.linkedin.metadata.entity.EntityService; @@ -124,9 +125,10 @@ public Task ingestProposal( @ActionParam(PARAM_PROPOSAL) @Nonnull MetadataChangeProposal metadataChangeProposal) throws URISyntaxException { log.info("INGEST PROPOSAL proposal: {}", metadataChangeProposal); - // TODO: Use the actor present in the IC. - final AuditStamp auditStamp = - new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(Constants.UNKNOWN_ACTOR)); + Authentication authentication = AuthenticationContext.getAuthentication(); + String actorUrnStr = authentication.getActor().toUrnStr(); + final AuditStamp auditStamp = new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(actorUrnStr)); + final List additionalChanges = AspectUtils.getAdditionalChanges(metadataChangeProposal, _entityService); diff --git a/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/EntityResource.java b/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/EntityResource.java index ea6dc4f76551a6..714092bd40152d 100644 --- a/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/EntityResource.java +++ b/metadata-service/restli-servlet-impl/src/main/java/com/linkedin/metadata/resources/entity/EntityResource.java @@ -1,13 +1,14 @@ package com.linkedin.metadata.resources.entity; import com.codahale.metrics.MetricRegistry; +import com.datahub.authentication.Authentication; +import com.datahub.authentication.AuthenticationContext; import com.linkedin.common.AuditStamp; import com.linkedin.common.UrnArray; import com.linkedin.common.urn.Urn; import com.linkedin.data.template.LongMap; import com.linkedin.data.template.StringArray; import com.linkedin.entity.Entity; -import com.linkedin.metadata.Constants; import com.linkedin.metadata.browse.BrowseResult; import com.linkedin.metadata.entity.DeleteEntityService; import com.linkedin.metadata.entity.EntityService; @@ -193,9 +194,9 @@ public Task ingest(@ActionParam(PARAM_ENTITY) @Nonnull Entity entity, SystemMetadata systemMetadata = populateDefaultFieldsIfEmpty(providedSystemMetadata); - // TODO Correctly audit ingestions. - final AuditStamp auditStamp = - new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(Constants.UNKNOWN_ACTOR)); + Authentication authentication = AuthenticationContext.getAuthentication(); + String actorUrnStr = authentication.getActor().toUrnStr(); + final AuditStamp auditStamp = new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(actorUrnStr)); // variables referenced in lambdas are required to be final final SystemMetadata finalSystemMetadata = systemMetadata; @@ -219,8 +220,9 @@ public Task batchIngest(@ActionParam(PARAM_ENTITIES) @Nonnull Entity[] ent } } - final AuditStamp auditStamp = - new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(Constants.UNKNOWN_ACTOR)); + Authentication authentication = AuthenticationContext.getAuthentication(); + String actorUrnStr = authentication.getActor().toUrnStr(); + final AuditStamp auditStamp = new AuditStamp().setTime(_clock.millis()).setActor(Urn.createFromString(actorUrnStr)); if (systemMetadataList == null) { systemMetadataList = new SystemMetadata[entities.length];