diff --git a/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/api/StorageIntegrationDescriptor.java b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/api/StorageIntegrationDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bca4c8970ce0b87e4918ea6cef7221473055fd1
--- /dev/null
+++ b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/api/StorageIntegrationDescriptor.java
@@ -0,0 +1,86 @@
+// Copyright © Microsoft Corporation
+//
+// 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 org.opengroup.osdu.notification.util.Config;
+import org.opengroup.osdu.notification.util.RestDescriptor;
+import org.opengroup.osdu.notification.util.TestUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class StorageIntegrationDescriptor extends RestDescriptor {
+
+    protected static final String LEGAL_TAG = TestUtils.getOsduTenant() + "-test-tag";
+
+    @Override
+    public String getPath() {
+        return "records";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "PUT";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "[\n" +
+                "  {\n" +
+                "      \"data\":{\n" +
+                "            \"Spuddate\":\"atspud\",\n" +
+                "            \"UWI\":\"atuwi\",\n" +
+                "            \"dlLatLongWGS84latitude\":\"latitude\",\n" +
+                "            \"dlLatLongWGS84longitude\":\"longitude\"},\n" +
+                "      \"version\":1591087431362345,\n" +
+                "      \"kind\":\"opendes:at:wellbore:1.0.0\",\n" +
+                "      \"acl\":{\n" +
+                "            \"viewers\":[\n" +
+                "                 \"data.test1@opendes.contoso.com\"],\n" +
+                "            \"owners\":[\n" +
+                "                 \"data.test1@opendes.contoso.com\"]},\n" +
+                "      \"legal\":{\n" +
+                "            \"legaltags\":[\n" +
+                "                 \"" + LEGAL_TAG + "\"],\n" +
+                "            \"otherRelevantDataCountries\":[\n" +
+                "                 \"BR\"],\n" +
+                "            \"status\":\"compliant\"},\n" +
+                "      \"createUser\":\"integrationtest@opendes.iam.gserviceaccount.com\",\n" +
+                "      \"createTime\":\"2020-06-01T18:32:52.054Z\",\n" +
+                "      \"modifyUser\":\"integrationtest@opendes.iam.gserviceaccount.com\",\n" +
+                "      \"modifyTime\":\"2020-06-02T08:43:51.553Z\"\n" +
+                "  }\n" +
+                "]";
+    }
+
+    @Override
+    public Map<String, String> getOsduTenantHeaders() {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("data-partition-id", Config.Instance().OsduTenant);
+        headers.put("correlation-id", UUID.randomUUID().toString());
+        return headers;
+    }
+
+    // Customer Tenant headers is not required by the current Storage -Notification
+    // Integration Test scenario.It might be useful in upcoming test scenarios/cases
+    @Override
+    public Map<String, String> getCustomerTenantHeaders() {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("data-partition-id", Config.Instance().ClientTenant);
+        headers.put("correlation-id", UUID.randomUUID().toString());
+        return headers;
+    }
+}
\ No newline at end of file
diff --git a/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/api/TestStorageIntegration.java b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/api/TestStorageIntegration.java
new file mode 100644
index 0000000000000000000000000000000000000000..37fa5bc8a040cf30f203003337b37c06dfd52a0f
--- /dev/null
+++ b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/api/TestStorageIntegration.java
@@ -0,0 +1,239 @@
+// Copyright © Microsoft Corporation
+//
+// 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 com.sun.jersey.api.client.ClientResponse;
+import org.apache.catalina.connector.Response;
+import org.apache.commons.lang3.time.StopWatch;
+import org.asynchttpclient.util.Assertions;
+import org.junit.*;
+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.model.notification.SubscriptionInfo;
+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.*;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class TestStorageIntegration extends BaseTestTemplate {
+
+    private String subscriptionId = null;
+    private String notificationId = null;
+    private final String ackSubscriptionId = "AckSubscription";
+    private final String ackNotificationId = "testingAcknowledgement";
+    private ISubscriptionService subscriptionService;
+    private static SubscriptionFactory factory;
+    protected static final String LEGAL_TAG = TestUtils.getOsduTenant() + "-test-tag";
+
+    @BeforeClass
+    public static void classSetup() throws Exception {
+        descriptor = new StorageIntegrationDescriptor();
+        //Configure Register Service Client Library
+        SubscriptionAPIConfig config = SubscriptionAPIConfig.builder().rootUrl(Config.Instance().RegisterServicePath).build();
+        factory = new SubscriptionFactory(config);
+    }
+
+    @AfterClass
+    public static void classTearDown() throws Exception {
+    }
+
+    @Before
+    @Override
+    public void setup() throws Exception {
+        this.testUtils = new AzureTestUtils();
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        subscriptionService.delete(subscriptionId);
+    }
+
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        createResourceInPartition(TestUtils.getOsduTenant());
+    }
+
+    private void createResourceInPartition(String partitionId) throws Exception {
+        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);
+
+        // Create a new subscription
+        Subscription subscription = new Subscription();
+        subscription.setName("storage-integration-test-hmac");
+        subscription.setDescription("Subscription created for Storage Integration Tests");
+        subscription.setTopic(Config.Instance().Topic);
+        subscription.setPushEndpoint(Config.Instance().HMACPushUrl);
+        HmacSecret secret = new HmacSecret();
+        secret.setValue(Config.Instance().hmacSecretValue);
+        subscription.setSecret(secret);
+        try {
+            Subscription subscriptionCreated = subscriptionService.create(subscription);
+            notificationId = subscriptionCreated.getNotificationId();
+            subscriptionId = subscriptionCreated.getId();
+            Config.Instance().NotificationId = notificationId;
+        } catch (SubscriptionException e) {
+            System.out.println("Subscription exception inner response : " + e.getHttpResponse());
+            throw e;
+        }
+    }
+
+    private void deleteAckSubscription() throws SubscriptionException {
+        try {
+            subscriptionService.delete(ackSubscriptionId);
+        } catch (SubscriptionException e) {
+            if (e.getHttpResponse().getResponseCode() == Response.SC_NOT_FOUND) {
+                System.out.println("Test Ack Subscription Not Found for deletion.");
+                return;
+            }
+            Assert.fail("Unable to delete Test Ack Subscription. Deletion Failed." + e);
+            throw e;
+        }
+    }
+
+    @Override
+    protected String getArg() {
+        return null;
+    }
+
+    @Override
+    protected String getInvalidArg() {
+        return null;
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+
+    @Test
+    @Override
+    public void should_return20XResponseCode_when_makingValidHttpsRequest() throws Exception {
+        try {
+            // Creates an actual subscription with a test endpoint i.e REGISTER_CUSTOM_PUSH_URL_HMAC
+            this.createResource();
+
+            // Delete the Test Ack subscription if there exists any as a part of cleanup.
+            // The Test Ack Subscription gets created if the the test endpoint of actual subscription
+            // created above receives notification from Notification Service.
+            this.deleteAckSubscription();
+
+            //  Create legal tag used in storage record
+            LegalTagUtils.create(LEGAL_TAG, this.testUtils.getAdminToken());
+
+            // Insert a storage Record.This will send a notification to  the event grid/service bus topic
+            // subscriptions.From there it goes to the Notification Service.Finally from there it goes to the
+            // test endpoint i.e REGISTER_CUSTOM_PUSH_URL_HMAC which creates the Test ack Subscription.
+            String URL = Config.Instance().StorageServicePath;
+            ClientResponse response = descriptor.run(URL, "", this.testUtils.getAdminToken());
+            assertEquals(error(response.getEntity(String.class)), 201, response.getStatus());
+
+            // Verification of Test Ack Subscription creation from the above process.
+            StopWatch stopWatch = new StopWatch();
+            stopWatch.start();
+            // Retrieval of test ack subscription from Cosmos-DB.
+            long retryCount = Long.parseLong(Config.Instance().RetryCount);
+            long timeOut = Long.parseLong(Config.Instance().TimeOutSeconds);
+            SubscriptionInfo ackSubscription = subscriptionService.get(ackSubscriptionId);
+            while (ackSubscription == null && retryCount > 0) {
+                TimeUnit.SECONDS.sleep(timeOut);
+                ackSubscription = subscriptionService.get(ackSubscriptionId);
+                retryCount--;
+            }
+            Assertions.assertNotNull(ackSubscription, "Unable to retrieve test ack subscription. Elapsed time in minutes : " + (stopWatch.getTime(TimeUnit.MINUTES)));
+            if (ackSubscription != null) {
+                assertEquals("Unexpected Test Ack Subscription.", ackNotificationId, ackSubscription.getNotificationId());
+            }
+            stopWatch.stop();
+        } catch (Exception e) {
+            fail("An exception occurred :" + e);
+        } finally {
+            // Delete Actual Subscription
+            this.deleteResource();
+            // Deletion of Test Ack Subscription
+            this.deleteAckSubscription();
+            //  Delete legal tag
+            LegalTagUtils.delete(LEGAL_TAG, this.testUtils.getAdminToken());
+
+        }
+    }
+
+    /* Keeping the No-op test cases implementation as ignored as the Storage-Notification Integration
+    Test scenario does not involves them. */
+    @Test
+    @Override
+    @Ignore
+    public void should_return400_when_makingHttpRequestWithoutToken() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_return307_when_makingHttpRequest() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_return401_when_accessingWithNoAccessCredentials() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_return401_when_noAccessOnCustomerTenant() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_return401_when_accessingWithEditorCredentials() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_return401_when_accessingWithAdminCredentials() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_return20X_when_usingCredentialsWithOpsPermission() throws Exception {
+    }
+
+    @Test
+    @Override
+    @Ignore
+    public void should_returnOk_when_makingHttpOptionsRequest() throws Exception {
+    }
+}
\ No newline at end of file
diff --git a/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/LegalTagUtils.java b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/LegalTagUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9f1eb14acdb95412a073c6b4316b4f682a07990
--- /dev/null
+++ b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/LegalTagUtils.java
@@ -0,0 +1,75 @@
+// Copyright 2017-2019, Schlumberger
+//
+// 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 com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.sun.jersey.api.client.ClientResponse;
+import org.apache.http.HttpStatus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class LegalTagUtils {
+    public static ClientResponse create(String legalTagName, String token) throws Exception {
+        return create("US", legalTagName, "2099-01-25", "Public Domain Data", token);
+    }
+
+    protected static ClientResponse create(String countryOfOrigin, String name, String expDate, String dataType, String token)
+            throws Exception {
+        String body = getBody(countryOfOrigin, name, expDate, dataType);
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Data-Partition-Id", TestUtils.getOsduTenant());
+        ClientResponse response = TestUtils.send(getLegalUrl(), "legaltags", "POST", token, body, "", headers, false);
+        assertEquals(HttpStatus.SC_CREATED, response.getStatus());
+        Thread.sleep(100);
+        return response;
+    }
+
+    public static ClientResponse delete(String legalTagName, String token) throws Exception {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Data-Partition-Id", TestUtils.getOsduTenant());
+        return TestUtils.send(getLegalUrl(), "legaltags/" + legalTagName, "DELETE", token, "", "", headers, false);
+    }
+
+    protected static String getLegalUrl() {
+        return Config.Instance().LegalServicePath;
+    }
+
+    protected static String getBody(String countryOfOrigin, String name, String expDate, String dataType) {
+
+        JsonArray coo = new JsonArray();
+        coo.add(countryOfOrigin);
+
+        JsonObject properties = new JsonObject();
+        properties.add("countryOfOrigin", coo);
+        properties.addProperty("contractId", "A1234");
+        properties.addProperty("expirationDate", expDate);
+        properties.addProperty("dataType", dataType);
+        properties.addProperty("originator", "MyCompany");
+        properties.addProperty("securityClassification", "Public");
+        properties.addProperty("exportClassification", "EAR99");
+        properties.addProperty("personalData", "No Personal Data");
+
+        JsonObject tag = new JsonObject();
+        tag.addProperty("name", name);
+        tag.addProperty("description", "test for " + name);
+        tag.add("properties", properties);
+
+        return tag.toString();
+    }
+}
diff --git a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java
index 0d126cd2cd08d10993df45dd83c61bc62984ea07..8f7655b27ddf731230131e91fedad90b67809763 100644
--- a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java
+++ b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java
@@ -24,55 +24,61 @@ public class Config {
     public String GSAPushUrl;
     public String HMACPushUrl;
     public String RegisterServicePath;
+    public String StorageServicePath;
+    public String LegalServicePath;
     public String Topic;
     public String hmacSecretValue;
     public String NotificationId;
     public String DE_OPS_TESTER = System.getProperty("DE_OPS_TESTER", System.getenv("DE_OPS_TESTER"));
-
+    public String RetryCount;
+    public String TimeOutSeconds;
     private static Config config = new Config();
 
     public static Config Instance() {
         String env = getEnvironment();
-        config.ClientTenant = getEnvironmentVariableOrDefaultValue("CLIENT_TENANT","nonexistenttenant");
-        config.IntegrationAudience =  getEnvironmentVariableOrDefaultValue("INTEGRATION_TEST_AUDIENCE","245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com");
-        config.OsduTenant = getEnvironmentVariableOrDefaultValue("OSDU_TENANT","opendes");
-        config.Topic = getEnvironmentVariableOrDefaultValue("TOPIC_ID","records-changed");
-
+        config.ClientTenant = getEnvironmentVariableOrDefaultValue("CLIENT_TENANT", "nonexistenttenant");
+        config.IntegrationAudience = getEnvironmentVariableOrDefaultValue("INTEGRATION_TEST_AUDIENCE", "245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com");
+        config.OsduTenant = getEnvironmentVariableOrDefaultValue("OSDU_TENANT", "opendes");
+        config.Topic = getEnvironmentVariableOrDefaultValue("TOPIC_ID", "records-changed");
+        config.TimeOutSeconds = getEnvironmentVariableOrDefaultValue("TIME_OUT_SECONDS", "60");
+        config.RetryCount = getEnvironmentVariableOrDefaultValue("RETRY_COUNT", "3");
         config.hmacSecretValue = System.getProperty("HMAC_SECRET", System.getenv("HMAC_SECRET"));
         if (env.equalsIgnoreCase("LOCAL")) {
             //make sure to run register service on a different port. You can also choose to point to Register service that is running in cloud
             String registerUrl = "http://localhost:8081/api/register/v1";
-
             //must have notification and register services running on different ports
             config.HostUrl = "http://localhost:8080/";
 
-            config.GSAPushUrl = registerUrl+"/test/gsa-challenge/";
-            config.HMACPushUrl = registerUrl+"/test/challenge/";
+            config.GSAPushUrl = registerUrl + "/test/gsa-challenge/";
+            config.HMACPushUrl = registerUrl + "/test/challenge/";
             config.RegisterServicePath = registerUrl;
+            config.StorageServicePath = "http://localhost:8085/api/storage/v2/";
+            config.LegalServicePath = "http://localhost:8087/api/legal/v1/";
+
         } else if (env.equalsIgnoreCase("DEV") || isGke() || env.equalsIgnoreCase("CLOUD")) {
             String registerUrl = System.getProperty("REGISTER_BASE_URL", System.getenv("REGISTER_BASE_URL"));
             config.HostUrl = System.getProperty("NOTIFICATION_BASE_URL", System.getenv("NOTIFICATION_BASE_URL"));
-            config.GSAPushUrl = registerUrl+"/test/gsa-challenge/";
+            config.GSAPushUrl = registerUrl + "/test/gsa-challenge/";
             //Adding this so CPs can point to custom HMAC push endpoints
-            config.HMACPushUrl = getEnvironmentVariableOrDefaultValue("REGISTER_CUSTOM_PUSH_URL_HMAC",registerUrl+"/test/challenge/");
+            config.HMACPushUrl = getEnvironmentVariableOrDefaultValue("REGISTER_CUSTOM_PUSH_URL_HMAC", registerUrl + "/test/challenge/");
             //Adding a new variable NOTIFICATION_REGISTER_BASE_URL since REGISTER_BASE_URL is used by Register integration tests which needs a trailing \
-             String regUrl= getEnvironmentVariable("NOTIFICATION_REGISTER_BASE_URL");
-             if(regUrl==null)
-             {
-                 config.RegisterServicePath = registerUrl;
-             }
-             else
-             {
-                 config.RegisterServicePath = regUrl+"/api/register/v1";
-             }
+            String regUrl = getEnvironmentVariable("NOTIFICATION_REGISTER_BASE_URL");
+            config.StorageServicePath = getEnvironmentVariable("STORAGE_HOST");
+            config.LegalServicePath = System.getProperty("LEGAL_URL", System.getenv("LEGAL_URL"));
+            if (regUrl == null) {
+                config.RegisterServicePath = registerUrl;
+            } else {
+                config.RegisterServicePath = regUrl + "/api/register/v1";
+            }
 
-        }else
+        } else
             throw new RuntimeException("$ENVIRONMENT environment variable not provided");
 
-        System.out.println("HostUrl="+config.HostUrl);
-        System.out.println("config.Topic="+ config.Topic);
-        System.out.println("config.HMACPushUrl="+ config.HMACPushUrl);
-        System.out.println("config.RegisterServicePath="+ config.RegisterServicePath);
+        System.out.println("HostUrl=" + config.HostUrl);
+        System.out.println("config.Topic=" + config.Topic);
+        System.out.println("config.HMACPushUrl=" + config.HMACPushUrl);
+        System.out.println("config.RegisterServicePath=" + config.RegisterServicePath);
+        System.out.println("config.StorageServicePath=" + config.StorageServicePath);
         return config;
     }
 
diff --git a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/RestDescriptor.java b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/RestDescriptor.java
index 38690fc885965e34570151a04883230632f48c86..08bab7e551b06c5f172aead358a159d99801257b 100644
--- a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/RestDescriptor.java
+++ b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/RestDescriptor.java
@@ -22,34 +22,51 @@ import java.util.Map;
 
 public abstract class RestDescriptor {
 
-	public RestDescriptor() {
-	}
-
-	private String arg = "";
-	public String arg(){
-		return arg;
-	}
-	public abstract String getPath();
-	public abstract String getHttpMethod();
-	public abstract String getValidBody();
-	public abstract Map<String,String> getOsduTenantHeaders();
-	public abstract Map<String,String> getCustomerTenantHeaders();
-	public String getQuery() { return ""; }
-
-	public ClientResponse runHttp(String arg, String token) throws Exception{
-		this.arg = arg;
-		return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(),true);
-	}
-	public ClientResponse run(String arg, String token) throws Exception{
-		this.arg = arg;
-		return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(),  getOsduTenantHeaders(),false);
-	}
-	public ClientResponse runOnCustomerTenant(String arg, String token) throws Exception{
-		this.arg = arg;
-		return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getCustomerTenantHeaders(), false);
-	}
-	public ClientResponse runOptions(String arg, String token) throws Exception{
-		this.arg = arg;
-		return TestUtils.send(getPath(), "OPTIONS", token, "", "",  getOsduTenantHeaders(),false);
-	}
+    public RestDescriptor() {
+    }
+
+    private String arg = "";
+
+    public String arg() {
+        return arg;
+    }
+
+    public abstract String getPath();
+
+    public abstract String getHttpMethod();
+
+    public abstract String getValidBody();
+
+    public abstract Map<String, String> getOsduTenantHeaders();
+
+    public abstract Map<String, String> getCustomerTenantHeaders();
+
+    public String getQuery() {
+        return "";
+    }
+
+    public ClientResponse runHttp(String arg, String token) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(), true);
+    }
+
+    public ClientResponse run(String arg, String token) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(), false);
+    }
+
+    public ClientResponse runOnCustomerTenant(String arg, String token) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getCustomerTenantHeaders(), false);
+    }
+
+    public ClientResponse runOptions(String arg, String token) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(getPath(), "OPTIONS", token, "", "", getOsduTenantHeaders(), false);
+    }
+
+    public ClientResponse run(String url, String arg, String token) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(url, getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(), false);
+    }
 }
\ No newline at end of file
diff --git a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/TestUtils.java b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/TestUtils.java
index 393089845fdad198817e00950eb9e7300dd7ff84..17d5d90b5ded8ad2a87658a3aebde2022ae8b1d0 100644
--- a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/TestUtils.java
+++ b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/TestUtils.java
@@ -35,46 +35,56 @@ import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.WebResource;
 
 public abstract class TestUtils {
-	protected String serviceAccountFile;
-	protected static String opsToken = null;
-	protected static String adminToken = null;
-	protected static String editorToken = null;
-	protected static String noAccessToken = null;
-
-	public static String getApiPath(String api, boolean enforceHttp) throws Exception {
-		String baseUrl = Config.Instance().HostUrl;
-		if(enforceHttp)
-			baseUrl = baseUrl.replaceFirst("https", "http");
-		URL mergedURL = new URL(baseUrl + api);
-		return mergedURL.toString();
-	}
-
-	public static String getOsduTenant(){
-		return Config.Instance().OsduTenant;
-	}
-
-	public static String getCustomerTenant(){
-		return Config.Instance().ClientTenant;
-	}
-
-	public abstract String getOpsToken() throws Exception;
-	public abstract String getAdminToken() throws Exception;
-	public abstract String getEditorToken() throws Exception;
-	public abstract String getNoAccessToken() throws Exception;
+    protected String serviceAccountFile;
+    protected static String opsToken = null;
+    protected static String adminToken = null;
+    protected static String editorToken = null;
+    protected static String noAccessToken = null;
+
+    public static String getApiPath(String api, boolean enforceHttp) throws Exception {
+        String baseUrl = Config.Instance().HostUrl;
+        if (enforceHttp)
+            baseUrl = baseUrl.replaceFirst("https", "http");
+        URL mergedURL = new URL(baseUrl + api);
+        return mergedURL.toString();
+    }
+
+    public static String getApiPath(String baseUrl, String api, boolean enforceHttp) throws Exception {
+        if (enforceHttp)
+            baseUrl = baseUrl.replaceFirst("https", "http");
+        URL mergedURL = new URL(baseUrl + api);
+        return mergedURL.toString();
+    }
+
+    public static String getOsduTenant() {
+        return Config.Instance().OsduTenant;
+    }
+
+    public static String getCustomerTenant() {
+        return Config.Instance().ClientTenant;
+    }
+
+    public abstract String getOpsToken() throws Exception;
+
+    public abstract String getAdminToken() throws Exception;
+
+    public abstract String getEditorToken() throws Exception;
+
+    public abstract String getNoAccessToken() throws Exception;
 
     public static ClientResponse send(String path, String httpMethod, String token, String requestBody, String query,
-                               Map<String,String> headers, boolean enforceHttp)
+                                      Map<String, String> headers, boolean enforceHttp)
             throws Exception {
 
         Client client = getClient();
-		client.setConnectTimeout(15000);
-		client.setReadTimeout(15000);
+        client.setConnectTimeout(50000);
+        client.setReadTimeout(50000);
         client.setFollowRedirects(false);
         String url = getApiPath(path + query, enforceHttp);
         System.out.println(url);
-		System.out.println(httpMethod);
-		System.out.println(requestBody);
-		System.out.println(headers);
+        System.out.println(httpMethod);
+        System.out.println(requestBody);
+        System.out.println(headers);
 
         WebResource webResource = client.resource(url);
         final WebResource.Builder builder = webResource.type(MediaType.APPLICATION_JSON)
@@ -85,47 +95,72 @@ public abstract class TestUtils {
         return response;
     }
 
-	@SuppressWarnings("unchecked")
-	public <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
-		String json = response.getEntity(String.class);
-
-		assertEquals(exepectedStatus, response.getStatus());
-		if (exepectedStatus == 204) {
-			return null;
-		}
-
-		assertEquals(MediaType.APPLICATION_JSON, response.getType().toString());
-		if (classOfT == String.class) {
-			return (T) json;
-		}
-
-		Gson gson = new Gson();
-		return gson.fromJson(json, classOfT);
-	}
-
-	public 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();
-	}
+    public static ClientResponse send(String url, String path, String httpMethod, String token, String requestBody,
+                                      String query, Map<String, String> headers, boolean enforceHttp)
+            throws Exception {
+
+        Client client = getClient();
+        client.setConnectTimeout(50000);
+        client.setReadTimeout(50000);
+        client.setFollowRedirects(false);
+        String URL = getApiPath(url, path + query, enforceHttp);
+        System.out.println(url + path);
+        System.out.println(httpMethod);
+        System.out.println(requestBody);
+        System.out.println(headers);
+        WebResource webResource = client.resource(URL);
+        final WebResource.Builder builder = webResource.type(MediaType.APPLICATION_JSON);
+        if (!token.isEmpty()) {
+            builder.header("Authorization", token);
+        }
+        headers.forEach((k, v) -> builder.header(k, v));
+        ClientResponse response = builder.method(httpMethod, ClientResponse.class, requestBody);
+
+        return response;
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
+        String json = response.getEntity(String.class);
+
+        assertEquals(exepectedStatus, response.getStatus());
+        if (exepectedStatus == 204) {
+            return null;
+        }
+
+        assertEquals(MediaType.APPLICATION_JSON, response.getType().toString());
+        if (classOfT == String.class) {
+            return (T) json;
+        }
+
+        Gson gson = new Gson();
+        return gson.fromJson(json, classOfT);
+    }
+
+    public 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();
+    }
 }
\ No newline at end of file