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