From 848574dbffbbed813c811fcf06c173154b2bcce5 Mon Sep 17 00:00:00 2001 From: RyanHolstien Date: Tue, 22 Nov 2022 13:05:09 -0600 Subject: [PATCH] fix(platform): patch for entity creation, honor async flag on request (#6504) --- .../linkedin/metadata/entity/AspectUtils.java | 7 ++- .../linkedin/metadata/AspectUtilsTest.java | 59 +++++++++++++++++++ .../entity/client/RestliEntityClient.java | 2 +- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 metadata-io/src/test/java/com/linkedin/metadata/AspectUtilsTest.java diff --git a/metadata-io/src/main/java/com/linkedin/metadata/entity/AspectUtils.java b/metadata-io/src/main/java/com/linkedin/metadata/entity/AspectUtils.java index a046ff7171..6b7bea11d1 100644 --- a/metadata-io/src/main/java/com/linkedin/metadata/entity/AspectUtils.java +++ b/metadata-io/src/main/java/com/linkedin/metadata/entity/AspectUtils.java @@ -73,9 +73,10 @@ public class AspectUtils { try { MetadataChangeProposal proposal = original.copy(); GenericAspect genericAspect = GenericRecordUtils.serializeAspect(aspect); - // Set UPSERT changetype here as additional changes being added should always be - // done in UPSERT mode even for patches - // proposal.setChangeType(ChangeType.UPSERT); + // Additional changes should never be set as PATCH, if a PATCH is coming across it should be an UPSERT + if (ChangeType.PATCH.equals(proposal.getChangeType())) { + proposal.setChangeType(ChangeType.UPSERT); + } proposal.setAspect(genericAspect); proposal.setAspectName(aspectName); return proposal; diff --git a/metadata-io/src/test/java/com/linkedin/metadata/AspectUtilsTest.java b/metadata-io/src/test/java/com/linkedin/metadata/AspectUtilsTest.java new file mode 100644 index 0000000000..0f1b312928 --- /dev/null +++ b/metadata-io/src/test/java/com/linkedin/metadata/AspectUtilsTest.java @@ -0,0 +1,59 @@ +package com.linkedin.metadata; + +import com.linkedin.common.FabricType; +import com.linkedin.common.urn.DataPlatformUrn; +import com.linkedin.common.urn.DatasetUrn; +import com.linkedin.dataset.DatasetProperties; +import com.linkedin.events.metadata.ChangeType; +import com.linkedin.metadata.entity.AspectUtils; +import com.linkedin.metadata.entity.EntityService; +import com.linkedin.metadata.entity.TestEntityRegistry; +import com.linkedin.metadata.entity.ebean.EbeanAspectDao; +import com.linkedin.metadata.event.EventProducer; +import com.linkedin.metadata.models.registry.ConfigEntityRegistry; +import com.linkedin.metadata.models.registry.EntityRegistry; +import com.linkedin.metadata.models.registry.EntityRegistryException; +import com.linkedin.metadata.models.registry.MergedEntityRegistry; +import com.linkedin.metadata.snapshot.Snapshot; +import com.linkedin.metadata.utils.GenericRecordUtils; +import com.linkedin.mxe.MetadataChangeProposal; +import io.ebean.EbeanServer; +import java.util.List; +import org.testng.Assert; +import org.testng.annotations.Test; + +import static org.mockito.Mockito.*; + + +public class AspectUtilsTest { + + protected final EntityRegistry _snapshotEntityRegistry = new TestEntityRegistry(); + protected final EntityRegistry _configEntityRegistry = + new ConfigEntityRegistry(Snapshot.class.getClassLoader().getResourceAsStream("entity-registry.yml")); + protected final EntityRegistry _testEntityRegistry = + new MergedEntityRegistry(_snapshotEntityRegistry).apply(_configEntityRegistry); + + public AspectUtilsTest() throws EntityRegistryException { + } + + @Test + public void testAdditionalChanges() { + EbeanServer server = EbeanTestUtils.createTestServer(); + EbeanAspectDao aspectDao = new EbeanAspectDao(server); + aspectDao.setConnectionValidated(true); + EventProducer mockProducer = mock(EventProducer.class); + EntityService entityService = new EntityService(aspectDao, mockProducer, _testEntityRegistry); + + MetadataChangeProposal proposal1 = new MetadataChangeProposal(); + proposal1.setEntityUrn(new DatasetUrn(new DataPlatformUrn("platform"), "name", FabricType.PROD)); + proposal1.setAspectName("datasetProperties"); + DatasetProperties datasetProperties = new DatasetProperties().setName("name"); + proposal1.setAspect(GenericRecordUtils.serializeAspect(datasetProperties)); + proposal1.setEntityType("dataset"); + proposal1.setChangeType(ChangeType.PATCH); + + List proposalList = AspectUtils.getAdditionalChanges(proposal1, entityService); + Assert.assertEquals(proposalList.size(), 3); + Assert.assertEquals(proposalList.get(0).getChangeType(), ChangeType.UPSERT); + } +} diff --git a/metadata-service/restli-client/src/main/java/com/linkedin/entity/client/RestliEntityClient.java b/metadata-service/restli-client/src/main/java/com/linkedin/entity/client/RestliEntityClient.java index 9e8dcf5220..b767a380ed 100644 --- a/metadata-service/restli-client/src/main/java/com/linkedin/entity/client/RestliEntityClient.java +++ b/metadata-service/restli-client/src/main/java/com/linkedin/entity/client/RestliEntityClient.java @@ -628,7 +628,7 @@ public class RestliEntityClient extends BaseClient implements EntityClient { public String ingestProposal(@Nonnull final MetadataChangeProposal metadataChangeProposal, @Nonnull final Authentication authentication, final boolean async) throws RemoteInvocationException { final AspectsDoIngestProposalRequestBuilder requestBuilder = - ASPECTS_REQUEST_BUILDERS.actionIngestProposal().proposalParam(metadataChangeProposal); + ASPECTS_REQUEST_BUILDERS.actionIngestProposal().proposalParam(metadataChangeProposal).asyncParam(String.valueOf(async)); return sendClientRequest(requestBuilder, authentication).getEntity(); }