diff --git a/NOTICE b/NOTICE index 51a5c1faf14eee5b858b61c082a575cc19542a87..d4657e8e70ad06febe974f563eb642517fac447f 100644 --- a/NOTICE +++ b/NOTICE @@ -120,6 +120,9 @@ The following software have components provided under the terms of this license: - JBoss Marshalling River (from https://repo1.maven.org/maven2/org/jboss/marshalling/jboss-marshalling-river) - JCIP Annotations under Apache License (from http://stephenc.github.com/jcip-annotations) - JHeaps (from http://www.jheaps.org) +- JJWT :: API (from https://repo1.maven.org/maven2/io/jsonwebtoken/jjwt-api) +- JJWT :: Extensions :: Jackson (from https://repo1.maven.org/maven2/io/jsonwebtoken/jjwt-jackson) +- JJWT :: Impl (from https://repo1.maven.org/maven2/io/jsonwebtoken/jjwt-impl) - JJWT :: Legacy Transitive Dependency Jar (from https://repo1.maven.org/maven2/io/jsonwebtoken/jjwt) - JMES Path Query library (from https://aws.amazon.com/sdkforjava) - JSON Small and Fast Parser (from https://repo1.maven.org/maven2/net/minidev/json-smart, https://urielch.github.io/) @@ -615,7 +618,6 @@ MIT The following software have components provided under the terms of this license: - Animal Sniffer Annotations (from https://repo1.maven.org/maven2/org/codehaus/mojo/animal-sniffer-annotations) -- Apache HttpClient Cache (from http://hc.apache.org/httpcomponents-client, http://hc.apache.org/httpcomponents-client-ga) - Azure Java Client Authentication Library for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java) - Azure Java Client Runtime for ARM (from https://github.com/Azure/autorest-clientruntime-for-java) - Azure Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java) @@ -743,6 +745,5 @@ unknown The following software have components provided under the terms of this license: - btf (from https://github.com/java-json-tools/btf) -- jackson-coreutils (from https://github.com/java-json-tools/jackson-coreutils) - json-patch (from https://github.com/fge/json-patch, https://github.com/java-json-tools/json-patch) - msg-simple (from https://github.com/java-json-tools/msg-simple) diff --git a/pom.xml b/pom.xml index 7c7621b2c04513b286607560f1f4f5844608e23b..9ab18cdc0b2cc6b5553e3f6b87f1875f2b869719 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ <maven.compiler.source>17</maven.compiler.source> <docker.image.prefix>opendes</docker.image.prefix> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <os-core-common-spring6.version>0.26.0</os-core-common-spring6.version> + <os-core-common-spring6.version>0.27.0-SNAPSHOT</os-core-common-spring6.version> <netty.version>4.1.51.Final</netty.version> <snakeyaml.version>2.0</snakeyaml.version> <commons-codec.version>1.14</commons-codec.version> diff --git a/provider/storage-aws/pom.xml b/provider/storage-aws/pom.xml index a1a2a32c0fcc899df1dbc850b1826247ef2a989c..93c3c85626294ef59a4fc4f99dbdbf6ba6dda2f8 100644 --- a/provider/storage-aws/pom.xml +++ b/provider/storage-aws/pom.xml @@ -70,6 +70,23 @@ </exclusions> </dependency> <!-- Third party Apache 2.0 license packages --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-autoconfigure</artifactId> + <version>${spring-boot.version}</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-tomcat</artifactId> + <version>${spring-boot.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + <version>${spring-framework-version}</version> + </dependency> + + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> diff --git a/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/CloudStorageImpl.java b/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/CloudStorageImpl.java index 82b1a8411a41a5829b9c04bb5509f290e09ddc1f..df3726211fb0b8a85dadb975b02be59c36c0f35c 100644 --- a/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/CloudStorageImpl.java +++ b/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/CloudStorageImpl.java @@ -24,6 +24,7 @@ import org.opengroup.osdu.core.common.model.storage.RecordData; import org.opengroup.osdu.core.common.model.storage.RecordMetadata; import org.opengroup.osdu.core.common.model.storage.RecordProcessing; import org.opengroup.osdu.core.common.model.storage.TransferInfo; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.provider.aws.security.UserAccessService; import org.opengroup.osdu.storage.provider.aws.util.WorkerThreadPool; import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; @@ -35,7 +36,6 @@ import org.opengroup.osdu.storage.provider.aws.util.s3.S3RecordClient; import org.apache.http.HttpStatus; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.springframework.stereotype.Repository; import static org.apache.commons.codec.binary.Base64.encodeBase64; @@ -235,14 +235,14 @@ public class CloudStorageImpl implements ICloudStorage { if (!id.equalsIgnoreCase(idWithVersion)) { long previousVersion = Long.parseLong(idWithVersion.split(":")[3]); - long currentVersion = currentRecords.get(CollaborationUtil.getIdWithNamespace(id, collaborationContext)).getLatestVersion(); + long currentVersion = currentRecords.get(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)).getLatestVersion(); if (previousVersion != currentVersion) { lockedRecords.add(idWithVersion); continue; } } validMetadata.add(recordMetadata); - originalAcls.put(recordMetadata.getId(), currentRecords.get(CollaborationUtil.getIdWithNamespace(id, collaborationContext)).getAcl()); + originalAcls.put(recordMetadata.getId(), currentRecords.get(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)).getAcl()); } return originalAcls; } diff --git a/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/MessageBusImpl.java b/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/MessageBusImpl.java index 5c2ac3fdfe286ae39ec55a7ee31b30de435e7c46..0baa251b7d946020efbaae230fe2fe0c120bd6d8 100644 --- a/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/MessageBusImpl.java +++ b/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/MessageBusImpl.java @@ -14,6 +14,7 @@ package org.opengroup.osdu.storage.provider.aws; +import com.amazonaws.services.sns.model.MessageAttributeValue; import com.amazonaws.services.sns.model.PublishRequest; import org.apache.commons.lang3.NotImplementedException; import org.opengroup.osdu.core.aws.ssm.K8sLocalParameterProvider; @@ -36,6 +37,7 @@ import jakarta.inject.Inject; import java.util.Arrays; import java.util.List; +import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -43,6 +45,7 @@ import java.util.Optional; public class MessageBusImpl implements IMessageBus { private String amazonSNSTopic; + private String amazonSNSTopicV2; private AmazonSNS snsClient; @Value("${AWS.REGION}") private String currentRegion; @@ -50,35 +53,61 @@ public class MessageBusImpl implements IMessageBus { @Value("${OSDU_TOPIC}") private String osduStorageTopic; + @Value("${OSDU_TOPIC_V2}") + private String osduStorageTopicV2; + @Inject private JaxRsDpsLog logger; + private <T> void doPublishMessage(boolean v2Message, Optional<CollaborationContext> collaborationContext, DpsHeaders headers, T... messages) { + final int BATCH_SIZE = 50; + PublishRequestBuilder<T> publishRequestBuilder = new PublishRequestBuilder<>(); + publishRequestBuilder.setGeneralParametersFromHeaders(headers); + logger.info("Storage publishes message " + headers.getCorrelationId()); + for (int i =0; i < messages.length; i+= BATCH_SIZE){ + + T[] batch = Arrays.copyOfRange(messages, i, Math.min(messages.length, i + BATCH_SIZE)); + + Map<String, MessageAttributeValue> additionalAttrs = new HashMap<>(); + String messageSNSTopic; + String messageOsduTopic; + + if (v2Message) { + if (collaborationContext.isPresent()) { + additionalAttrs.put(DpsHeaders.COLLABORATION, getAttrValForContext(collaborationContext.get())); + } + messageOsduTopic = osduStorageTopicV2; //records-changed-v2 + messageSNSTopic = amazonSNSTopicV2; + } else { + messageOsduTopic = osduStorageTopic; + messageSNSTopic = amazonSNSTopic; + } + PublishRequest publishRequest = publishRequestBuilder.generatePublishRequest(messageOsduTopic, messageSNSTopic, Arrays.asList(batch), additionalAttrs); + + snsClient.publish(publishRequest); + } + } + + private static MessageAttributeValue getAttrValForContext(CollaborationContext collaborationContext) { + return new MessageAttributeValue().withDataType("String").withStringValue("id=" + collaborationContext.getId() + ",application=" + collaborationContext.getApplication()); + } + @PostConstruct public void init() throws K8sParameterNotFoundException { K8sLocalParameterProvider provider = new K8sLocalParameterProvider(); amazonSNSTopic = provider.getParameterAsString("storage-sns-topic-arn"); + amazonSNSTopicV2 = provider.getParameterAsString("storage-v2-sns-topic-arn"); snsClient = new AmazonSNSConfig(currentRegion).AmazonSNS(); } @Override public void publishMessage(DpsHeaders headers, PubSubInfo... messages) { - final int BATCH_SIZE = 50; - PublishRequestBuilder<PubSubInfo> publishRequestBuilder = new PublishRequestBuilder<>(); - publishRequestBuilder.setGeneralParametersFromHeaders(headers); - logger.info("Storage publishes message " + headers.getCorrelationId()); - for (int i = 0; i < messages.length; i += BATCH_SIZE) { - - PubSubInfo[] batch = Arrays.copyOfRange(messages, i, Math.min(messages.length, i + BATCH_SIZE)); - - PublishRequest publishRequest = publishRequestBuilder.generatePublishRequest(osduStorageTopic, amazonSNSTopic, Arrays.asList(batch)); - - snsClient.publish(publishRequest); - } + doPublishMessage(false,Optional.empty(), headers, messages); } @Override public void publishMessage(Optional<CollaborationContext> collaborationContext, DpsHeaders headers, RecordChangedV2... messages) { - // To be implemented by aws provider + doPublishMessage(true, collaborationContext, headers, messages); } @Override diff --git a/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/RecordsMetadataRepositoryImpl.java b/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/RecordsMetadataRepositoryImpl.java index b5cd9994c13db57a3fc5fe1e7d7f8a9e916aff22..fe9b24bc76e48e21a8a25a033a2bee4509194cc0 100644 --- a/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/RecordsMetadataRepositoryImpl.java +++ b/provider/storage-aws/src/main/java/org/opengroup/osdu/storage/provider/aws/RecordsMetadataRepositoryImpl.java @@ -31,7 +31,7 @@ import org.opengroup.osdu.storage.provider.aws.util.WorkerThreadPool; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; import org.opengroup.osdu.storage.provider.aws.util.dynamodb.LegalTagAssociationDoc; import org.opengroup.osdu.storage.provider.aws.util.dynamodb.RecordMetadataDoc; -import org.opengroup.osdu.storage.util.CollaborationUtil; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Repository; @@ -49,7 +49,7 @@ import java.util.stream.Collectors; @ConditionalOnProperty(prefix = "repository", name = "implementation", havingValue = "dynamodb", matchIfMissing = true) @Repository -public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository<String> { +public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository<String> { @Inject private DpsHeaders headers; @@ -81,7 +81,7 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository RecordMetadataDoc doc = new RecordMetadataDoc(); // Set the core fields (what is expected in every implementation) - doc.setId(CollaborationUtil.getIdWithNamespace(metadata.getId(), collaborationContext)); + doc.setId(CollaborationContextUtil.composeIdWithNamespace(metadata.getId(), collaborationContext)); doc.setMetadata(metadata); // Add extra indexed fields for querying in DynamoDB doc.setKind(metadata.getKind()); @@ -90,7 +90,7 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository doc.setUser(metadata.getUser()); // Store the record to the database metadataDocs.add(doc); - saveLegalTagAssociation(CollaborationUtil.getIdWithNamespace(metadata.getId(), collaborationContext), + saveLegalTagAssociation(CollaborationContextUtil.composeIdWithNamespace(metadata.getId(), collaborationContext), metadata.getLegal().getLegaltags(), legalDocs); } @@ -159,7 +159,7 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error", "Could not save record metadata", firstFailedException); } } - + @Override public List<RecordMetadata> createOrUpdate(List<RecordMetadata> recordsMetadata, Optional<CollaborationContext> collaborationContext) { if (recordsMetadata != null) { @@ -177,9 +177,9 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository RecordMetadata rmd = get(id,collaborationContext); DynamoDBQueryHelperV2 recordMetadataQueryHelper = getRecordMetadataQueryHelper(); recordMetadataQueryHelper.deleteByPrimaryKey(RecordMetadataDoc.class, - CollaborationUtil.getIdWithNamespace(id, collaborationContext)); + CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)); for (String legalTag : rmd.getLegal().getLegaltags()) { - deleteLegalTagAssociation(CollaborationUtil.getIdWithNamespace(id, collaborationContext), legalTag); + deleteLegalTagAssociation(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext), legalTag); } } @@ -187,7 +187,7 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository public RecordMetadata get(String id, Optional<CollaborationContext> collaborationContext) { DynamoDBQueryHelperV2 recordMetadataQueryHelper = getRecordMetadataQueryHelper(); RecordMetadataDoc doc = recordMetadataQueryHelper.loadByPrimaryKey(RecordMetadataDoc.class, - CollaborationUtil.getIdWithNamespace(id, collaborationContext)); + CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)); if (doc == null) { return null; } else { @@ -197,11 +197,11 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository @Override public Map<String, RecordMetadata> get(List<String> ids, Optional<CollaborationContext> collaborationContext) { - + DynamoDBQueryHelperV2 recordMetadataQueryHelper = getRecordMetadataQueryHelper(); - + Map<String, RecordMetadata> output = new HashMap<>(); - Set<String> filteredIds = ids.stream().map(id -> CollaborationUtil.getIdWithNamespace(id, collaborationContext)).collect(Collectors.toSet()); + Set<String> filteredIds = ids.stream().map(id -> CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)).collect(Collectors.toSet()); Lists.partition(filteredIds.stream().toList(), MAX_DYNAMODB_READ_BATCH_SIZE) .stream() .map(recordIds -> recordMetadataQueryHelper.batchLoadByPrimaryKey(RecordMetadataDoc.class, new HashSet<>(recordIds))) @@ -222,7 +222,7 @@ public class RecordsMetadataRepositoryImpl implements IRecordsMetadataRepository String legalTagName, int limit, String cursor) { DynamoDBQueryHelperV2 legalTagQueryHelper = getLegalTagQueryHelper(); - + LegalTagAssociationDoc legalTagAssociationDoc = new LegalTagAssociationDoc(); legalTagAssociationDoc.setLegalTag(legalTagName); QueryPageResult<LegalTagAssociationDoc> result = null; diff --git a/provider/storage-aws/src/main/resources/application.properties b/provider/storage-aws/src/main/resources/application.properties index 622f233db92cd837a4fc73854c1a9805e3f38ac1..c0989901cbf4363f1792fd7ef8960efec9a1d88b 100644 --- a/provider/storage-aws/src/main/resources/application.properties +++ b/provider/storage-aws/src/main/resources/application.properties @@ -72,6 +72,7 @@ aws.elasticache.cluster.port=${CACHE_CLUSTER_PORT:null} aws.elasticache.cluster.key=${CACHE_CLUSTER_KEY:null} OSDU_TOPIC=${OSDU_STORAGE_TOPIC:records-changed} +OSDU_TOPIC_V2=${OSDU_STORAGE_TOPIC_V2:records-changed-v2} # values mongo/dinamo for choose any condition from implementation repository.implementation=${STORAGE_SERVICE_REPOSITORY_IMPLEMENTATION:dynamodb} diff --git a/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/MessageBusImplTest.java b/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/MessageBusImplTest.java index 7dbc7f249fe6c28020283efbbd1e988d5fad1e19..90eac930d88a5282bc8e7431478c9a54d0b241c5 100644 --- a/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/MessageBusImplTest.java +++ b/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/MessageBusImplTest.java @@ -18,27 +18,34 @@ import com.amazonaws.services.sns.AmazonSNS; import com.amazonaws.services.sns.model.MessageAttributeValue; import com.amazonaws.services.sns.model.PublishRequest; import com.amazonaws.services.sns.model.PublishResult; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.junit.jupiter.api.BeforeEach; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; +import org.junit.jupiter.api.Test; +import org.mockito.*; +import org.opengroup.osdu.core.aws.sns.AmazonSNSConfig; +import org.opengroup.osdu.core.aws.ssm.K8sLocalParameterProvider; +import org.opengroup.osdu.core.aws.ssm.K8sParameterNotFoundException; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.CollaborationContext; import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.indexer.OperationType; -import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; import org.opengroup.osdu.core.common.model.storage.PubSubInfo; +import org.opengroup.osdu.storage.model.RecordChangedV2; +import org.opengroup.osdu.storage.provider.aws.util.CollaborationContextTestUtil; import java.util.Map; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; -class MessageBusImplTest { +public class MessageBusImplTest { + + private final static String AWS_SNS_TOPIC = "storage_sqs_url"; + private final static String AWS_SNS_TOPIC_V2 = "storage_sqs_url_v2"; @InjectMocks private MessageBusImpl messageBus; @@ -52,11 +59,26 @@ class MessageBusImplTest { @Captor private ArgumentCaptor<PublishRequest> publishRequestCaptor; + @BeforeEach - void setUp() { + void setUp() throws K8sParameterNotFoundException { openMocks(this); } + private void initAndRun(Runnable runnable) throws K8sParameterNotFoundException { + try (MockedConstruction<K8sLocalParameterProvider> provider = Mockito.mockConstruction(K8sLocalParameterProvider.class, (mock, context) -> { + when(mock.getParameterAsString("storage-sns-topic-arn")).thenReturn(AWS_SNS_TOPIC); + when(mock.getParameterAsString("storage-v2-sns-topic-arn")).thenReturn(AWS_SNS_TOPIC_V2); + })) { + try (MockedConstruction<AmazonSNSConfig> config = Mockito.mockConstruction(AmazonSNSConfig.class, (mock1, context) -> { + when(mock1.AmazonSNS()).thenReturn(snsClient); + })) { + messageBus.init(); + runnable.run(); + } + } + } + private void assertMessageHasAttributes(PublishRequest message, String key, String value) { Map<String, MessageAttributeValue> attrMap = message.getMessageAttributes(); MessageAttributeValue messageAttr = attrMap.get(key); @@ -65,32 +87,77 @@ class MessageBusImplTest { assertEquals(value, messageAttr.getStringValue()); } + private void assertMessageDoesNotHaveAttributes(PublishRequest message, String key) { + Map<String, MessageAttributeValue> attrMap = message.getMessageAttributes(); + MessageAttributeValue messageAttr = attrMap.get(key); + assertEquals(null, messageAttr); + } + + @Test + public void publishMessageOutsideForRecordNotOnNamespace() throws K8sParameterNotFoundException { + initAndRun(() -> { + // arrange + DpsHeaders headers = new DpsHeaders(); + PubSubInfo message = new PubSubInfo(); + message.setKind("common:welldb:wellbore:1.0.12311"); + message.setOp(OperationType.create_schema); + + PubSubInfo[] messages = new PubSubInfo[1]; + messages[0] = message; + Mockito.when(snsClient.publish(publishRequestCaptor.capture())) + .thenReturn(any(PublishResult.class)); + + // act + messageBus.publishMessage(headers, messages); + + // assert + Mockito.verify(snsClient, Mockito.times(1)).publish(any(PublishRequest.class)); + + PublishRequest receivedRequest = publishRequestCaptor.getValue(); + + assertEquals(AWS_SNS_TOPIC, receivedRequest.getTopicArn()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.ACCOUNT_ID, headers.getPartitionIdWithFallbackToAccountId()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.DATA_PARTITION_ID, headers.getPartitionIdWithFallbackToAccountId()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.CORRELATION_ID, headers.getCorrelationId()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.USER_EMAIL, headers.getUserEmail()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.AUTHORIZATION, headers.getAuthorization()); + assertMessageDoesNotHaveAttributes(receivedRequest, DpsHeaders.COLLABORATION); + + } + ); + } + @Test - void publishMessage() { - // arrange - String amazonSNSTopic = null; - DpsHeaders headers = new DpsHeaders(); - PubSubInfo message = new PubSubInfo(); - message.setKind("common:welldb:wellbore:1.0.12311"); - message.setOp(OperationType.create_schema); - - PubSubInfo[] messages = new PubSubInfo[1]; - messages[0] = message; - Mockito.when(snsClient.publish(publishRequestCaptor.capture())) - .thenReturn(any(PublishResult.class)); - - // act - messageBus.publishMessage(headers, messages); - - // assert - Mockito.verify(snsClient, Mockito.times(1)).publish(any(PublishRequest.class)); - - PublishRequest receivedRequest = publishRequestCaptor.getValue(); - - assertMessageHasAttributes(receivedRequest, DpsHeaders.ACCOUNT_ID, headers.getPartitionIdWithFallbackToAccountId()); - assertMessageHasAttributes(receivedRequest, DpsHeaders.DATA_PARTITION_ID, headers.getPartitionIdWithFallbackToAccountId()); - assertMessageHasAttributes(receivedRequest, DpsHeaders.CORRELATION_ID, headers.getCorrelationId()); - assertMessageHasAttributes(receivedRequest, DpsHeaders.USER_EMAIL, headers.getUserEmail()); - assertMessageHasAttributes(receivedRequest, DpsHeaders.AUTHORIZATION, headers.getAuthorization()); + public void publishMessageForRecordOnNamespace() throws K8sParameterNotFoundException { + initAndRun(() -> { + // arrange + DpsHeaders headers = new DpsHeaders(); + RecordChangedV2 message = new RecordChangedV2(); + message.setKind("common:welldb:wellbore:1.0.12311"); + message.setOp(OperationType.create_schema); + + RecordChangedV2[] messages = new RecordChangedV2[1]; + messages[0] = message; + Mockito.when(snsClient.publish(publishRequestCaptor.capture())) + .thenReturn(any(PublishResult.class)); + // act + final CollaborationContext collaborationContext = CollaborationContextTestUtil.getACollaborationContext(); + final String collaborationContextString = String.format("id=%s,application=%s", collaborationContext.getId(), collaborationContext.getApplication()); + + messageBus.publishMessage(Optional.of(collaborationContext), headers, messages); + + // assert + Mockito.verify(snsClient, Mockito.times(1)).publish(any(PublishRequest.class)); + + PublishRequest receivedRequest = publishRequestCaptor.getValue(); + + assertEquals(AWS_SNS_TOPIC_V2, receivedRequest.getTopicArn()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.ACCOUNT_ID, headers.getPartitionIdWithFallbackToAccountId()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.DATA_PARTITION_ID, headers.getPartitionIdWithFallbackToAccountId()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.CORRELATION_ID, headers.getCorrelationId()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.USER_EMAIL, headers.getUserEmail()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.AUTHORIZATION, headers.getAuthorization()); + assertMessageHasAttributes(receivedRequest, DpsHeaders.COLLABORATION, collaborationContextString); + }); } } diff --git a/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/util/CollaborationContextTestUtil.java b/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/util/CollaborationContextTestUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..9ff0220829ea153e8ae11377e560032af52d8ef4 --- /dev/null +++ b/provider/storage-aws/src/test/java/org/opengroup/osdu/storage/provider/aws/util/CollaborationContextTestUtil.java @@ -0,0 +1,16 @@ +package org.opengroup.osdu.storage.provider.aws.util; + +import org.opengroup.osdu.core.common.model.http.CollaborationContext; + +import java.util.Collections; +import java.util.UUID; + +public class CollaborationContextTestUtil { + + public static CollaborationContext getACollaborationContext() { + final UUID id = UUID.randomUUID(); + final String application = "application"; + return new CollaborationContext(id, application, Collections.emptyMap()); + } + +} diff --git a/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/CloudStorageImpl.java b/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/CloudStorageImpl.java index 38915e34fc24f3d4ede2e551d26d7c06e605907f..bbc4124801816ad5fb9a8eeb094ca9aac8a9c0d2 100644 --- a/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/CloudStorageImpl.java +++ b/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/CloudStorageImpl.java @@ -27,12 +27,12 @@ import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.http.CollaborationContext; import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.storage.*; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.provider.azure.repository.GroupsInfoRepository; import org.opengroup.osdu.storage.provider.azure.repository.RecordMetadataRepository; import org.opengroup.osdu.storage.provider.azure.util.EntitlementsHelper; import org.opengroup.osdu.storage.provider.azure.util.RecordUtil; import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.opengroup.osdu.storage.util.CrcHashGenerator; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; @@ -108,7 +108,7 @@ public class CloudStorageImpl implements ICloudStorage { // validate that updated metadata has the same version if (!id.equalsIgnoreCase(idWithVersion)) { long previousVersion = Long.parseLong(idWithVersion.split(":")[3]); - long currentVersion = currentRecords.get(CollaborationUtil.getIdWithNamespace(id, collaborationContext)).getLatestVersion(); + long currentVersion = currentRecords.get(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)).getLatestVersion(); // if version is different, do not update if (previousVersion != currentVersion) { lockedRecords.add(idWithVersion); @@ -116,7 +116,7 @@ public class CloudStorageImpl implements ICloudStorage { } } validMetadata.add(recordMetadata); - originalAcls.put(recordMetadata.getId(), currentRecords.get(CollaborationUtil.getIdWithNamespace(id, collaborationContext)).getAcl()); + originalAcls.put(recordMetadata.getId(), currentRecords.get(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)).getAcl()); } return originalAcls; } @@ -284,7 +284,7 @@ public class CloudStorageImpl implements ICloudStorage { String dataPartitionId = headers.getPartitionId(); for (String recordId : recordIds) { - RecordMetadata recordMetadata = recordsMetadata.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)); + RecordMetadata recordMetadata = recordsMetadata.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)); if (!entitlementsHelper.hasViewerAccessToRecord(recordMetadata)) { continue; } diff --git a/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/repository/RecordMetadataRepository.java b/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/repository/RecordMetadataRepository.java index 37b1a65d0860577841f20ace7a222882c4b41de1..ce2f82627724ec129ff3ac935983898a5e44e9e1 100644 --- a/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/repository/RecordMetadataRepository.java +++ b/provider/storage-azure/src/main/java/org/opengroup/osdu/storage/provider/azure/repository/RecordMetadataRepository.java @@ -34,11 +34,11 @@ import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.legal.LegalCompliance; import org.opengroup.osdu.core.common.model.storage.RecordMetadata; import org.opengroup.osdu.storage.provider.azure.model.RecordMetadataDoc; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.provider.azure.di.AzureBootstrapConfig; import org.opengroup.osdu.storage.provider.azure.di.CosmosContainerConfig; import org.opengroup.osdu.storage.provider.azure.model.DocumentCount; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -108,7 +108,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record modifyUser = recordMetadata.getModifyUser(); modifyTime = recordMetadata.getModifyTime(); cosmosPatchOperations = getCosmosPatchOperations(modifyUser, modifyTime, jsonPatchPerRecordEntry.getValue()); - String docId = CollaborationUtil.getIdWithNamespace(recordMetadata.getId(), collaborationContext); + String docId = CollaborationContextUtil.composeIdWithNamespace(recordMetadata.getId(), collaborationContext); cosmosPatchOperationsPerDoc.put(docId, cosmosPatchOperations); partitionKeyForDoc.put(docId, recordMetadata.getId()); } @@ -121,7 +121,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record for (String cosmosError : originalExceptionErrors) { String[] idAndError = cosmosError.split("\\|"); //assuming azure library throws an error in the format of "recordId|<message with responseCode>|<exception>" - recordIdToError.put(CollaborationUtil.getIdWithoutNamespace(idAndError[0], collaborationContext), idAndError[1]); + recordIdToError.put(CollaborationContextUtil.getIdWithoutNamespace(idAndError[0], collaborationContext), idAndError[1]); } } else { throw e; @@ -155,7 +155,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record private void createOrUpdateSerial(List<RecordMetadata> recordsMetadata, Optional<CollaborationContext> collaborationContext) { for (RecordMetadata recordMetadata : recordsMetadata) { RecordMetadataDoc doc = new RecordMetadataDoc(); - doc.setId(CollaborationUtil.getIdWithNamespace(recordMetadata.getId(), collaborationContext)); + doc.setId(CollaborationContextUtil.composeIdWithNamespace(recordMetadata.getId(), collaborationContext)); doc.setMetadata(recordMetadata); this.save(doc); } @@ -171,7 +171,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record List<String> partitionKeys = new ArrayList<>(); for (RecordMetadata recordMetadata : recordsMetadata) { RecordMetadataDoc doc = new RecordMetadataDoc(); - doc.setId(CollaborationUtil.getIdWithNamespace(recordMetadata.getId(), collaborationContext)); + doc.setId(CollaborationContextUtil.composeIdWithNamespace(recordMetadata.getId(), collaborationContext)); doc.setMetadata(recordMetadata); docs.add(doc); partitionKeys.add(recordMetadata.getId()); @@ -182,7 +182,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record @Override public RecordMetadata get(String id, Optional<CollaborationContext> collaborationContext) { - RecordMetadataDoc item = this.getOne(CollaborationUtil.getIdWithNamespace(id, collaborationContext)); + RecordMetadataDoc item = this.getOne(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)); return (item == null) ? null : item.getMetadata(); } @@ -272,7 +272,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record if (!collaborationContext.isPresent()) { queryText = String.format("SELECT c.metadata.id FROM c WHERE c.metadata.kind = '%s' AND c.metadata.status = '%s' AND c.id = c.metadata.id", kind, status); } else { - queryText = String.format("SELECT c.metadata.id FROM c WHERE c.metadata.kind = '%s' AND c.metadata.status = '%s' and STARTSWITH(c.id, '%s')", kind, status, CollaborationUtil.getNamespace(collaborationContext)); + queryText = String.format("SELECT c.metadata.id FROM c WHERE c.metadata.kind = '%s' AND c.metadata.status = '%s' and STARTSWITH(c.id, '%s')", kind, status, CollaborationContextUtil.getNamespace(collaborationContext)); } return new SqlQuerySpec(queryText); } @@ -291,7 +291,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record @Override public void delete(String id, Optional<CollaborationContext> collaborationContext) { - this.deleteById(CollaborationUtil.getIdWithNamespace(id, collaborationContext), headers.getPartitionId(), cosmosDBName, recordMetadataCollection, CollaborationUtil.getIdWithNamespace(id, collaborationContext)); + this.deleteById(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext), headers.getPartitionId(), cosmosDBName, recordMetadataCollection, CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)); } /** @@ -304,7 +304,7 @@ public class RecordMetadataRepository extends SimpleCosmosStoreRepository<Record StringBuilder sb = new StringBuilder(); sb.append("SELECT * FROM c WHERE c.id IN ("); for (String id : ids) { - sb.append("\"" + CollaborationUtil.getIdWithNamespace(id, collaborationContext) + "\","); + sb.append("\"" + CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext) + "\","); } // remove trailing comma, add closing parenthesis diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/service/BatchServiceImpl.java b/storage-core/src/main/java/org/opengroup/osdu/storage/service/BatchServiceImpl.java index fe4c594a00a17b376a4ecc92e0260a880f63e2fe..82a10bcbd2057ec4d9ec976c5a662d0dc07fd61a 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/service/BatchServiceImpl.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/service/BatchServiceImpl.java @@ -28,13 +28,13 @@ import org.opengroup.osdu.core.common.model.indexer.OperationType; import org.opengroup.osdu.core.common.model.storage.Record; import org.opengroup.osdu.core.common.model.storage.*; import org.opengroup.osdu.core.common.storage.PersistenceHelper; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.conversion.DpsConversionService; import org.opengroup.osdu.storage.logging.StorageAuditLogger; import org.opengroup.osdu.storage.opa.model.ValidationOutputRecord; import org.opengroup.osdu.storage.opa.service.IOPAService; import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.springframework.beans.factory.annotation.Autowired; import java.util.*; @@ -91,7 +91,7 @@ public abstract class BatchServiceImpl implements BatchService { Map<String, RecordMetadata> recordsMetadata = this.recordRepository.get(recordIds, collaborationContext); for (String recordId : recordIds) { - RecordMetadata recordMetadata = recordsMetadata.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)); + RecordMetadata recordMetadata = recordsMetadata.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)); if (recordMetadata == null || !recordMetadata.getStatus().equals(RecordState.active)) { recordsNotFound.add(recordId); @@ -136,7 +136,7 @@ public abstract class BatchServiceImpl implements BatchService { jsonRecord = PersistenceHelper.filterRecordDataFields(jsonRecord, validAttributes); } - RecordMetadata recordMetadata = recordsMetadata.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)); + RecordMetadata recordMetadata = recordsMetadata.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)); JsonObject recordObject = PersistenceHelper.combineRecordMetaDataAndRecordDataIntoJsonObject(jsonRecord, recordMetadata, recordMetadata.getLatestVersion()); Gson gson = new Gson(); @@ -180,7 +180,7 @@ public abstract class BatchServiceImpl implements BatchService { Map<String, RecordMetadata> recordsMetadata = this.recordRepository.get(recordIds, collaborationContext); for (String recordId : recordIds) { - RecordMetadata recordMetadata = recordsMetadata.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)); + RecordMetadata recordMetadata = recordsMetadata.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)); if (recordMetadata == null || !recordMetadata.getStatus().equals(RecordState.active)) { recordsNotFound.add(recordId); continue; @@ -214,7 +214,7 @@ public abstract class BatchServiceImpl implements BatchService { recordsNotFoundInCloudStorage.add(recordId); } else { JsonElement jsonRecord = jsonParser.parse(recordData); - RecordMetadata recordMetadata = recordsMetadata.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)); + RecordMetadata recordMetadata = recordsMetadata.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)); JsonObject recordJsonObject = PersistenceHelper.combineRecordMetaDataAndRecordDataIntoJsonObject( jsonRecord, recordMetadata, recordMetadata.getLatestVersion()); jsonObjectRecords.add(recordJsonObject); @@ -259,7 +259,7 @@ public abstract class BatchServiceImpl implements BatchService { Map<String, String> recordsMap = new HashMap<>(); List<RecordMetadata> recordMetadataList = new ArrayList<>(); for (Map.Entry<String, String> record : recordsPreAclMap.entrySet()) { - RecordMetadata recordMetadata = recordsMetadata.get(CollaborationUtil.getIdWithNamespace(record.getKey(), collaborationContext)); + RecordMetadata recordMetadata = recordsMetadata.get(CollaborationContextUtil.composeIdWithNamespace(record.getKey(), collaborationContext)); recordMetadataList.add(recordMetadata); } diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/service/BulkUpdateRecordServiceImpl.java b/storage-core/src/main/java/org/opengroup/osdu/storage/service/BulkUpdateRecordServiceImpl.java index 9cc45fd5023142c9ff1f3d621fe3b90722ca05e4..09c3d6fe85e68451ff4b1e794891c0f505928af2 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/service/BulkUpdateRecordServiceImpl.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/service/BulkUpdateRecordServiceImpl.java @@ -22,12 +22,12 @@ import org.opengroup.osdu.core.common.model.storage.PatchOperation; import org.opengroup.osdu.core.common.model.storage.RecordBulkUpdateParam; import org.opengroup.osdu.core.common.model.storage.RecordMetadata; import org.opengroup.osdu.core.common.model.storage.RecordQuery; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.logging.StorageAuditLogger; import org.opengroup.osdu.storage.opa.model.ValidationOutputRecord; import org.opengroup.osdu.storage.opa.service.IOPAService; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; import org.opengroup.osdu.storage.response.BulkUpdateRecordsResponse; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.opengroup.osdu.storage.util.api.RecordUtil; import org.opengroup.osdu.storage.validation.api.PatchOperationValidator; import org.springframework.beans.factory.annotation.Autowired; @@ -106,7 +106,7 @@ public class BulkUpdateRecordServiceImpl implements BulkUpdateRecordService { final long currentTimestamp = clock.millis(); for (String id : idsWithoutVersion) { String idWithVersion = idMap.get(id); - RecordMetadata metadata = existingRecords.get(CollaborationUtil.getIdWithNamespace(id, collaborationContext)); + RecordMetadata metadata = existingRecords.get(CollaborationContextUtil.composeIdWithNamespace(id, collaborationContext)); if (metadata == null) { notFoundRecordIds.add(idWithVersion); diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/service/IngestionServiceImpl.java b/storage-core/src/main/java/org/opengroup/osdu/storage/service/IngestionServiceImpl.java index 38ed6f81df797b9ab71574cb88b50512891e58ba..38a0fabfe5edb7a551f542ca3bef1ed60636200c 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/service/IngestionServiceImpl.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/service/IngestionServiceImpl.java @@ -31,13 +31,13 @@ import org.opengroup.osdu.core.common.model.storage.*; import org.opengroup.osdu.core.common.model.storage.validation.ValidationDoc; import org.opengroup.osdu.core.common.model.tenant.TenantInfo; import org.opengroup.osdu.storage.di.GcsVersionPathLimitationConfig; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.logging.StorageAuditLogger; import org.opengroup.osdu.storage.opa.model.OpaError; import org.opengroup.osdu.storage.opa.model.ValidationOutputRecord; import org.opengroup.osdu.storage.opa.service.IOPAService; import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.opengroup.osdu.storage.util.RecordBlocks; import org.opengroup.osdu.storage.util.api.RecordUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -196,7 +196,7 @@ public class IngestionServiceImpl implements IngestionService { inputRecords.forEach(record -> { RecordData recordData = new RecordData(record); Map<String, String> hash = recordBlocks.hashForRecordData(recordData); - if (!existingRecords.containsKey(CollaborationUtil.getIdWithNamespace(record.getId(), collaborationContext))) { + if (!existingRecords.containsKey(CollaborationContextUtil.composeIdWithNamespace(record.getId(), collaborationContext))) { RecordMetadata recordMetadata = new RecordMetadata(record); recordMetadata.setUser(transfer.getUser()); recordMetadata.setStatus(RecordState.active); @@ -207,7 +207,7 @@ public class IngestionServiceImpl implements IngestionService { } else { recordData.setModifyUser(transfer.getUser()); recordData.setModifyTime(currentTimestamp); - RecordMetadata existingRecordMetadata = existingRecords.get(CollaborationUtil.getIdWithNamespace(record.getId(), collaborationContext)); + RecordMetadata existingRecordMetadata = existingRecords.get(CollaborationContextUtil.composeIdWithNamespace(record.getId(), collaborationContext)); RecordMetadata updatedRecordMetadata = new RecordMetadata(record); if (!existingRecordMetadata.getKind().equalsIgnoreCase(updatedRecordMetadata.getKind())) { updatedRecordMetadata.setPreviousVersionKind(existingRecordMetadata.getKind()); diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/service/PatchRecordsServiceImpl.java b/storage-core/src/main/java/org/opengroup/osdu/storage/service/PatchRecordsServiceImpl.java index 6884da6f8fb107075f589fc0a36f5b8116b1acdd..3187abc3e16b93ac90a156abbb21fbb84b1d5e3e 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/service/PatchRecordsServiceImpl.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/service/PatchRecordsServiceImpl.java @@ -25,13 +25,13 @@ import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.indexer.OperationType; import org.opengroup.osdu.core.common.model.storage.Record; import org.opengroup.osdu.core.common.model.storage.*; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.logging.StorageAuditLogger; import org.opengroup.osdu.storage.opa.model.OpaError; import org.opengroup.osdu.storage.opa.model.ValidationOutputRecord; import org.opengroup.osdu.storage.opa.service.IOPAService; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; import org.opengroup.osdu.storage.response.PatchRecordsResponse; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.opengroup.osdu.storage.util.JsonPatchUtil; import org.opengroup.osdu.storage.util.api.RecordUtil; import org.opengroup.osdu.storage.validation.api.PatchInputValidator; @@ -141,7 +141,7 @@ public class PatchRecordsServiceImpl implements PatchRecordsService { } Map<RecordMetadata, JsonPatch> patchPerRecord = new HashMap<>(); for (String recordId : recordIds) { - RecordMetadata metadata = existingRecords.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)); + RecordMetadata metadata = existingRecords.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)); try { if (metadata == null) { /* diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/service/RecordServiceImpl.java b/storage-core/src/main/java/org/opengroup/osdu/storage/service/RecordServiceImpl.java index 6f1e057550999e68bc844f3effa6ae8f5cd5b928..7a17d57291a1b80605f8b17e9e876b780c6988f6 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/service/RecordServiceImpl.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/service/RecordServiceImpl.java @@ -30,13 +30,13 @@ import org.opengroup.osdu.core.common.model.storage.Record; import org.opengroup.osdu.core.common.model.storage.RecordMetadata; import org.opengroup.osdu.core.common.model.storage.RecordState; import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.exception.DeleteRecordsException; import org.opengroup.osdu.storage.logging.StorageAuditLogger; import org.opengroup.osdu.storage.model.RecordChangedV2Delete; import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; import org.opengroup.osdu.storage.provider.interfaces.IMessageBus; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; -import org.opengroup.osdu.storage.util.CollaborationUtil; import org.opengroup.osdu.storage.util.api.RecordUtil; import org.opengroup.osdu.storage.validation.ValidationDoc; import org.opengroup.osdu.storage.validation.impl.VersionIdsValidator; @@ -295,7 +295,7 @@ public class RecordServiceImpl implements RecordService { Map<String, RecordMetadata> result = this.recordRepository.get(recordIds, collaborationContext); recordIds.stream() - .filter(recordId -> result.get(CollaborationUtil.getIdWithNamespace(recordId, collaborationContext)) == null) + .filter(recordId -> result.get(CollaborationContextUtil.composeIdWithNamespace(recordId, collaborationContext)) == null) .forEach(recordId -> { String msg = String.format("Record with id '%s' not found", recordId); notDeletedRecords.add(new ImmutablePair<>(recordId, msg)); diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/util/CollaborationUtil.java b/storage-core/src/main/java/org/opengroup/osdu/storage/util/CollaborationUtil.java deleted file mode 100644 index 55bfbc7b97a6f2d150bea45fce275f935a43b809..0000000000000000000000000000000000000000 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/util/CollaborationUtil.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.opengroup.osdu.storage.util; - -import org.opengroup.osdu.core.common.model.http.CollaborationContext; - -import java.util.Optional; - -public class CollaborationUtil { - - public static String getIdWithNamespace(String recordId, Optional<CollaborationContext> collaborationContext) { - return !collaborationContext.isPresent() ? recordId : collaborationContext.get().getId() + recordId; - } - - public static String getIdWithoutNamespace(String recordId, Optional<CollaborationContext> collaborationContext) { - return !collaborationContext.isPresent() ? recordId : recordId.substring(collaborationContext.get().getId().length()); - } - - public static String getNamespace(Optional<CollaborationContext> collaborationContext) { - return collaborationContext.isPresent() ? collaborationContext.get().getId() : ""; - } -} diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/util/GlobalExceptionMapper.java b/storage-core/src/main/java/org/opengroup/osdu/storage/util/GlobalExceptionMapper.java index 592b33590965629fff8a51572fb69168adc5c042..447c9db326f803999655019800ce205c43857fd6 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/util/GlobalExceptionMapper.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/util/GlobalExceptionMapper.java @@ -27,9 +27,9 @@ import com.google.gson.JsonPrimitive; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import jakarta.validation.ValidationException; -import javassist.NotFoundException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.opengroup.osdu.core.common.exception.NotFoundException; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.storage.exception.DeleteRecordsException; @@ -205,4 +205,4 @@ public class GlobalExceptionMapper extends ResponseEntityExceptionHandler { return this.getErrorResponse( new AppException(HttpStatus.BAD_REQUEST.value(), "Validation error.",errorMessage)); } -} \ No newline at end of file +} diff --git a/storage-core/src/main/java/org/opengroup/osdu/storage/util/RecordBlocks.java b/storage-core/src/main/java/org/opengroup/osdu/storage/util/RecordBlocks.java index d2a122977964c8adbbed19cde848b9363fc0ce49..f8329e600141d63ce8681366dfd1fb877572b71a 100644 --- a/storage-core/src/main/java/org/opengroup/osdu/storage/util/RecordBlocks.java +++ b/storage-core/src/main/java/org/opengroup/osdu/storage/util/RecordBlocks.java @@ -9,6 +9,7 @@ import org.opengroup.osdu.core.common.model.indexer.OperationType; import org.opengroup.osdu.core.common.model.storage.RecordData; import org.opengroup.osdu.core.common.model.storage.RecordMetadata; import org.opengroup.osdu.core.common.model.storage.RecordProcessing; +import org.opengroup.osdu.core.common.util.CollaborationContextUtil; import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -40,7 +41,7 @@ public class RecordBlocks { for (RecordProcessing x : recordsToProcess) { if (x.getOperationType().equals(OperationType.update)) { String recordBlocksUpdate = ""; - String id = CollaborationUtil.getIdWithNamespace(x.getRecordMetadata().getId(), collaborationContext); + String id = CollaborationContextUtil.composeIdWithNamespace(x.getRecordMetadata().getId(), collaborationContext); RecordMetadata previousRecordMetadata = existingRecords.get(id); Map<String, Integer> previousMetadataCompare = populateHashes(previousRecordMetadata); Map<String, Integer> currentMetadataCompare = populateHashes(x.getRecordMetadata()); diff --git a/storage-core/src/test/java/org/opengroup/osdu/storage/service/IngestionServiceImplTest.java b/storage-core/src/test/java/org/opengroup/osdu/storage/service/IngestionServiceImplTest.java index b6947c863ee24976fdcd197da22a6211c20dc48c..2a8f11a03f808adcfec8add3156144e13db07883 100644 --- a/storage-core/src/test/java/org/opengroup/osdu/storage/service/IngestionServiceImplTest.java +++ b/storage-core/src/test/java/org/opengroup/osdu/storage/service/IngestionServiceImplTest.java @@ -36,6 +36,7 @@ import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException; import org.opengroup.osdu.core.common.model.entitlements.GroupInfo; import org.opengroup.osdu.core.common.model.entitlements.Groups; import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.CollaborationContext; import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.indexer.OperationType; import org.opengroup.osdu.core.common.model.legal.Legal; @@ -53,8 +54,8 @@ import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage; import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository; import org.opengroup.osdu.storage.util.CrcHashGenerator; import org.opengroup.osdu.storage.util.RecordBlocks; +import org.opengroup.osdu.storage.util.RecordTestUtil; import org.opengroup.osdu.storage.util.api.RecordUtil; -import org.springframework.test.util.ReflectionTestUtils; import java.util.*; import java.util.stream.IntStream; @@ -133,12 +134,15 @@ public class IngestionServiceImplTest { private static final String USER = "testuser@gmail.com"; private static final String NEW_USER = "newuser@gmail.com"; private static final String TENANT = "tenant1"; + private static final UUID COLLABORATION_ID =UUID.randomUUID(); private static final String[] VALID_ACL = new String[] { "data.email1@tenant1.gmail.com", "data.test@tenant1.gmail.com" }; private static final String[] INVALID_ACL = new String[] { "data.email1@test.test.com", "data.test@test.test.com" }; private static final String[] NON_OWNER_ACL = new String[] { "data.not_owner@test.test.com" }; private Record record1; private Record record2; + private Record record1inCollaboration; + private Record record2inCollaboration; private List<Record> records; private Acl acl; @@ -174,13 +178,17 @@ public class IngestionServiceImplTest { this.record2.setId(RECORD_ID2); this.record2.setLegal(legal); + this.record1.setAcl(this.acl); + this.record2.setAcl(this.acl); + + this.record1inCollaboration = RecordTestUtil.ofOtherAndCollaboration(record1, COLLABORATION_ID); + this.record2inCollaboration = RecordTestUtil.ofOtherAndCollaboration(record2, COLLABORATION_ID); + + this.records = new ArrayList<>(); this.records.add(this.record1); this.records.add(this.record2); - this.record1.setAcl(this.acl); - this.record2.setAcl(this.acl); - lenient().when(this.tenant.getName()).thenReturn(TENANT); lenient().when(this.authService.hasOwnerAccess(any(),any())).thenReturn(true); recordBlocks = new RecordBlocks(cloudStorage, crcHashGenerator); @@ -251,7 +259,47 @@ public class IngestionServiceImplTest { assertEquals(2, transferInfo.getRecordCount()); ArgumentCaptor<List> ids = ArgumentCaptor.forClass(List.class); - verify(this.recordRepository).get(ids.capture(), any()); + verify(this.recordRepository).get(ids.capture(), eq(Optional.empty())); + + List<String> capturedIds = ids.getValue(); + assertEquals(2, capturedIds.size()); + assertTrue(capturedIds.get(0).startsWith("tenant1:")); + assertTrue(capturedIds.get(1).startsWith("tenant1:")); + + ArgumentCaptor<TransferBatch> transferCaptor = ArgumentCaptor.forClass(TransferBatch.class); + verify(this.persistenceService).persistRecordBatch(transferCaptor.capture(), eq(Optional.empty())); + verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); + + TransferBatch capturedTransfer = transferCaptor.getValue(); + assertEquals(transferInfo, capturedTransfer.getTransferInfo()); + assertEquals(2, capturedTransfer.getRecords().size()); + + // TODO ASSERT VALUES ON RECORD + for (RecordProcessing processing : capturedTransfer.getRecords()) { + if (processing.getRecordMetadata().getKind().equals(KIND_1)) { + assertEquals(OperationType.create, processing.getOperationType()); + } else { + assertEquals(OperationType.create, processing.getOperationType()); + } + } + } + + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void should_createTwoRecordsInCollaboration_when_twoRecordsWithoutIdArePersisted() { + when(this.authService.isValidAcl(any(), any())).thenReturn(true); + this.record1.setId(null); + this.record2.setId(null); + this.acl.setViewers(VALID_ACL); + this.acl.setOwners(VALID_ACL); + + when(this.cloudStorage.hasAccess(new RecordMetadata[] {})).thenReturn(true); + final CollaborationContext collaborationContext = new CollaborationContext(COLLABORATION_ID, "app1", Collections.emptyMap()); + TransferInfo transferInfo = this.sut.createUpdateRecords(false, this.records, USER, Optional.of(collaborationContext)); + assertEquals(Integer.valueOf(2), transferInfo.getRecordCount()); + + ArgumentCaptor<List> ids = ArgumentCaptor.forClass(List.class); + verify(this.recordRepository).get(ids.capture(), eq(Optional.of(collaborationContext))); List<String> capturedIds = ids.getValue(); assertEquals(2, capturedIds.size()); @@ -259,7 +307,7 @@ public class IngestionServiceImplTest { assertTrue(capturedIds.get(1).startsWith("tenant1:")); ArgumentCaptor<TransferBatch> transferCaptor = ArgumentCaptor.forClass(TransferBatch.class); - verify(this.persistenceService).persistRecordBatch(transferCaptor.capture(), any()); + verify(this.persistenceService).persistRecordBatch(transferCaptor.capture(), eq(Optional.of(collaborationContext))); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); TransferBatch capturedTransfer = transferCaptor.getValue(); @@ -329,7 +377,7 @@ public class IngestionServiceImplTest { recordMetadataList.add(existingRecordMetadata1); when(this.authService.hasOwnerAccess(any(), any())).thenReturn(false); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); AppException exception = assertThrows(AppException.class, ()->{ this.sut.createUpdateRecords(false, this.records, USER, Optional.empty()); @@ -340,7 +388,7 @@ public class IngestionServiceImplTest { } - @Test + @Test @SuppressWarnings("unchecked") public void should_updateTwoRecords_when_twoRecordIDsAreAlreadyPresentInDataLake() { when(this.authService.isValidAcl(any(), any())).thenReturn(true); @@ -370,7 +418,7 @@ public class IngestionServiceImplTest { when(this.cloudStorage.hasAccess(output.values().toArray(new RecordMetadata[output.size()]))).thenReturn(true); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); when(this.cloudStorage.read(existingRecordMetadata1, 3L, false)).thenReturn(new Gson().toJson(this.record1)); when(this.cloudStorage.read(existingRecordMetadata2, 5L, false)).thenReturn(new Gson().toJson(this.record2)); @@ -381,7 +429,60 @@ public class IngestionServiceImplTest { ArgumentCaptor<TransferBatch> transfer = ArgumentCaptor.forClass(TransferBatch.class); - verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), any()); + verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), eq(Optional.empty())); + verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); + + TransferBatch input = transfer.getValue(); + + for (RecordProcessing rp : input.getRecords()) { + assertEquals(OperationType.update, rp.getOperationType()); + } + } + + @Test + @SuppressWarnings("unchecked") + public void should_updateTwoRecordsInCollaboration_when_twoRecordIDsAreAlreadyPresentInDataLake() { + when(this.authService.isValidAcl(any(), any())).thenReturn(true); + + this.record1.setId(RECORD_ID1); + this.record2.setId(RECORD_ID2); + this.acl.setViewers(VALID_ACL); + this.acl.setOwners(VALID_ACL); + + RecordMetadata existingRecordMetadata1 = new RecordMetadata(); + existingRecordMetadata1.setUser(NEW_USER); + existingRecordMetadata1.setKind(KIND_1); + existingRecordMetadata1.setStatus(RecordState.active); + existingRecordMetadata1.setAcl(this.acl); + existingRecordMetadata1.setGcsVersionPaths(Lists.newArrayList("path/1", "path/2", "path/3")); + + RecordMetadata existingRecordMetadata2 = new RecordMetadata(); + existingRecordMetadata2.setUser(NEW_USER); + existingRecordMetadata2.setKind(KIND_2); + existingRecordMetadata2.setStatus(RecordState.active); + existingRecordMetadata2.setAcl(acl); + existingRecordMetadata2.setGcsVersionPaths(Lists.newArrayList("path/4", "path/5")); + + Map<String, RecordMetadata> output = new HashMap<>(); + output.put(record1inCollaboration.getId(), existingRecordMetadata1); + output.put(record2inCollaboration.getId(), existingRecordMetadata2); + + final CollaborationContext collaborationContext = new CollaborationContext(COLLABORATION_ID, "app1", Collections.emptyMap()); + + when(this.cloudStorage.hasAccess(output.values().toArray(new RecordMetadata[output.size()]))).thenReturn(true); + + when(this.recordRepository.get(any(List.class), eq(Optional.of(collaborationContext)))).thenReturn(output); + when(this.cloudStorage.read(existingRecordMetadata1, 3L, false)).thenReturn(new Gson().toJson(this.record1)); + when(this.cloudStorage.read(existingRecordMetadata2, 5L, false)).thenReturn(new Gson().toJson(this.record2)); + + TransferInfo transferInfo = this.sut.createUpdateRecords(false, records, USER, Optional.of(collaborationContext)); + assertEquals(USER, transferInfo.getUser()); + assertEquals(Integer.valueOf(2), transferInfo.getRecordCount()); + assertNotNull(transferInfo.getVersion()); + + ArgumentCaptor<TransferBatch> transfer = ArgumentCaptor.forClass(TransferBatch.class); + + verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), eq(Optional.of(collaborationContext))); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); TransferBatch input = transfer.getValue(); @@ -413,7 +514,7 @@ public class IngestionServiceImplTest { when(this.cloudStorage.hasAccess(existingRecordMetadata1)).thenReturn(true); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); when(this.authService.hasOwnerAccess(any(), any())).thenReturn(true); when(this.cloudStorage.read(existingRecordMetadata1, 3L, false)).thenReturn(new Gson().toJson(this.record1)); @@ -425,7 +526,7 @@ public class IngestionServiceImplTest { ArgumentCaptor<TransferBatch> transfer = ArgumentCaptor.forClass(TransferBatch.class); - verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), any()); + verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), eq(Optional.empty())); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); TransferBatch input = transfer.getValue(); @@ -463,7 +564,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, updatedRecordMetadata); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); when(this.cloudStorage.hasAccess(updatedRecordMetadata)).thenReturn(true); Record recordInStorage = new Record(); @@ -476,7 +577,7 @@ public class IngestionServiceImplTest { assertEquals(USER, transferInfo.getUser()); assertEquals(1, transferInfo.getRecordCount()); assertNotNull(transferInfo.getVersion()); - verify(this.persistenceService, times(0)).persistRecordBatch(any(), any()); + verify(this.persistenceService, times(0)).persistRecordBatch(any(), eq(Optional.empty())); } @@ -503,7 +604,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, updatedRecordMetadata); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); when(this.cloudStorage.hasAccess(updatedRecordMetadata)).thenReturn(true); Record recordInStorage = new Record(); @@ -519,7 +620,7 @@ public class IngestionServiceImplTest { assertEquals(USER, transferInfo.getUser()); assertEquals(1, transferInfo.getRecordCount()); assertNotNull(transferInfo.getVersion()); - verify(this.persistenceService, times(0)).persistRecordBatch(any(), any()); + verify(this.persistenceService, times(0)).persistRecordBatch(any(), eq(Optional.empty())); } @Test @@ -569,7 +670,7 @@ public class IngestionServiceImplTest { assertEquals(USER, transferInfo.getUser()); assertEquals(1, transferInfo.getRecordCount()); assertNotNull(transferInfo.getVersion()); - verify(this.persistenceService, times(1)).persistRecordBatch(any(), any()); + verify(this.persistenceService, times(1)).persistRecordBatch(any(), eq(Optional.empty())); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); } @@ -622,7 +723,7 @@ public class IngestionServiceImplTest { assertEquals(USER, transferInfo.getUser()); assertEquals(1, transferInfo.getRecordCount()); assertNotNull(transferInfo.getVersion()); - verify(this.persistenceService, times(1)).persistRecordBatch(any(), any()); + verify(this.persistenceService, times(1)).persistRecordBatch(any(), eq(Optional.empty())); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); } @@ -681,7 +782,7 @@ public class IngestionServiceImplTest { ArgumentCaptor<TransferBatch> captor = ArgumentCaptor.forClass(TransferBatch.class); - verify(this.persistenceService).persistRecordBatch(captor.capture(), any()); + verify(this.persistenceService).persistRecordBatch(captor.capture(), eq(Optional.empty())); TransferBatch batch = captor.getValue(); assertEquals(1, batch.getTransferInfo().getRecordCount()); @@ -711,7 +812,7 @@ public class IngestionServiceImplTest { List<RecordMetadata> recordMetadataList = new ArrayList<>(); recordMetadataList.add(existingRecordMetadata1); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); AppException exception = assertThrows(AppException.class, ()->{ this.sut.createUpdateRecords(false, this.records, USER, Optional.empty()); @@ -743,7 +844,7 @@ public class IngestionServiceImplTest { List<RecordMetadata> recordMetadataList = new ArrayList<>(); recordMetadataList.add(existingRecordMetadata1); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); AppException exception = assertThrows(AppException.class, ()->{ this.sut.createUpdateRecords(false, this.records, USER, Optional.empty()); @@ -771,7 +872,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, existingRecordMetadata1); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); List<OpaError> errors = new ArrayList<>(); errors.add(OpaError.builder().message("User is not authorized to create or update records.").reason("User Unauthorized").code("401").build()); @@ -816,7 +917,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, existingRecordMetadata1); output.put(RECORD_ID2, existingRecordMetadata2); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); ValidationOutputRecord validationOutputRecord1 = ValidationOutputRecord.builder().id(RECORD_ID1).errors(Collections.EMPTY_LIST).build(); ValidationOutputRecord validationOutputRecord2 = ValidationOutputRecord.builder().id(RECORD_ID2).errors(Collections.EMPTY_LIST).build(); @@ -834,7 +935,7 @@ public class IngestionServiceImplTest { ArgumentCaptor<TransferBatch> transfer = ArgumentCaptor.forClass(TransferBatch.class); - verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), any()); + verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), eq(Optional.empty())); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); TransferBatch input = transfer.getValue(); @@ -864,7 +965,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, existingRecordMetadata1); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); List<OpaError> errors = new ArrayList<>(); errors.add(OpaError.builder().message("The user is not authorized to perform this action").reason("Access denied").code("403").build()); @@ -902,7 +1003,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, existingRecordMetadata1); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); List<OpaError> errors = new ArrayList<>(); errors.add(OpaError.builder().message("The user is not authorized to perform this action").reason("Access denied").code("403").build()); @@ -942,7 +1043,7 @@ public class IngestionServiceImplTest { Map<String, RecordMetadata> output = new HashMap<>(); output.put(RECORD_ID1, existingRecordMetadata1); - when(this.recordRepository.get(any(List.class), any())).thenReturn(output); + when(this.recordRepository.get(any(List.class), eq(Optional.empty()))).thenReturn(output); when(this.cloudStorage.read(existingRecordMetadata1, 3L, false)).thenReturn(new Gson().toJson(this.record1)); @@ -953,7 +1054,7 @@ public class IngestionServiceImplTest { ArgumentCaptor<TransferBatch> transfer = ArgumentCaptor.forClass(TransferBatch.class); - verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), any()); + verify(this.persistenceService, times(1)).persistRecordBatch(transfer.capture(), eq(Optional.empty())); verify(this.auditLogger).createOrUpdateRecordsSuccess(any()); TransferBatch input = transfer.getValue(); diff --git a/storage-core/src/test/java/org/opengroup/osdu/storage/util/CollaborationUtilTest.java b/storage-core/src/test/java/org/opengroup/osdu/storage/util/CollaborationUtilTest.java deleted file mode 100644 index 703f38361143718cc73b3128ffe95a9331df283b..0000000000000000000000000000000000000000 --- a/storage-core/src/test/java/org/opengroup/osdu/storage/util/CollaborationUtilTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.opengroup.osdu.storage.util; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opengroup.osdu.core.common.model.http.CollaborationContext; - -import java.util.Optional; -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@ExtendWith(MockitoExtension.class) -public class CollaborationUtilTest { - - private final static String RECORD_ID = "opendes:id:15706318658560"; - @InjectMocks - private CollaborationUtil collaborationUtil; - - @Test - public void shouldGetCorrectIdWithNamespace_IfCollaborationContextIsProvided() { - UUID CollaborationId = UUID.randomUUID(); - CollaborationContext collaborationContext = CollaborationContext.builder().id(CollaborationId).application("unit testing").build(); - - String result = CollaborationUtil.getIdWithNamespace(RECORD_ID, Optional.of(collaborationContext)); - - assertEquals(result, CollaborationId.toString() + RECORD_ID); - } - - @Test - public void shouldGetCorrectIdWithoutNamespace_IfCollaborationContextIsProvided() { - UUID CollaborationId = UUID.randomUUID(); - CollaborationContext collaborationContext = CollaborationContext.builder().id(CollaborationId).application("unit testing").build(); - - String result = CollaborationUtil.getIdWithoutNamespace(collaborationContext.getId() + RECORD_ID, Optional.of(collaborationContext)); - - assertEquals(result, RECORD_ID); - } - - @Test - public void shouldGetOnlyId_IfEmptyCollaborationContextIsProvided_whenGetIdWithNamespace() { - String result = CollaborationUtil.getIdWithNamespace(RECORD_ID, Optional.empty()); - - assertEquals(result, RECORD_ID); - } - - @Test - public void shouldGetOnlyId_IfEmptyCollaborationContextIsProvided_whenGetIdWithoutNamespace() { - String result = CollaborationUtil.getIdWithoutNamespace(RECORD_ID, Optional.empty()); - - assertEquals(result, RECORD_ID); - } -} diff --git a/storage-core/src/test/java/org/opengroup/osdu/storage/util/GlobalExceptionMapperTest.java b/storage-core/src/test/java/org/opengroup/osdu/storage/util/GlobalExceptionMapperTest.java index c975c992f2eef64e08035428ec29647ddfc56d2d..6501cb1602a39223f07ac20a73c5c09ef5c081f2 100644 --- a/storage-core/src/test/java/org/opengroup/osdu/storage/util/GlobalExceptionMapperTest.java +++ b/storage-core/src/test/java/org/opengroup/osdu/storage/util/GlobalExceptionMapperTest.java @@ -17,7 +17,6 @@ package org.opengroup.osdu.storage.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; import jakarta.validation.ValidationException; -import javassist.NotFoundException; import org.apache.http.HttpStatus; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -25,6 +24,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.opengroup.osdu.core.common.exception.NotFoundException; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; import org.opengroup.osdu.core.common.model.http.AppError; import org.opengroup.osdu.core.common.model.http.AppException; @@ -126,4 +126,4 @@ public class GlobalExceptionMapperTest { assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, response.getStatusCodeValue()); } -} \ No newline at end of file +} diff --git a/storage-core/src/test/java/org/opengroup/osdu/storage/util/RecordTestUtil.java b/storage-core/src/test/java/org/opengroup/osdu/storage/util/RecordTestUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..d5102aeeee7856eb69e565a3d22a2938545cbfbc --- /dev/null +++ b/storage-core/src/test/java/org/opengroup/osdu/storage/util/RecordTestUtil.java @@ -0,0 +1,62 @@ +package org.opengroup.osdu.storage.util; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import org.opengroup.osdu.core.common.model.storage.Record; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class RecordTestUtil { + + private RecordTestUtil() { + } + + // Create a record from another record, copying all fields except the id using all-arguments constructor + public static Record ofOtherAndCollaboration(Record other, UUID collaborationId) { + return new Record( + collaborationId.toString()+ other.getId() , + other.getVersion(), + other.getKind(), + other.getAcl(), + other.getLegal(), + cloneData(other.getData()), + other.getAncestry(), + cloneMeta(other.getMeta()), + cloneTags(other.getTags()), + other.getCreateUser(), + other.getCreateTime(), + other.getModifyUser(), + other.getModifyTime() + ); + } + + + private static Map<String, String> cloneTags(Map<String, String> tags) { + if (tags == null) { + return null; + } + return new HashMap<>(tags); + } + + private static Map<String, Object> cloneData(Map<String, Object> data) { + if (data == null) { + return null; + } + String json = new Gson().toJson(data); + return new Gson().fromJson(json, new TypeToken<Map<String, Object>>() { + }.getType()); + } + + private static Map<String, Object>[] cloneMeta(Map<String, Object>[] meta) { + if (meta == null) { + return null; + } + String json = new Gson().toJson(meta); + return new Gson().fromJson(json, new TypeToken<Map<String, Object>>() { + }.getType()); + } + + +} diff --git a/testing/pom.xml b/testing/pom.xml index f5cf359f34f5edb490a74d43b9072c2d74ba09e6..2c03438606571f4636813b22c95e3ca4477e7b4e 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -41,7 +41,7 @@ <properties> <maven.compiler.target>17</maven.compiler.target> <maven.compiler.source>17</maven.compiler.source> - <os-core-common.version>0.26.0</os-core-common.version> + <os-core-common.version>0.27.0-SNAPSHOT</os-core-common.version> <java.version>17</java.version> <log4j.version>2.23.0</log4j.version> <jackson.version>2.16.1</jackson.version> diff --git a/testing/storage-test-core/src/main/java/org/opengroup/osdu/storage/util/EntitlementsUtil.java b/testing/storage-test-core/src/main/java/org/opengroup/osdu/storage/util/EntitlementsUtil.java index e7de29a952bc9b6056fdafaa32ee538e2f32a163..06e747452b67744fbdda4ec88f6bb41ed601c902 100644 --- a/testing/storage-test-core/src/main/java/org/opengroup/osdu/storage/util/EntitlementsUtil.java +++ b/testing/storage-test-core/src/main/java/org/opengroup/osdu/storage/util/EntitlementsUtil.java @@ -22,7 +22,7 @@ import com.google.gson.JsonObject; import java.util.Map; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; -import org.springframework.http.HttpMethod; +import org.opengroup.osdu.core.common.http.HttpRequest; public class EntitlementsUtil { @@ -35,7 +35,7 @@ public class EntitlementsUtil { CloseableHttpResponse response = TestUtils.send( getEntitlementsUrl(), GROUPS_ENDPOINT, - HttpMethod.POST.name(), + HttpRequest.POST, headers, body, "" @@ -49,7 +49,7 @@ public class EntitlementsUtil { CloseableHttpResponse response = TestUtils.send( getEntitlementsUrl(), GROUPS_ENDPOINT, - HttpMethod.DELETE.name(), + HttpRequest.DELETE, headers, "", groupEmail