diff --git a/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/CacheConfig.java b/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/CacheConfig.java
index 0e47fceb0c2718a6deb5c59666ea75dd0f3b2c5e..a5d0155a2eee851189ee7736a9df35301b646749 100644
--- a/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/CacheConfig.java
+++ b/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/CacheConfig.java
@@ -65,13 +65,10 @@ public class CacheConfig {
     configurationBuilder.commandTimeout(redisProperties.getTimeOut());
     LettuceClientConfiguration lettuceClientConfiguration = configurationBuilder.build();
 
-    LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(
+    return new LettuceConnectionFactory(
         redisConfiguration,
         lettuceClientConfiguration
     );
-
-    lettuceConnectionFactory.isUseSsl();
-    return lettuceConnectionFactory;
   }
 
   @Bean
diff --git a/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManager.java b/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManager.java
index ab7e558f0a6fb0643da8e3ff6d4f18a4e5c0bdd5..1a7e405665e4504ad0cb028c48b402ab247c4bc0 100644
--- a/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManager.java
+++ b/provider/notification-gc/src/main/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManager.java
@@ -32,7 +32,7 @@ import org.springframework.stereotype.Component;
 public class ExternalSubscriptionsManager {
 
   private final SubscriptionCacheRepo subscriptionCacheRepo;
-  private final RegisterSubscriptionService subscriptionHandler;
+  private final RegisterSubscriptionService subscriptionService;
 
   public void invokeTenantSubscribers(String dataPartitionId) {
     Set<Subscription> members = subscriptionCacheRepo.getDataPartitionSubscribers(dataPartitionId);
@@ -62,7 +62,7 @@ public class ExternalSubscriptionsManager {
   }
 
   private Subscription retrieveSubscriptionFromHandler(String dataPartitionId, String subscriptionId, String topic) {
-    Subscription subscription = subscriptionHandler.getSubscriptionsByNotificationId(dataPartitionId,subscriptionId);
+    Subscription subscription = subscriptionService.getSubscriptionsByNotificationId(dataPartitionId,subscriptionId);
     if (subscription == null) {
       log.debug("Subscription:{} not available in Register. Marking it as not available in cache.", subscriptionId);
       subscriptionCacheRepo.poisonSub(dataPartitionId, topic, subscriptionId);
@@ -77,7 +77,7 @@ public class ExternalSubscriptionsManager {
   }
 
   public void updateSubscription(String dataPartitionId, String subscriptionId) {
-    Subscription subscription = subscriptionHandler.getSubscriptionsByNotificationId(
+    Subscription subscription = subscriptionService.getSubscriptionsByNotificationId(
         dataPartitionId,
         subscriptionId
     );
@@ -89,10 +89,10 @@ public class ExternalSubscriptionsManager {
   }
 
   private void reloadSubscriptionInfoCache(String dataPartitionId) {
-    List<Subscription> fragmentarySubInfos = subscriptionHandler.getAllSubscriptionInfos(
+    List<Subscription> fragmentarySubInfos = subscriptionService.getAllSubscriptionInfos(
         dataPartitionId);
     for (Subscription freagmentedSubscription : fragmentarySubInfos) {
-      Subscription subscription = subscriptionHandler.getSubscriptionsByNotificationId(dataPartitionId, freagmentedSubscription.getNotificationId());
+      Subscription subscription = subscriptionService.getSubscriptionsByNotificationId(dataPartitionId, freagmentedSubscription.getNotificationId());
       if(Objects.isNull(subscription)){
         log.warn("Cannot init cache for sub id:{}. Empty response from Register. Skipping it.", freagmentedSubscription.getNotificationId());
       }else {
diff --git a/provider/notification-gc/src/test/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManagerTest.java b/provider/notification-gc/src/test/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManagerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5ac56aed20c76c5b2302c7940bf7d384c4e31b0
--- /dev/null
+++ b/provider/notification-gc/src/test/java/org/opengroup/osdu/notification/provider/gcp/service/ExternalSubscriptionsManagerTest.java
@@ -0,0 +1,168 @@
+/*
+ *  Copyright 2020-2023 Google LLC
+ *  Copyright 2020-2023 EPAM Systems, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.opengroup.osdu.notification.provider.gcp.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opengroup.osdu.core.common.model.notification.Subscription;
+import org.opengroup.osdu.notification.provider.gcp.repo.SubscriptionCacheRepo;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ExternalSubscriptionsManagerTest {
+
+  public static final String TEST_TENANT = "test-tenant";
+  private static final String TENANT_WO_SUBS = "no-sub-tenant";
+  public static final String TEST_TOPIC = "topic";
+  public static final String TEST_NOTIF_ID = "test-id";
+
+  @InjectMocks
+  private ExternalSubscriptionsManager manager;
+  @Mock
+  private SubscriptionCacheRepo mockSubCacheRepo;
+  @Mock
+  private RegisterSubscriptionService mockSubService;
+
+  private Subscription subscription;
+
+  private Set<Subscription> subscriptions;
+
+  @Before
+  public void setUp() {
+    subscription = new Subscription();
+    subscription.setNotificationId(TEST_NOTIF_ID);
+    subscription.setTopic(TEST_TOPIC);
+
+    subscriptions = new HashSet<>() {{
+      add(subscription);
+    }};
+  }
+
+  @Test
+  public void testInvokeTenantSubscribers_noActiveSubs() {
+    when(mockSubCacheRepo.getDataPartitionSubscribers(TENANT_WO_SUBS)).thenReturn(
+        Collections.emptySet());
+    manager.invokeTenantSubscribers(TENANT_WO_SUBS);
+    verify(mockSubCacheRepo, times(0)).writeSubscription(anyString(), any());
+    verify(mockSubService, times(1)).getAllSubscriptionInfos(TENANT_WO_SUBS);
+  }
+
+  @Test
+  public void testInvokeTenantSubscribers_withActiveSubs() {
+    when(mockSubCacheRepo.getDataPartitionSubscribers(TEST_TENANT)).thenReturn(subscriptions);
+    manager.invokeTenantSubscribers(TEST_TENANT);
+    verify(mockSubService, times(0)).getAllSubscriptionInfos(TEST_TENANT);
+  }
+
+  @Test
+  public void testInvokeTenantSubscribers_withActiveSubs_emptyCache() {
+    when(mockSubCacheRepo.getDataPartitionSubscribers(TEST_TENANT)).thenReturn(null);
+    when(mockSubService.getAllSubscriptionInfos(TEST_TENANT)).thenReturn(Collections.singletonList(subscription));
+    when(mockSubService.getSubscriptionsByNotificationId(TEST_TENANT, TEST_NOTIF_ID)).thenReturn(subscription);
+
+    manager.invokeTenantSubscribers(TEST_TENANT);
+
+    verify(mockSubService, times(1)).getAllSubscriptionInfos(TEST_TENANT);
+    verify(mockSubCacheRepo, times(1)).writeSubscription(TEST_TENANT, subscription);
+  }
+
+  @Test
+  public void testGetSubscriptionsForTopic() {
+    doReturn(subscriptions).when(mockSubCacheRepo).getTopicSubscribers(TEST_TENANT, TEST_TOPIC);
+    Set<Subscription> actualSubscriptions = manager.getSubscriptionsForTopic(TEST_TENANT,
+        TEST_TOPIC);
+    assertEquals(subscriptions, actualSubscriptions);
+  }
+
+  @Test
+  public void testGetSubscription_inCache() {
+    when(mockSubCacheRepo.readSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID)).thenReturn(
+        subscription);
+    Subscription actualSub = manager.getSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+    assertEquals(subscription, actualSub);
+    verify(mockSubService, times(0)).getSubscriptionsByNotificationId(anyString(), anyString());
+  }
+
+  @Test
+  public void testGetSubscription_notInCache_active() {
+    when(mockSubCacheRepo.readSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID)).thenReturn(null);
+    when(mockSubService.getSubscriptionsByNotificationId(TEST_TENANT, TEST_NOTIF_ID)).thenReturn(
+        subscription);
+
+    Subscription actualSub = manager.getSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+    assertEquals(subscription, actualSub);
+    verify(mockSubCacheRepo, times(1)).writeSubscription(TEST_TENANT, subscription);
+  }
+
+  @Test
+  public void testGetSubscription_notInCache_notAvailableInRegister() {
+    when(mockSubCacheRepo.readSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID)).thenReturn(null);
+    when(mockSubService.getSubscriptionsByNotificationId(TEST_TENANT, TEST_NOTIF_ID)).thenReturn(
+        null);
+
+    Subscription actualSub = manager.getSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+    assertNull(actualSub);
+    verify(mockSubCacheRepo, times(1)).poisonSub(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+  }
+
+  @Test
+  public void testGetSubscription_InCache_Poisoned() {
+    when(mockSubCacheRepo.readSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID)).thenReturn(null);
+    when(mockSubCacheRepo.checkIfSubIsPoisoned(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID)).thenReturn(
+        new Subscription());
+
+    Subscription actualSub = manager.getSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+    assertNull(actualSub);
+    verify(mockSubService, times(0)).getSubscriptionsByNotificationId(anyString(), anyString());
+  }
+
+  @Test
+  public void testRemoveSubscription() {
+    boolean b = manager.removeSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+    verify(mockSubCacheRepo, times(1)).deleteSubscription(TEST_TENANT, TEST_TOPIC, TEST_NOTIF_ID);
+  }
+
+  @Test
+  public void testUpdateSubscription_availableInRegister() {
+    when(mockSubService.getSubscriptionsByNotificationId(TEST_TENANT, TEST_NOTIF_ID)).thenReturn(
+        subscription);
+    manager.updateSubscription(TEST_TENANT, TEST_NOTIF_ID);
+    verify(mockSubCacheRepo, times(1)).updateSubscription(TEST_TENANT, subscription);
+  }
+
+  @Test
+  public void testUpdateSubscription_notAvailableInRegister() {
+    manager.updateSubscription(TEST_TENANT, TEST_NOTIF_ID);
+    verify(mockSubCacheRepo, times(0)).updateSubscription(anyString(), any());
+  }
+}
\ No newline at end of file
diff --git a/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/api/TestPushEndpointGsa.java b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/api/TestPushEndpointGsa.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5d8f4f2dfa8404a80beaf88a1bad21efc1c771d
--- /dev/null
+++ b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/api/TestPushEndpointGsa.java
@@ -0,0 +1,149 @@
+/*
+ *  Copyright 2020-2023 Google LLC
+ *  Copyright 2020-2023 EPAM Systems, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.opengroup.osdu.notification.api;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.opengroup.osdu.notification.util.Constants.GROUP_ID;
+
+import com.google.common.base.Strings;
+import com.sun.jersey.api.client.ClientResponse;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.notification.GsaSecret;
+import org.opengroup.osdu.core.common.model.notification.GsaSecretValue;
+import org.opengroup.osdu.core.common.model.notification.Secret;
+import org.opengroup.osdu.core.common.model.notification.Subscription;
+import org.opengroup.osdu.core.common.notification.ISubscriptionService;
+import org.opengroup.osdu.core.common.notification.SubscriptionAPIConfig;
+import org.opengroup.osdu.core.common.notification.SubscriptionException;
+import org.opengroup.osdu.core.common.notification.SubscriptionFactory;
+import org.opengroup.osdu.notification.util.AnthosTestUtils;
+import org.opengroup.osdu.notification.util.ServicesUtils;
+import org.opengroup.osdu.notification.util.TestUtils;
+
+public class TestPushEndpointGsa {
+  public static final String REGISTER_BASE_URL = "REGISTER_BASE_URL";
+  public static final String TOPIC_ID = "TOPIC_ID";
+  public static final String INTEGRATION_AUDIENCE = "INTEGRATION_AUDIENCE";
+  public static final String OSDU_TENANT = "OSDU_TENANT";
+  public static final String STORAGE_HOST = "STORAGE_HOST";
+  public static final String LEGAL_HOST = "LEGAL_HOST";
+  public static final String DE_OPS_TESTER = "DE_OPS_TESTER";
+  private String subscriptionId = null;
+  private String notificationId = null;
+  private ISubscriptionService subscriptionService;
+  private static SubscriptionFactory factory;
+  private TestUtils testUtils = new AnthosTestUtils();
+  private final String suffix = String.valueOf(System.currentTimeMillis());
+  private String baseRegisterUrl;
+  private String topic;
+  private String tenant;
+  private String integrationAudience;
+  private String storageHost;
+  private String legalHost;
+  private String groupId;
+  private static final String LEGAL_TAG_NAME = "notification-test-gsa";
+  private ServicesUtils servicesUtils;
+
+  @After
+  public void deleteResource() throws Exception {
+    subscriptionService.delete(subscriptionId);
+    servicesUtils.deleteStorageRecords(3, suffix);
+    servicesUtils.deleteLegalTag(LEGAL_TAG_NAME);
+  }
+
+  @Before
+  public void createResource() throws Exception {
+    baseRegisterUrl = System.getProperty(REGISTER_BASE_URL, System.getenv(REGISTER_BASE_URL));
+    topic = System.getProperty(TOPIC_ID, System.getenv(TOPIC_ID));
+    integrationAudience = System.getProperty(INTEGRATION_AUDIENCE, System.getenv(INTEGRATION_AUDIENCE));
+    tenant = System.getProperty(OSDU_TENANT, System.getenv(OSDU_TENANT));
+    if (Strings.isNullOrEmpty(integrationAudience)) {
+      integrationAudience = tenant;
+    }
+    storageHost = System.getProperty(STORAGE_HOST, System.getenv(STORAGE_HOST));
+    legalHost = System.getProperty(LEGAL_HOST, System.getenv(LEGAL_HOST));
+    groupId = System.getProperty(GROUP_ID, System.getenv(GROUP_ID));
+    servicesUtils = new ServicesUtils(storageHost, legalHost, testUtils, tenant, groupId);
+    servicesUtils.createLegalTag(LEGAL_TAG_NAME);
+    createResourceInPartition(tenant);
+  }
+
+  @Test
+  public void testPushEndpoint() throws Exception {
+    servicesUtils.createStorageRecords(suffix, 3, LEGAL_TAG_NAME);
+    Thread.sleep(10000);
+    assertNotNull(subscriptionId);
+    assertNotNull(notificationId);
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DpsHeaders.DATA_PARTITION_ID, tenant);
+    ClientResponse clientResponse = testUtils.send(baseRegisterUrl, "/test-gc/state", "GET", testUtils.getOpsToken(), null, "",
+        headers, false);
+    Map<String, Number> response = new HashMap<>();
+    response = testUtils.getResult(clientResponse, 200, response.getClass());
+    assertNotNull(response);
+    assertTrue(response.containsKey(suffix));
+    assertTrue(response.get(suffix).longValue() >= 3);
+  }
+
+  private void createResourceInPartition(String partitionId) throws Exception {
+
+    SubscriptionAPIConfig config = SubscriptionAPIConfig.builder().rootUrl(baseRegisterUrl).build();
+    factory = new SubscriptionFactory(config);
+
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
+    headers.put(DpsHeaders.AUTHORIZATION, testUtils.getOpsToken());
+    DpsHeaders dpsHeaders = DpsHeaders.createFromMap(headers);
+    subscriptionService = factory.create(dpsHeaders);
+
+    Subscription subscription = new Subscription();
+    subscription.setName("subscription-integration-test-gsa-" + suffix);
+    subscription.setDescription("subscription created for gsa integration test " + suffix);
+    subscription.setTopic(topic);
+    subscription.setPushEndpoint(getPushUrl());
+
+    Secret gsaSecret = new GsaSecret();
+    GsaSecretValue gsaSecretValue = new GsaSecretValue();
+    gsaSecretValue.setAudience(integrationAudience);
+    String opsTester = System.getProperty(DE_OPS_TESTER, System.getenv(DE_OPS_TESTER));
+    gsaSecretValue.setKey(new String(Base64.getDecoder().decode(opsTester)));
+    gsaSecret.setSecretType("GSA");
+    ((GsaSecret) gsaSecret).setValue(gsaSecretValue);
+    subscription.setSecret(gsaSecret);
+    try {
+      Subscription subscriptionCreated = subscriptionService.create(subscription);
+      notificationId = subscriptionCreated.getNotificationId();
+      subscriptionId = subscriptionCreated.getId();
+    } catch (SubscriptionException e) {
+      System.out.println("Subscription exception inner response : " + e.getHttpResponse());
+      throw e;
+    }
+  }
+
+  private String getPushUrl() {
+    return baseRegisterUrl + "/test-gc/gsa-challenge/" + suffix;
+  }
+
+}
diff --git a/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/api/TestPushEndpointHMAC.java b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/api/TestPushEndpointHMAC.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d5b0458a5f8cea6c2caa3071528251ead1aa005
--- /dev/null
+++ b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/api/TestPushEndpointHMAC.java
@@ -0,0 +1,135 @@
+/*
+ *  Copyright 2020-2023 Google LLC
+ *  Copyright 2020-2023 EPAM Systems, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.opengroup.osdu.notification.api;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.opengroup.osdu.notification.util.Constants.GROUP_ID;
+
+import com.sun.jersey.api.client.ClientResponse;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.notification.HmacSecret;
+import org.opengroup.osdu.core.common.model.notification.Subscription;
+import org.opengroup.osdu.core.common.notification.ISubscriptionService;
+import org.opengroup.osdu.core.common.notification.SubscriptionAPIConfig;
+import org.opengroup.osdu.core.common.notification.SubscriptionException;
+import org.opengroup.osdu.core.common.notification.SubscriptionFactory;
+import org.opengroup.osdu.notification.util.AnthosTestUtils;
+import org.opengroup.osdu.notification.util.ServicesUtils;
+import org.opengroup.osdu.notification.util.TestUtils;
+
+public class TestPushEndpointHMAC {
+  public static final String REGISTER_BASE_URL = "REGISTER_BASE_URL";
+  public static final String TOPIC_ID = "TOPIC_ID";
+  public static final String HMAC_SECRET = "HMAC_SECRET";
+  public static final String OSDU_TENANT = "OSDU_TENANT";
+  public static final String STORAGE_HOST = "STORAGE_HOST";
+  public static final String LEGAL_HOST = "LEGAL_HOST";
+  private String subscriptionId = null;
+  private String notificationId = null;
+  private ISubscriptionService subscriptionService;
+  private static SubscriptionFactory factory;
+  private TestUtils testUtils = new AnthosTestUtils();
+  private final String suffix = String.valueOf(System.currentTimeMillis());
+  private String baseRegisterUrl;
+  private String topic;
+  private String hmacSecretValue;
+  private String tenant;
+  private String storageHost;
+  private String legalHost;
+  private String groupId;
+  private static final String LEGAL_TAG_NAME = "notification-test-hmac";
+  private ServicesUtils servicesUtils;
+
+  @After
+  public void deleteResource() throws Exception {
+    subscriptionService.delete(subscriptionId);
+    servicesUtils.deleteStorageRecords(3, suffix);
+    servicesUtils.deleteLegalTag(LEGAL_TAG_NAME);
+  }
+
+  @Before
+  public void createResource() throws Exception {
+    baseRegisterUrl = System.getProperty(REGISTER_BASE_URL, System.getenv(REGISTER_BASE_URL));
+    topic = System.getProperty(TOPIC_ID, System.getenv(TOPIC_ID));
+    hmacSecretValue = System.getProperty(HMAC_SECRET, System.getenv(HMAC_SECRET));
+    tenant = System.getProperty(OSDU_TENANT, System.getenv(OSDU_TENANT));
+    storageHost = System.getProperty(STORAGE_HOST, System.getenv(STORAGE_HOST));
+    legalHost = System.getProperty(LEGAL_HOST, System.getenv(LEGAL_HOST));
+    groupId = System.getProperty(GROUP_ID, System.getenv(GROUP_ID));
+    servicesUtils = new ServicesUtils(storageHost, legalHost, testUtils, tenant, groupId);
+    servicesUtils.createLegalTag(LEGAL_TAG_NAME);
+    createResourceInPartition(tenant);
+  }
+
+  @Test
+  public void testPushEndpoint() throws Exception {
+    servicesUtils.createStorageRecords(suffix, 3, LEGAL_TAG_NAME);
+    Thread.sleep(10000);
+    assertNotNull(subscriptionId);
+    assertNotNull(notificationId);
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DpsHeaders.DATA_PARTITION_ID, tenant);
+    ClientResponse clientResponse = testUtils.send(baseRegisterUrl, "/test-gc/state", "GET", testUtils.getOpsToken(), null, "",
+        headers, false);
+    Map<String, Number> response = new HashMap<>();
+    response = testUtils.getResult(clientResponse, 200, response.getClass());
+    assertNotNull(response);
+    assertTrue(response.containsKey(suffix));
+    assertTrue(response.get(suffix).longValue() >= 3);
+  }
+
+  private void createResourceInPartition(String partitionId) throws Exception {
+
+    SubscriptionAPIConfig config = SubscriptionAPIConfig.builder().rootUrl(baseRegisterUrl).build();
+    factory = new SubscriptionFactory(config);
+
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
+    headers.put(DpsHeaders.AUTHORIZATION, testUtils.getOpsToken());
+    DpsHeaders dpsHeaders = DpsHeaders.createFromMap(headers);
+    subscriptionService = factory.create(dpsHeaders);
+
+    Subscription subscription = new Subscription();
+    subscription.setName("subscription-integration-test-hmac-" + suffix);
+    subscription.setDescription("subscription created for hmac integration test " + suffix);
+    subscription.setTopic(topic);
+    subscription.setPushEndpoint(getPushUrl());
+    HmacSecret secret = new HmacSecret();
+    secret.setValue(hmacSecretValue);
+
+    subscription.setSecret(secret);
+    try {
+      Subscription subscriptionCreated = subscriptionService.create(subscription);
+      notificationId = subscriptionCreated.getNotificationId();
+      subscriptionId = subscriptionCreated.getId();
+    } catch (SubscriptionException e) {
+      System.out.println("Subscription exception inner response : " + e.getHttpResponse());
+      throw e;
+    }
+  }
+
+  private String getPushUrl() {
+    return baseRegisterUrl + "/test-gc/challenge/" + suffix;
+  }
+}
diff --git a/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/Constants.java b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/Constants.java
new file mode 100644
index 0000000000000000000000000000000000000000..7889fab81ba31cbd3f5c840c2aca9d838c02aa21
--- /dev/null
+++ b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/Constants.java
@@ -0,0 +1,6 @@
+package org.opengroup.osdu.notification.util;
+
+public class Constants {
+
+  public static final String GROUP_ID = "GROUP_ID";
+}
diff --git a/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/FileUtils.java b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/FileUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc0713c1665b4db5276e88a9b6c8b1c64085fa4d
--- /dev/null
+++ b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/FileUtils.java
@@ -0,0 +1,39 @@
+/*
+ *  Copyright 2020-2023 Google LLC
+ *  Copyright 2020-2023 EPAM Systems, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.opengroup.osdu.notification.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class FileUtils {
+  public String readFromLocalFilePath(String filePath) throws IOException {
+
+    InputStream inStream = this.getClass().getResourceAsStream(filePath);
+    BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
+    StringBuilder stringBuilder = new StringBuilder();
+
+    String eachLine = "";
+    while ((eachLine = br.readLine()) != null) {
+      stringBuilder.append(eachLine);
+    }
+
+    return stringBuilder.toString();
+  }
+}
diff --git a/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/HttpClient.java b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/HttpClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..b14839c915deb5235307f3d80a0491beabe5df64
--- /dev/null
+++ b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/HttpClient.java
@@ -0,0 +1,108 @@
+/*
+ *  Copyright 2020-2023 Google LLC
+ *  Copyright 2020-2023 EPAM Systems, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.opengroup.osdu.notification.util;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.gson.Gson;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import java.net.URI;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.ws.rs.core.MediaType;
+import org.apache.commons.lang3.StringUtils;
+
+public class HttpClient {
+  private HttpClient(){
+  }
+
+  public static ClientResponse send(String url, String path, String httpMethod,
+                                    Map<String, String> headers,
+                                    String requestBody, String query) throws Exception {
+
+    String normalizedUrl = new URI(String.format("%s/%s", url, path)).normalize().toString();
+    normalizedUrl = StringUtils.removeEnd(normalizedUrl, "/");
+    log(httpMethod, normalizedUrl + query, headers, requestBody);
+    Client client = getClient();
+
+    WebResource webResource = client.resource(normalizedUrl + query);
+    WebResource.Builder builder = webResource.accept(MediaType.APPLICATION_JSON)
+        .type(MediaType.APPLICATION_JSON);
+    headers.forEach(builder::header);
+
+    if ("POST".equals(httpMethod) && StringUtils.isEmpty(requestBody)) {
+      requestBody = "{}"; //solves 411 error when sending empty-body POST request
+    }
+
+    return builder.method(httpMethod, ClientResponse.class, requestBody);
+  }
+
+  private static void log(String method, String url, Map<String, String> headers, String body) {
+    System.out.println(String.format("%s: %s", method, url));
+    System.out.println(body);
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
+    assertEquals(exepectedStatus, response.getStatus());
+    if (exepectedStatus == 204) {
+      return null;
+    }
+
+    assertEquals("application/json; charset=UTF-8", response.getType().toString());
+    String json = response.getEntity(String.class);
+    if (classOfT == String.class) {
+      return (T) json;
+    }
+
+    Gson gson = new Gson();
+    return gson.fromJson(json, classOfT);
+  }
+
+  protected static Client getClient() {
+    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
+      @Override
+      public X509Certificate[] getAcceptedIssuers() {
+        return null;
+      }
+
+      @Override
+      public void checkClientTrusted(X509Certificate[] certs, String authType) {
+      }
+
+      @Override
+      public void checkServerTrusted(X509Certificate[] certs, String authType) {
+      }
+    }};
+
+    try {
+      SSLContext sc = SSLContext.getInstance("TLS");
+      sc.init(null, trustAllCerts, new SecureRandom());
+      HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+    } catch (Exception e) {
+    }
+    return Client.create();
+  }
+}
diff --git a/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/ServicesUtils.java b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/ServicesUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..eabebc585ab5316e311ea07969044766fe9e9fe8
--- /dev/null
+++ b/testing/notification-test-baremetal/src/test/java/org/opengroup/osdu/notification/util/ServicesUtils.java
@@ -0,0 +1,96 @@
+/*
+ *  Copyright 2020-2023 Google LLC
+ *  Copyright 2020-2023 EPAM Systems, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.opengroup.osdu.notification.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.sun.jersey.api.client.ClientResponse;
+import java.util.HashMap;
+import java.util.Map;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+
+public class ServicesUtils {
+  private String storageHost;
+  private String legalHost;
+  private TestUtils testUtils;
+  private String partitionId;
+  private String groupId;
+  private FileUtils fileUtils;
+
+  public ServicesUtils(String storageHost, String legalHost, TestUtils testUtils, String partitionId, String groupId) {
+    this.storageHost = storageHost;
+    this.legalHost = legalHost;
+    this.testUtils = testUtils;
+    this.partitionId = partitionId;
+    this.groupId = groupId;
+    this.fileUtils = new FileUtils();
+  }
+
+  public ClientResponse createLegalTag(String tagName) throws Exception {
+    String legalBody = fileUtils.readFromLocalFilePath("/LegalTag.json");
+    legalBody = legalBody.replace("{{tagName}}", tagName);
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
+    headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
+
+    ClientResponse legalResponse = HttpClient.send(legalHost, "legaltags", "POST", headers, legalBody, "");
+
+    boolean createdOrAlreadyExists = legalResponse.getStatus() == 201 || legalResponse.getStatus() == 409;
+    assertTrue(createdOrAlreadyExists);
+    return legalResponse;
+  }
+
+  public void deleteLegalTag(String tagName) throws Exception{
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
+    headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
+    ClientResponse legalResponse = HttpClient.send(legalHost, String.format("legaltags/%s", tagName), "DELETE",
+        headers, "", "");
+    assertEquals(204, legalResponse.getStatus());
+  }
+
+  public void createStorageRecords(String suffix, int count, String legalTag) throws Exception{
+    String body = fileUtils.readFromLocalFilePath("/StorageRecord.json");
+    body = body.replace("{{data-partition-id}}", partitionId);
+    body = body.replace("{{legal-tag}}", partitionId + "-" + legalTag);
+    body = body.replace("{{group_id}}", groupId);
+    for (int i = 0; i < count; i++) {
+      String actualBody = body.replace("{{ids-suffix}}", suffix + String.valueOf(i));
+      Map<String, String> headers = new HashMap<>();
+      headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
+      headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
+      ClientResponse storageResponse = HttpClient.send(storageHost, "records", "PUT",
+          headers, actualBody, "");
+      assertEquals(201, storageResponse.getStatus());
+    }
+  }
+
+  public void deleteStorageRecords(int count, String suffix) throws Exception{
+    for (int i = 0; i < count; i++) {
+      Map<String, String> headers = new HashMap<>();
+      headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
+      headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
+      String recordId = partitionId + ":dataset--ConnectedSource.Generic:notification-test-" + suffix + i;
+      ClientResponse storageResponse = HttpClient.send(storageHost, "records/" + recordId, "DELETE",
+          headers, "", "");
+      assertEquals(204, storageResponse.getStatus());
+    }
+  }
+
+}