diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9347bdb802599a2292b62025da0101426600e854..905c96d7870ad60d34358ed678b66d720b71a1bf 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,6 +18,7 @@ variables:
   AZURE_TEST_SUBDIR: testing/register-test-azure
   AZURE_SWAGGER_PATH: api/register/v1/swagger-ui/index.html#/
   SERVICE_JAVA_VERSION: "17"
+  ACCEPTANCE_TEST_DIR: "register-acceptance-test"
 
 include: 
   - project: "osdu/platform/ci-cd-pipelines"
diff --git a/register-acceptance-test/README.md b/register-acceptance-test/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..77e5cfcc32652b7b9a0a2a48208319515d9dab0e
--- /dev/null
+++ b/register-acceptance-test/README.md
@@ -0,0 +1,65 @@
+### Running E2E Tests
+
+You will need to have the following environment variables defined.
+
+| name                        | value                                                        | description                                       | sensitive? | source | required |
+|-----------------------------|--------------------------------------------------------------|---------------------------------------------------|------------|--------|----------|
+| `CLIENT_TENANT`             | ex `osdu`                                                    | Shared Tenant name                                | no         | -      | yes      |
+| `OSDU_TENANT`               | ex `osdu`                                                    | OSDU tenant                                       | no         | -      | yes      |
+| `REGISTER_BASE_URL`         | ex `http://localhost:8080`                                   | Register service Base URL                         | no         | -      | yes      |
+| `REGISTER_CUSTOM_PUSH_URL`  | ex `http://localhost:8080/api/register/v1/test/challenge/1 ` | Registration Push URL                             | no         | -      | yes      |
+| `SUBSCRIPTION_ID`           | ex `abc`                                                     | Subscription used for testing                     | no         | -      | yes      |
+| `SUBSCRIBER_PRIVATE_KEY_ID` | `********`                                                   | Subscriber key                                    | yes        | -      | yes      |
+| `SUBSCRIBER_SECRET`         | `********`                                                   | Subscriber secret                                 | yes        | -      | yes      |
+| `TEST_TOPIC_NAME`           | ex `records-changed`                                         | Event grid topic name, default- 'records-changed' | no         | -      | no       |
+
+Authentication can be provided as OIDC config:
+
+| name                                      | value                                      | description             | sensitive? | source |
+|-------------------------------------------|--------------------------------------------|-------------------------|------------|--------|
+| `EDITOR_OPENID_PROVIDER_CLIENT_ID`        | `********`                                 | Editor Client Id        | yes        | -      |
+| `EDITOR_OPENID_PROVIDER_CLIENT_SECRET`    | `********`                                 | Editor Client secret    | yes        | -      |
+| `ADMIN_OPENID_PROVIDER_CLIENT_ID`         | `********`                                 | Admin Client Id         | yes        | -      |
+| `ADMIN_OPENID_PROVIDER_CLIENT_SECRET`     | `********`                                 | Admin Client secret     | yes        | -      |
+| `NO_ACCESS_OPENID_PROVIDER_CLIENT_ID`     | `********`                                 | No Access Client Id     | yes        | -      |
+| `NO_ACCESS_OPENID_PROVIDER_CLIENT_SECRET` | `********`                                 | No Access Client secret | yes        | -      |
+| `OPS_OPENID_PROVIDER_CLIENT_ID`           | `********`                                 | Ops Client Id           | yes        | -      |
+| `OPS_OPENID_PROVIDER_CLIENT_SECRET`       | `********`                                 | Ops Client secret       | yes        | -      |
+| `TEST_OPENID_PROVIDER_URL`                | ex `https://keycloak.com/auth/realms/osdu` | OpenID provider url     | yes        | -      |
+
+Or tokens can be used directly from env variables:
+
+| name                    | value      | description           | sensitive? | source |
+|-------------------------|------------|-----------------------|------------|--------|
+| `EDITOR_TOKEN`          | `********` | Editor Token          | yes        | -      |
+| `PRIVILEGED_USER_TOKEN` | `********` | Privileged User Token | yes        | -      |
+| `OPS_TOKEN`             | `********` | Ops Token             | yes        | -      |
+| `NO_ACCESS_USER_TOKEN`  | `********` | No Access Token       | yes        | -      |
+
+
+Execute following command to build code and run all the integration tests:
+
+ ```bash
+ # Note: this assumes that the environment variables for integration tests as outlined
+ #       above are already exported in your environment.
+ # build + install integration test core
+ $ (cd register-acceptance-test && mvn clean test)
+ ```
+
+## License
+
+Copyright © Google LLC
+
+Copyright © EPAM Systems
+
+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](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.
diff --git a/register-acceptance-test/pom.xml b/register-acceptance-test/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..adb2be5bd69370afb7669f9ae5e54ba90b462e26
--- /dev/null
+++ b/register-acceptance-test/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2017-2020 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.opengroup.osdu.register</groupId>
+    <artifactId>register-acceptance-test</artifactId>
+    <version>0.28.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <description>Register service Acceptance tests module</description>
+
+    <properties>
+        <maven.compiler.target>17</maven.compiler.target>
+        <maven.compiler.source>17</maven.compiler.source>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jackson-databind.version>2.16.1</jackson-databind.version>
+        <jackson.version>2.16.1</jackson.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-runtime</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.26</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+            <version>2.1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish</groupId>
+            <artifactId>jakarta.json</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>1.19.4</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>27.1-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opengroup.osdu</groupId>
+            <artifactId>core-lib-gc-spring6</artifactId>
+            <version>0.26.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson-databind.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.9</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+        </dependency>
+        <dependency>
+            <groupId>au.com.dius</groupId>
+            <artifactId>pact-jvm-provider-junit_2.12</artifactId>
+            <version>3.5.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>oauth2-oidc-sdk</artifactId>
+            <version>9.15</version>
+        </dependency>
+    </dependencies>
+
+    <repositories>
+        <repository>
+            <id>${repo.releases.id}</id>
+            <url>${repo.releases.url}</url>
+        </repository>
+    </repositories>
+
+    <distributionManagement>
+        <repository>
+            <id>${publish.releases.id}</id>
+            <url>${publish.releases.url}</url>
+        </repository>
+        <snapshotRepository>
+            <id>${publish.snapshots.id}</id>
+            <url>${publish.snapshots.url}</url>
+        </snapshotRepository>
+    </distributionManagement>
+</project>
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/CreateActionApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/CreateActionApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb87c2522c68448bbad55f19f42774d97c2c580e
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/CreateActionApiTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Action;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.CreateApiTestTemplate;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import static org.junit.Assert.*;
+
+public final class CreateActionApiTest extends CreateApiTestTemplate {
+
+    public CreateActionApiTest() {
+        super(new DeleteActionDescriptor(), new CreateActionDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String url = "";
+        String pushPath = System.getProperty("REGISTER_CUSTOM_PUSH_URL", System.getenv("REGISTER_CUSTOM_PUSH_URL"));
+        if( Strings.isNullOrEmpty(pushPath)) {
+            url= Config.Instance().securePushUrl + "api/register/v1/test/challenge";
+        }
+        else
+        {
+            url = pushPath;
+        }
+        String body = response.getEntity(String.class);
+        Action action = new Gson().fromJson(body, Action.class);
+        assertEquals("My test listener.", action.description);
+        assertTrue(action.contactEmail, action.contactEmail.equals("integrationtest@test.com"));
+        assertEquals("My listener", action.name);
+        assertEquals(url, action.url);
+        assertEquals(url, action.img);
+        assertEquals(1, action.filter.entityType.size());
+        assertEquals("*", action.filter.entityType.get(0));
+
+        assertEquals(1, action.filter.source.size());
+        assertEquals("*", action.filter.source.get(0));
+
+        assertEquals(1, action.filter.version.size());
+        assertEquals("*", action.filter.version.get(0));
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/CreateActionDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/CreateActionDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d12040c3e5634f6859c38db440c67f23135956a
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/CreateActionDescriptor.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import com.google.common.base.Strings;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class CreateActionDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/action";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "POST";
+    }
+
+    @Override
+    public String getValidBody() {
+        String url = "";
+        String pushPath = System.getProperty("REGISTER_CUSTOM_PUSH_URL", System.getenv("REGISTER_CUSTOM_PUSH_URL"));
+        if( Strings.isNullOrEmpty(pushPath)) {
+            url= Config.Instance().securePushUrl + "api/register/v1/test/challenge";
+        }
+        else
+        {
+            url = pushPath;
+        }
+
+        return "{\n" +
+                "\t\"id\": \"" + getArg() + "\",\n" +
+                "\t\"name\": \"My listener\",\n" +
+                "\t\"description\": \"My test listener.\",\n" +
+                "\t\"url\":\"" + url + "\",\n" +
+                "\t\"img\": \"" + url + "\",\n" +
+                "\t\"contactEmail\": \"" + "integrationtest@test.com" + "\",\n" +
+                "\t\"filter\": {\n" +
+                "\t\"entityType\": [\"*\"],\n" +
+                "\t\"source\": [\"*\"],\n" +
+                "\t\"version\": [\"*\"]}\n" +
+                "}";
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/DeleteActionApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/DeleteActionApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..815e4221e6a7f8da89b1e97c099b52a4549b89e9
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/DeleteActionApiTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.util.DeleteApiTestTemplate;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+public final class DeleteActionApiTest extends DeleteApiTestTemplate {
+
+    public DeleteActionApiTest() {
+        super(new DeleteActionDescriptor(), new CreateActionDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/DeleteActionDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/DeleteActionDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..1473e4a191d89e4ec4763f41dcb6a9483b50da8f
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/DeleteActionDescriptor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class DeleteActionDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/action/" + getArg();
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "DELETE";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/GetActionByIdApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/GetActionByIdApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fd97ebf034e948197975d8344afbea52a8eaacb
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/GetActionByIdApiTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Action;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import org.opengroup.osdu.register.util.RetrieveApiTestTemplate;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public final class GetActionByIdApiTest extends RetrieveApiTestTemplate {
+
+    public GetActionByIdApiTest() {
+        super(new GetActionDescriptor(), new DeleteActionDescriptor(), new CreateActionDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+       // String url = Config.Instance().securePushUrl + "api/register/v1/test/challenge";
+
+        String url = "";
+        String pushPath = System.getProperty("REGISTER_CUSTOM_PUSH_URL", System.getenv("REGISTER_CUSTOM_PUSH_URL"));
+        if( Strings.isNullOrEmpty(pushPath)) {
+            url= Config.Instance().securePushUrl + "api/register/v1/test/challenge";
+        }
+        else
+        {
+            url = pushPath;
+        }
+        String body = response.getEntity(String.class);
+        Action action = new Gson().fromJson(body, Action.class);
+        assertEquals("My test listener.", action.description);
+        assertTrue(action.contactEmail, action.contactEmail.equals("integrationtest@test.com"));
+        assertEquals("My listener", action.name);
+        assertEquals(url, action.url);
+        assertEquals(url, action.img);
+        assertEquals(1, action.filter.entityType.size());
+        assertEquals("*", action.filter.entityType.get(0));
+
+        assertEquals(1, action.filter.source.size());
+        assertEquals("*", action.filter.source.get(0));
+
+        assertEquals(1, action.filter.version.size());
+        assertEquals("*", action.filter.version.get(0));
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/GetActionDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/GetActionDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..50d398715698e20c906862bc9b751a985ca461d1
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/GetActionDescriptor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class GetActionDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/action/" + getArg();
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/RetrieveActionApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/RetrieveActionApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..db30aca4a2d1663e35b4d249d5fcca9ae11bbd4a
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/RetrieveActionApiTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.util.BaseTestTemplate;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+
+public final class RetrieveActionApiTest extends BaseTestTemplate {
+    protected RestDescriptor createDescriptor;
+    protected RestDescriptor deleteDescriptor;
+    private String id = "retrieveactiontest" + System.currentTimeMillis();
+
+    public RetrieveActionApiTest() {
+        super(new RetrieveActionDescriptor());
+        this.createDescriptor = new CreateActionDescriptor();
+        this.deleteDescriptor = new DeleteActionDescriptor();
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        deleteDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        createDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        createDescriptor.run(ext, testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/RetrieveActionDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/RetrieveActionDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b729a499d643eb527fa1b7c8ffcdfd07a3870bfa
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/RetrieveActionDescriptor.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class RetrieveActionDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/action:retrieve";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "POST";
+    }
+
+    @Override
+    public String getValidBody() {
+        String kind = "tenant1:source:type:1.0.0";
+        return "{\n" +
+                "\t\"id\": \"" + getArg() + "\",\n" +
+                "\t\"kind\": \"" + kind + "\",\n" +
+                "\t\"data\": {\n" +
+                "\t\"msg\": \"hello\"\n}" +
+                "}";
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/TestActionApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/TestActionApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..913290efb846ab187d0cdbf6be016349feaf9280
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/action/TestActionApiTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017-2020, 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.register.action;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.ParsedAction;
+import org.opengroup.osdu.register.model.TestPayload;
+import org.opengroup.osdu.register.model.ValidationErrorResponse;
+import org.opengroup.osdu.register.util.TestBase;
+import org.opengroup.osdu.register.util.TestPayloadReader;
+import org.opengroup.osdu.register.util.TestHttpClient;
+import org.opengroup.osdu.register.util.TestUtils;
+import com.sun.jersey.api.client.ClientResponse;
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+
+import javax.ws.rs.HttpMethod;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.junit.Assert.*;
+
+public final class TestActionApiTest extends TestBase {
+
+    private static final String PATH = "api/register/v1/action:test";
+
+    private TestPayloadReader reader = new TestPayloadReader();
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Test
+    public void should_return20X_when_usingCredentialsWithPermission() throws Exception {
+        String validPayload = reader.getTestPayload("actionApi/validTestAction.json");
+
+        ClientResponse response = TestUtils.send(PATH, HttpMethod.POST, testUtils.getOpsAccessToken(), validPayload, "");
+        assertEquals(HttpStatus.SC_OK, response.getStatus());
+
+        String body = response.getEntity(String.class);
+        ParsedAction parsedAction = new Gson().fromJson(body, ParsedAction.class);
+        assertEquals("https://myapp.osdu.opengroup.org/action/abc123", parsedAction.url);
+        assertTrue(Strings.isNullOrEmpty(parsedAction.errors));
+    }
+
+    @Test
+    public void should_return40XResponseCode_when_makingRequest_withInvalidPayload() throws Exception {
+        List<TestPayload> payloadList = new ArrayList<>();
+        payloadList.add(TestPayload.builder()
+                .expectedErrors(Arrays.asList("action.url must be a valid URL", "testPayload must not be null"))
+                .payloadFileName("actionApi/invalidUrlTestActionPayload.json").build());
+        payloadList.add(TestPayload.builder()
+                .expectedErrors(Arrays.asList("action.url must be a valid URL"))
+                .payloadFileName("actionApi/nonHttpsTestAction.json").build());
+        payloadList.add(TestPayload.builder()
+                .expectedErrors(Arrays.asList("action.filter Found empty filter values. Must provide a filter value. Use '*' if you want to match all values for a filter property."))
+                .payloadFileName("actionApi/invalidFilterEntityTypeTestAction.json").build());
+        payloadList.add(TestPayload.builder()
+                .expectedErrors(Arrays.asList("action.name must match \"^[A-Za-z0-9- ]{2,50}\"", "action.name must not be empty"))
+                .payloadFileName("actionApi/invalidNameTestAction.json").build());
+
+        for (TestPayload payload : payloadList) {
+            makeRequestWithInvalidPayload(payload.getExpectedErrors(), payload.getPayloadFileName());
+        }
+    }
+
+    public void makeRequestWithInvalidPayload(List<String> expectedErrors, String payloadFileName) throws Exception {
+        String payload = reader.getTestPayload(payloadFileName);
+
+        ClientResponse response = TestUtils.send(PATH, HttpMethod.POST, testUtils.getOpsAccessToken(), payload, "");
+        assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
+        String body = response.getEntity(String.class);
+        ValidationErrorResponse validationErrorResponse = new Gson().fromJson(body, ValidationErrorResponse.class);
+        List<String> actualErrors = new Gson().fromJson(validationErrorResponse.getMessage(), new TypeToken<List<String>>() {
+        }.getType());
+        assertThat(expectedErrors, containsInAnyOrder(actualErrors.toArray()));
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/config/OpenIDProviderConfig.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/config/OpenIDProviderConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f2e98e72ca1b213cbba8208e3023ab486975c0d
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/config/OpenIDProviderConfig.java
@@ -0,0 +1,127 @@
+/*
+  Copyright 2002-2022 Google LLC
+  Copyright 2002-2022 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.register.config;
+
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+import com.nimbusds.oauth2.sdk.http.HTTPResponse;
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderConfigurationRequest;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+public class OpenIDProviderConfig {
+
+  private String opsClientId;
+  private String opsClientSecret;
+  private String adminClientId;
+  private String adminClientSecret;
+  private String editorClientId;
+  private String editorClientSecret;
+  private String noAccessClientId;
+  private String noAccessClientSecret;
+  private String url;
+  private final String[] scopes = {"openid"};
+  private static final OpenIDProviderConfig openIDProviderConfig = new OpenIDProviderConfig();
+  private static OIDCProviderMetadata providerMetadata;
+
+  public static OpenIDProviderConfig Instance() {
+    try {
+      openIDProviderConfig.opsClientId = System.getProperty("OPS_OPENID_PROVIDER_CLIENT_ID",
+          System.getenv("OPS_OPENID_PROVIDER_CLIENT_ID"));
+      openIDProviderConfig.opsClientSecret = System.getProperty(
+          "OPS_OPENID_PROVIDER_CLIENT_SECRET",
+          System.getenv("OPS_OPENID_PROVIDER_CLIENT_SECRET"));
+
+      openIDProviderConfig.adminClientId = System.getProperty(
+          "ADMIN_OPENID_PROVIDER_CLIENT_ID",
+          System.getenv("ADMIN_OPENID_PROVIDER_CLIENT_ID"));
+      openIDProviderConfig.adminClientSecret = System.getProperty(
+          "ADMIN_OPENID_PROVIDER_CLIENT_SECRET",
+          System.getenv("ADMIN_OPENID_PROVIDER_CLIENT_SECRET"));
+
+      openIDProviderConfig.editorClientId = System.getProperty(
+          "EDITOR_OPENID_PROVIDER_CLIENT_ID",
+          System.getenv("EDITOR_OPENID_PROVIDER_CLIENT_ID"));
+      openIDProviderConfig.editorClientSecret = System.getProperty(
+          "EDITOR_OPENID_PROVIDER_CLIENT_SECRET",
+          System.getenv("EDITOR_OPENID_PROVIDER_CLIENT_SECRET"));
+
+      openIDProviderConfig.noAccessClientId = System.getProperty(
+          "NO_ACCESS_OPENID_PROVIDER_CLIENT_ID",
+          System.getenv("NO_ACCESS_OPENID_PROVIDER_CLIENT_ID"));
+      openIDProviderConfig.noAccessClientSecret = System.getProperty(
+          "NO_ACCESS_OPENID_PROVIDER_CLIENT_SECRET",
+          System.getenv("NO_ACCESS_OPENID_PROVIDER_CLIENT_SECRET"));
+
+      openIDProviderConfig.url =
+          System.getProperty("TEST_OPENID_PROVIDER_URL", System.getenv("TEST_OPENID_PROVIDER_URL"));
+      Issuer issuer = new Issuer(openIDProviderConfig.url);
+      OIDCProviderConfigurationRequest request = new OIDCProviderConfigurationRequest(issuer);
+      HTTPRequest httpRequest = request.toHTTPRequest();
+      HTTPResponse httpResponse = httpRequest.send();
+      providerMetadata = OIDCProviderMetadata.parse(httpResponse.getContentAsJSONObject());
+    } catch (Exception e) {
+      throw new RuntimeException("Malformed token provider configuration", e);
+    }
+    return openIDProviderConfig;
+  }
+
+  public String getOpsClientId() {
+    return opsClientId;
+  }
+
+  public String getOpsClientSecret() {
+    return opsClientSecret;
+  }
+
+  public String getAdminClientId() {
+    return adminClientId;
+  }
+
+  public String getAdminClientSecret() {
+    return adminClientSecret;
+  }
+
+  public String getEditorClientId() {
+    return editorClientId;
+  }
+
+  public String getEditorClientSecret() {
+    return editorClientSecret;
+  }
+
+  public String getNoAccessClientId() {
+    return noAccessClientId;
+  }
+
+  public String getNoAccessClientSecret() {
+    return noAccessClientSecret;
+  }
+
+  public String getUrl() {
+    return url;
+  }
+
+  public String[] getScopes() {
+    return scopes;
+  }
+
+  public OIDCProviderMetadata getProviderMetadata() {
+    return providerMetadata;
+  }
+}
+
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/CreateDdmsDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/CreateDdmsDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ff25d1557b7bca96e98ef3d9f1dc01a768f8890
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/CreateDdmsDescriptor.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import org.opengroup.osdu.register.util.TestPayloadReader;
+
+public class CreateDdmsDescriptor extends RestDescriptor {
+    private final TestPayloadReader reader = new TestPayloadReader();
+
+    @Override
+    public String getPath() {
+        return "api/register/v1/ddms";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "POST";
+    }
+
+    @Override
+    public String getValidBody() {
+        return reader.getCreateRequestPayload("createDdmsApi/validCreateDdmsRequestBody.json", getArg(), Config.Instance().OsduTenant);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/CreateRegistrationApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/CreateRegistrationApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..23b03bb1d1ab111f3b34fbb8f58f2dc73fcb4f4e
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/CreateRegistrationApiTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Ddms;
+import org.opengroup.osdu.register.util.CreateApiTestTemplate;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import static org.junit.Assert.*;
+
+public final class CreateRegistrationApiTest extends CreateApiTestTemplate {
+
+    public CreateRegistrationApiTest() {
+        super(new DeleteDdmsDescriptor(), new CreateDdmsDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String body = response.getEntity(String.class);
+        Ddms ddms = new Gson().fromJson(body, Ddms.class);
+        assertEquals(getId(), ddms.id);
+        assertEquals("My test ddms.", ddms.description);
+        assertTrue(ddms.contactEmail, ddms.contactEmail.equals("test@test.com"));
+        assertNotNull(ddms.createdDateTimeEpoch);
+        assertEquals("logDDMS", ddms.name);
+        assertEquals(1, ddms.interfaces.size());
+        assertEquals("wellbore", ddms.interfaces.iterator().next().entityType);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/DeleteDdmsDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/DeleteDdmsDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b0b25ed424aa739aebf054546c7caf77ad6ccf9
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/DeleteDdmsDescriptor.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class DeleteDdmsDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/ddms/" + getArg();
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "DELETE";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/DeleteRegistrationApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/DeleteRegistrationApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ca508344098b8fe39751b37635bbed43a0bde47
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/DeleteRegistrationApiTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.util.DeleteApiTestTemplate;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+public final class DeleteRegistrationApiTest extends DeleteApiTestTemplate {
+
+    public DeleteRegistrationApiTest() {
+        super(new DeleteDdmsDescriptor(), new CreateDdmsDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetConsumptionByIdApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetConsumptionByIdApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..aea933c8f3c3a51bcdb104949578856419628144
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetConsumptionByIdApiTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.util.ConsumptionApiTemplate;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+public final class GetConsumptionByIdApiTest extends ConsumptionApiTemplate {
+
+    public GetConsumptionByIdApiTest() {
+        super(new GetRedirectEndpointByIdDescriptor(), new DeleteDdmsDescriptor(), new CreateDdmsDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetDdmsByIdDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetDdmsByIdDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..91fa85fdd5b9b81dba78e9429a3e3142d13dbae3
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetDdmsByIdDescriptor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class GetDdmsByIdDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/ddms/" + getArg();
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetRedirectEndpointByIdDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetRedirectEndpointByIdDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e761d6e5c0d02291681113a1b80dda4d52ef12c
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetRedirectEndpointByIdDescriptor.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class GetRedirectEndpointByIdDescriptor extends RestDescriptor {
+    private static long NOW;
+    private static String TENANT_ID;
+
+    @Override
+    public String getPath() {
+        return String.format("api/register/v1/ddms/%s/%s/%s", getArg(), getType(), getLocalId());
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+    public String getType() {
+        return "wellbore";
+    }
+
+    public String getLocalId() {
+        NOW = System.currentTimeMillis();
+        TENANT_ID = System.getProperty("OSDU_TENANT", System.getenv("OSDU_TENANT"));
+        if (TENANT_ID == null) {
+            TENANT_ID = "opendes";
+        }
+        return TENANT_ID + ":test:1.1." + NOW;
+    }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetRegistrationByIdApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetRegistrationByIdApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..18d277d853b1318fd33d4ffdda7c92cd5a560e1b
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/GetRegistrationByIdApiTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Ddms;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import org.opengroup.osdu.register.util.RetrieveApiTestTemplate;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public final class GetRegistrationByIdApiTest extends RetrieveApiTestTemplate {
+
+    public GetRegistrationByIdApiTest() {
+        super(new GetDdmsByIdDescriptor(), new DeleteDdmsDescriptor(), new CreateDdmsDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String body = response.getEntity(String.class);
+        Ddms ddms = new Gson().fromJson(body, Ddms.class);
+        assertEquals("My test ddms.", ddms.description);
+        assertTrue(ddms.contactEmail, ddms.contactEmail.equals("test@test.com"));
+        assertEquals("logDDMS", ddms.name);
+        assertEquals(1, ddms.interfaces.size());
+        assertEquals("wellbore", ddms.interfaces.iterator().next().entityType);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/QueryDdmsByTypeDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/QueryDdmsByTypeDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..15a0228185c3a2992ae1668876d01c059a446077
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/QueryDdmsByTypeDescriptor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class QueryDdmsByTypeDescriptor extends RestDescriptor {
+
+    @Override
+    public String getPath() {
+        return "api/register/v1/ddms";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+    @Override
+    public String getQuery() {
+        return "?type=" + getArg();
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/QueryDdmsByTypeTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/QueryDdmsByTypeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2112cdeaa15f1322b8718170763d68e360d86328
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/ddms/QueryDdmsByTypeTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2017-2020, 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.register.ddms;
+
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Ddms;
+import org.opengroup.osdu.register.util.BaseTestTemplate;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public final class QueryDdmsByTypeTest extends BaseTestTemplate {
+
+    public QueryDdmsByTypeTest() {
+        super(new QueryDdmsByTypeDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    private String id = "querytest" + System.currentTimeMillis();
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        new DeleteDdmsDescriptor().run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        ClientResponse response = new CreateDdmsDescriptor().run(getId(), testUtils.getOpsAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 201, response.getStatus());
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+
+    @Override
+    public void should_return20XResponseCode_when_makingValidHttpsRequest() throws Exception {
+        createResource();
+        ClientResponse response = descriptor.run("wellbore", testUtils.getOpsAccessToken());
+        assertEquals(error(""), expectedOkResponseCode(), response.getStatus());
+        validate20XResponse(response, descriptor);
+
+        response = descriptor.run("wellb", testUtils.getOpsAccessToken());
+        assertEquals(error(""), expectedOkResponseCode(), response.getStatus());
+        String body = response.getEntity(String.class);
+        Ddms[] ddmsArr = new Gson().fromJson(body, Ddms[].class);
+        List<Ddms> allDms = Arrays.asList(ddmsArr);
+        assertEquals(0, allDms.size());
+
+        deleteResource();
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String body = response.getEntity(String.class);
+        Ddms[] ddmsArr = new Gson().fromJson(body, Ddms[].class);
+        List<Ddms> allDms = Arrays.asList(ddmsArr);
+        assertTrue(allDms.size() >= 1);
+
+        List<Ddms> ddms = allDms.stream().filter(f -> f.id.equalsIgnoreCase(getId())).collect(Collectors.toList());
+        assertEquals(1, ddms.size());
+        assertEquals("My test ddms.", ddms.get(0).description);
+        assertTrue(ddms.get(0).contactEmail, ddms.get(0).contactEmail.equals("test@test.com"));
+        assertEquals("logDDMS", ddms.get(0).name);
+        assertEquals(1, ddms.get(0).interfaces.size());
+        assertEquals("wellbore", ddms.get(0).interfaces.iterator().next().entityType);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Action.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Action.java
new file mode 100644
index 0000000000000000000000000000000000000000..0092d64197d14b86cdcd5c5c6372304269b6a8f1
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Action.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Action {
+    public String id;
+    public String name;
+    public String description;
+    public String url;
+    public String img;
+    public String contactEmail;
+    public Timestamp createdOnEpoch = Timestamp.from(Instant.now());
+    public Filter filter = new Filter();
+
+    public class Filter {
+        public List<String> entityType = new ArrayList<>();
+        public List<String> source = new ArrayList<>();
+        public List<String> version = new ArrayList<>();
+    }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/DataEcosystemReference.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/DataEcosystemReference.java
new file mode 100644
index 0000000000000000000000000000000000000000..4820b435695687ca2304c026b2d60e3588eab5fe
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/DataEcosystemReference.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class DataEcosystemReference {
+    private String dataPartitionId;
+    private String ddmsId;
+    private String ddmsRecordLocalId;
+
+    public String getReferenceId() {
+        return String.format("%s:%s:%s", this.dataPartitionId, this.ddmsId, this.ddmsRecordLocalId);
+    }
+
+    public DataEcosystemReference(String dataPartitionId, String ddmsId, String ddmsRecordLocalId) {
+        this.dataPartitionId = dataPartitionId;
+        this.ddmsId = ddmsId;
+        this.ddmsRecordLocalId = ddmsRecordLocalId;
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Ddms.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Ddms.java
new file mode 100644
index 0000000000000000000000000000000000000000..e22063f8529bbe12c70a3bfa18861c0370344ffa
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Ddms.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+import java.sql.Timestamp;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class Ddms {
+    public String id;
+
+    public String name;
+
+    public String description;
+
+    public String contactEmail;
+
+    public Timestamp createdDateTimeEpoch;
+
+    public Set<RegisteredInterface> interfaces = new HashSet<>();
+
+    public class RegisteredInterface {
+        public String entityType;
+
+        public Map<String, Object> schema;
+    }
+}
+
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/ParsedAction.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/ParsedAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ce04922a1561e56d0d5fda853682e5a81c462ce
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/ParsedAction.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+public class ParsedAction {
+    public String url;
+    public String errors;
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Subscriber.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Subscriber.java
new file mode 100644
index 0000000000000000000000000000000000000000..44a8ac49def08c90b8d40059854ccb2f1b9d66e3
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Subscriber.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+public class Subscriber {
+    public String id;
+    public String name;
+    public String description;
+    public String topic;
+    public String pushEndpoint;
+    public String notificationId;
+    public String createdBy;
+}
+
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/TenantResult.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/TenantResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a1808787c95284f16e17e35238c9e242181e086
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/TenantResult.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TenantResult {
+    public List<String> errors = new ArrayList<>();
+    public String correlationId = "";
+    public String tenant = "";
+    public boolean pass = true;
+
+    public void addError(String error) {
+        errors.add(error);
+        pass = false;
+    }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/TestPayload.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/TestPayload.java
new file mode 100644
index 0000000000000000000000000000000000000000..d01a311aaf2d3b136825375ba8f664712dd5a844
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/TestPayload.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@Builder
+public class TestPayload {
+    List<String> expectedErrors;
+    String payloadFileName;
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Topic.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Topic.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7b6cb3f81ecc0c7203c0c47e2dc773f786346e4
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/Topic.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+public class Topic {
+    public String name;
+    public String description;
+    public String state;
+    public Object example;
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/ValidationErrorResponse.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/ValidationErrorResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf9c7dd1e63778cc28742dc0730077d569686fac
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/model/ValidationErrorResponse.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-2020, 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.register.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ValidationErrorResponse {
+    private int code;
+    private String reason;
+    private String message;
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/CreateSubscriberApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/CreateSubscriberApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1406920f2a9a77b488fe66961ced90201eeceeb
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/CreateSubscriberApiTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Subscriber;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.CreateApiTestTemplate;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import static org.junit.Assert.*;
+
+public final class CreateSubscriberApiTest extends CreateApiTestTemplate {
+
+    public CreateSubscriberApiTest() {
+        super(new DeleteSubscriberDescriptor(), new CreateSubscriberDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() throws Exception {
+        this.testUtils = new TestHttpClient();
+        deleteResource();
+    }
+
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected String getId() {
+        return Config.Instance().subscriptionId;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+
+        String url = "";
+        String pushPath = System.getProperty("REGISTER_CUSTOM_PUSH_URL1", System.getenv("REGISTER_CUSTOM_PUSH_URL1"));
+        if( Strings.isNullOrEmpty(pushPath)) {
+            url = Config.Instance().PushUrl + "api/register/v1/test/challenge/1";
+        }
+        else
+        {
+            url = pushPath;
+        }
+
+        String body = response.getEntity(String.class);
+
+        Subscriber subscriber = new Gson().fromJson(body, Subscriber.class);
+        assertEquals("My test listener.", subscriber.description);
+        assertEquals("My listener", subscriber.name);
+        assertEquals("records-changed", subscriber.topic);
+        assertFalse(Strings.isNullOrEmpty(subscriber.notificationId));
+        assertEquals(url, subscriber.pushEndpoint);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/CreateSubscriberDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/CreateSubscriberDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..eab10c1109b75ddf9b88f0f5d697356374f0ecdd
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/CreateSubscriberDescriptor.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import com.google.common.base.Strings;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import org.opengroup.osdu.register.util.TestPayloadReader;
+
+import java.util.Base64;
+
+public class CreateSubscriberDescriptor extends RestDescriptor {
+    private final TestPayloadReader reader = new TestPayloadReader();
+    private static String topicName = System.getProperty("TEST_TOPIC_NAME", System.getenv("TEST_TOPIC_NAME"));
+
+    @Override
+    public String getPath() {
+        return "api/register/v1/subscription";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "POST";
+    }
+
+    @Override
+    public String getValidBody() {
+        //String url = Config.Instance().PushUrl + "api/register/v1/test/challenge/1";
+
+        String url = "";
+        String urlExt ="1";
+        if(getArg() == "create" || getArg() == "delete" || getArg() == "get")
+        {
+            urlExt = getArg();
+        }
+        String pushPath = System.getProperty("REGISTER_CUSTOM_PUSH_URL1", System.getenv("REGISTER_CUSTOM_PUSH_URL1"));
+        if( Strings.isNullOrEmpty(pushPath)) {
+            url = Config.Instance().PushUrl + "api/register/v1/test/challenge/"+urlExt;
+        }
+        else
+        {
+            url = pushPath;
+        }
+        String secret = Config.Instance().SUBSCRIBER_SECRET;
+        String subId = genSubscriptionId(url);
+
+        if(Strings.isNullOrEmpty(topicName)) {
+            topicName = "records-changed";
+        }
+
+        return "{\n" +
+                "\t\"id\": \"" + subId + "\",\n" +
+                "\t\"name\": \"My listener\",\n" +
+                "\t\"description\": \"My test listener.\",\n" +
+                "\t\"pushEndpoint\":\"" + url + "\",\n" +
+                "\t\"topic\":\"" + topicName + "\",\n" +
+                "\t\"secret\": {\n" +
+                "\t\t\"secretType\" : \"HMAC\",\n" +
+                "\t\"value\":\"" + secret + "\"\n" +
+                "\t}\n" +
+                "}";
+    }
+    private static String genSubscriptionId(String custom_push_url)
+    {
+        return Base64.getEncoder().encodeToString((topicName+ custom_push_url).getBytes());
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/DeleteSubscriberApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/DeleteSubscriberApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9529c6b956691f346a532400dbce3a927e902587
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/DeleteSubscriberApiTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.DeleteApiTestTemplate;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+public final class DeleteSubscriberApiTest extends DeleteApiTestTemplate {
+
+    public DeleteSubscriberApiTest() {
+        super(new DeleteSubscriberDescriptor(), new CreateSubscriberDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected String getId() {
+        return Config.Instance().subscriptionId;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/DeleteSubscriberDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/DeleteSubscriberDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7893ace93ff075bcbb12f2a63613044048d0087
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/DeleteSubscriberDescriptor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class DeleteSubscriberDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/subscription/" + getArg();
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "DELETE";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/GetSubscriberByIdApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/GetSubscriberByIdApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..09f33fc9449002e03a84b96f1365198d4e0c26e6
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/GetSubscriberByIdApiTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Subscriber;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import org.opengroup.osdu.register.util.RetrieveApiTestTemplate;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public final class GetSubscriberByIdApiTest extends RetrieveApiTestTemplate {
+
+    public GetSubscriberByIdApiTest() {
+        super(new GetSubscriberDescriptor(), new DeleteSubscriberDescriptor(), new CreateSubscriberDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() throws Exception {
+        this.testUtils = new TestHttpClient();
+        deleteResource();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected String getId() {
+        return Config.Instance().subscriptionId;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String body = response.getEntity(String.class);
+        Subscriber subscriber = new Gson().fromJson(body, Subscriber.class);
+        assertEquals("My test listener.", subscriber.description);
+        assertEquals("My listener", subscriber.name);
+        assertEquals("records-changed", subscriber.topic);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/GetSubscriberDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/GetSubscriberDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f5ef78f34a70281a9446b2ab41af2cf5c5af41e
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/GetSubscriberDescriptor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class GetSubscriberDescriptor extends RestDescriptor {
+    @Override
+    public String getPath() {
+        return "api/register/v1/subscription/" + getArg();
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/ListTopicsApiTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/ListTopicsApiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d4b5bf2935a904308cdf1502bd8f0ba1dd3c6c2
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/ListTopicsApiTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.lang.StringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Topic;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import org.opengroup.osdu.register.util.BaseTestTemplate;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public final class ListTopicsApiTest extends BaseTestTemplate {
+    public static final String TOPIC_NAME = System.getProperty("TEST_TOPIC_NAME",
+            StringUtils.isNotEmpty(System.getenv("TEST_TOPIC_NAME")) ? System.getenv("TEST_TOPIC_NAME") : "records-changed");
+
+
+    public ListTopicsApiTest() {
+        super(new ListTopicsDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        this.testUtils = new TestHttpClient();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return false;
+    }
+
+    @Override
+    protected String getId() {
+        return "";
+    }
+
+    @Override
+    protected void deleteResource() {
+    }
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+    }
+
+    @Override
+    protected void createResource() {
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String body = response.getEntity(String.class);
+        java.lang.reflect.Type listType = new TypeToken<ArrayList<Topic>>() {
+        }.getType();
+        Gson gson = new Gson();
+        List<Topic> messages = gson.fromJson(body, listType);
+        assertTrue(messages.size() > 0);
+        assertTrue(messages.stream().anyMatch(m -> m.name.equalsIgnoreCase(TOPIC_NAME)));
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/ListTopicsDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/ListTopicsDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..56f026a57a7e1e6b5d5a251ff9a699b5942a93ab
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/ListTopicsDescriptor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class ListTopicsDescriptor extends RestDescriptor {
+
+    @Override
+    public String getPath() {
+        return "api/register/v1/topics";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/QuerySubscriberDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/QuerySubscriberDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..128bbe5870a3c0750f93f94723a8f4d6a5d6a108
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/QuerySubscriberDescriptor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import org.opengroup.osdu.register.util.RestDescriptor;
+
+public class QuerySubscriberDescriptor extends RestDescriptor {
+
+    @Override
+    public String getPath() {
+        return "api/register/v1/subscription";
+    }
+
+    @Override
+    public String getHttpMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getValidBody() {
+        return "";
+    }
+
+    @Override
+    public String getQuery() {
+        return "?notificationId=" + getArg();
+    }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/QuerySubscriberTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/QuerySubscriberTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d598bd07c1dca8c85081aab6589b493f30e24e46
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/subscriber/QuerySubscriberTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2017-2020, 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.register.subscriber;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.register.model.Subscriber;
+import org.opengroup.osdu.register.util.BaseTestTemplate;
+import org.opengroup.osdu.register.util.Config;
+import org.opengroup.osdu.register.util.RestDescriptor;
+import com.sun.jersey.api.client.ClientResponse;
+import org.opengroup.osdu.register.util.TestHttpClient;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public final class QuerySubscriberTest extends BaseTestTemplate {
+
+    Subscriber createdSubscriber;
+    DeleteSubscriberDescriptor deleteDescriptor = new DeleteSubscriberDescriptor();
+
+    public QuerySubscriberTest() {
+        super(new QuerySubscriberDescriptor());
+    }
+
+    @Before
+    @Override
+    public void setup() throws Exception {
+        this.testUtils = new TestHttpClient();
+        deleteResource();
+    }
+
+    @After
+    @Override
+    public void tearDown() {
+        this.testUtils = null;
+    }
+
+    @Override
+    protected boolean isDataInTenant() {
+        return true;
+    }
+
+    @Override
+    protected String getId() {
+        return Config.Instance().subscriptionId;
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        deleteDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        // do nothing
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        ClientResponse response = new CreateSubscriberDescriptor().run(getId(), testUtils.getOpsAccessToken());
+        String body = response.getEntity(String.class);
+        createdSubscriber = new Gson().fromJson(body, Subscriber.class);
+        assertEquals(error(body), 201, response.getStatus());
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+
+    @Override
+    public void should_return20XResponseCode_when_makingValidHttpsRequest() throws Exception {
+        createResource();
+        ClientResponse response = descriptor.run(createdSubscriber.notificationId, testUtils.getOpsAccessToken());
+        assertEquals(error(""), expectedOkResponseCode(), response.getStatus());
+        validate20XResponse(response, descriptor);
+
+        response = descriptor.run("de-randomNotificationId", testUtils.getOpsAccessToken());
+        assertEquals(error(""), expectedOkResponseCode(), response.getStatus());
+        String body = response.getEntity(String.class);
+        Subscriber[] dmsArr = new Gson().fromJson(body, Subscriber[].class);
+        List<Subscriber> allDms = Arrays.asList(dmsArr);
+        assertEquals(0, allDms.size());
+
+        deleteResource();
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        String body = response.getEntity(String.class);
+        Subscriber[] SubscriberArr = new Gson().fromJson(body, Subscriber[].class);
+        List<Subscriber> subscriberList = Arrays.asList(SubscriberArr);
+        assertTrue(subscriberList.size() >= 1);
+
+        List<Subscriber> subscribers = subscriberList.stream().filter(f -> f.id.equalsIgnoreCase(getId())).collect(Collectors.toList());
+        assertEquals(1, subscribers.size());
+        //String url = Config.Instance().PushUrl + "api/register/v1/test/challenge/1";
+
+
+        String url = "";
+        String pushPath = System.getProperty("REGISTER_CUSTOM_PUSH_URL1", System.getenv("REGISTER_CUSTOM_PUSH_URL1"));
+        if( Strings.isNullOrEmpty(pushPath)) {
+            url = Config.Instance().PushUrl + "api/register/v1/test/challenge/1";
+        }
+        else
+        {
+            url = pushPath;
+        }
+        assertEquals(1, subscribers.size());
+        assertEquals(url, subscribers.get(0).pushEndpoint);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/BaseTestTemplate.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/BaseTestTemplate.java
new file mode 100644
index 0000000000000000000000000000000000000000..674e46ca8d265d61bffa3da9376e682c86a816fa
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/BaseTestTemplate.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.sun.jersey.api.client.ClientResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@Slf4j
+public abstract class BaseTestTemplate extends TestBase {
+
+    public BaseTestTemplate(RestDescriptor descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    protected RestDescriptor descriptor;
+
+    protected abstract boolean isDataInTenant();
+
+    protected abstract String  getId();
+
+
+    protected String error(String body) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+        String subsAsJson = null;
+        try {
+            subsAsJson = objectMapper.writeValueAsString(body);
+            JsonNode jsonNode = objectMapper.readTree(subsAsJson);
+            // removing Secret before logging
+            if (jsonNode != null && jsonNode.has("secret")) {
+                ((ObjectNode) jsonNode).remove("secret");
+            }
+        } catch (Exception e) {
+            log.error("Error while parsing response body", e);
+        }
+        log.info(String.format("error method call: -----------------------------------------------------------------------\n%s: %s %s \nResponse Body: %s", descriptor.getHttpMethod(), descriptor.getPath(), descriptor.getQuery(), subsAsJson));
+        return String.format("%s: %s %s \nResponse Body: %s", descriptor.getHttpMethod(), descriptor.getPath(), descriptor.getQuery(), body);
+    }
+
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        if (response.getStatus() != 204)
+            log.info(String.format("Response body: %s", response.getEntity(String.class)));
+    }
+
+    protected abstract void deleteResource() throws Exception;
+    protected abstract void deleteResourcewitharg(String ext) throws Exception;
+
+    protected abstract void createResource() throws Exception;
+
+    protected abstract void createResourcewitharg(String ext) throws Exception;
+
+    protected abstract int expectedOkResponseCode();
+
+    @Test
+    public void should_return401_when_noAccessOnCustomerTenantOps() throws Exception {
+        ClientResponse response = descriptor.runOnCustomerTenant(getId(), testUtils.getOpsAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 401, response.getStatus());
+    }
+
+    @Test
+    public void should_return401_when_noAccessOnCustomerTenantAdm() throws Exception {
+        ClientResponse response = descriptor.runOnCustomerTenant(getId(), testUtils.getAdmAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 401, response.getStatus());
+    }
+
+    @Test
+    public void should_return401_when_noAccessOnCustomerTenantEditor() throws Exception {
+        ClientResponse response = descriptor.runOnCustomerTenant(getId(), testUtils.getEditorAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 401, response.getStatus());
+    }
+
+    @Test
+    public void should_return401_when_accessingWithCredentialsWithoutPermission() throws Exception {
+        ClientResponse response = descriptor.run(getId(), testUtils.getNoDataAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 401, response.getStatus());
+    }
+
+    @Ignore("Issue reported in GL")
+    @Test
+    public void should_return20X_when_usingCredentialsWithPermissionOps() throws Exception {
+        should_return20X_when_usingCredentialsWithPermission(testUtils.getOpsAccessToken());
+    }
+
+    public void should_return20X_when_usingCredentialsWithPermission(String token) throws Exception {
+        createResource();
+        ClientResponse response = descriptor.run(getId(), token);
+        deleteResource();
+
+        assertEquals("[GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH]", response.getHeaders().getFirst("Access-Control-Allow-Methods"));
+
+        assertEquals("[origin, content-type, accept, authorization, data-partition-id, correlation-id, appkey]", response.getHeaders().getFirst("Access-Control-Allow-Headers"));
+
+        assertEquals("[*]", response.getHeaders().getFirst("Access-Control-Allow-Origin"));
+        assertEquals("[true]", response.getHeaders().getFirst("Access-Control-Allow-Credentials"));
+        assertEquals("DENY", response.getHeaders().getFirst("X-Frame-Options"));
+        assertEquals("1; mode=block", response.getHeaders().getFirst("X-XSS-Protection"));
+        assertEquals("nosniff", response.getHeaders().getFirst("X-Content-Type-Options"));
+        assertEquals("[no-cache, no-store, must-revalidate]", response.getHeaders().getFirst("Cache-Control"));
+        assertEquals("[default-src 'self']", response.getHeaders().getFirst("Content-Security-Policy"));
+        assertEquals("[max-age=31536000; includeSubDomains]", response.getHeaders().getFirst("Strict-Transport-Security"));
+        assertEquals("[0]", response.getHeaders().getFirst("Expires"));
+        assertEquals(error(response.getStatus() == 204 ? "" : response.getEntity(String.class)), expectedOkResponseCode(), response.getStatus());
+    }
+
+    @Test
+    public void should_returnOk_when_makingHttpOptionsRequest() throws Exception {
+        ClientResponse response = descriptor.runOptions(getId(), testUtils.getOpsAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 200, response.getStatus());
+    }
+
+    @Ignore("Issue reported in GL")
+    @Test
+    public void should_return307_when_makingHttpRequest() throws Exception {
+        ClientResponse response = descriptor.runHttp(getId(), testUtils.getOpsAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 307, response.getStatus());
+    }
+
+    @Test
+    public void should_return20XResponseCode_when_makingValidHttpsRequest() throws Exception {
+        createResource();
+        ClientResponse response = descriptor.run(getId(), testUtils.getOpsAccessToken());
+        deleteResource();
+        assertEquals(error(""), expectedOkResponseCode(), response.getStatus());
+        validate20XResponse(response, descriptor);
+    }
+
+    @Test
+    public void should_return400_when_makingHttpRequestWithoutToken() throws Exception {
+        ClientResponse response = descriptor.run(getId(), "");
+
+        // Check if the response status is 400, 401, or 403, since different CSPs use different status codes
+        assertTrue(error(response.getEntity(String.class)), response.getStatus() == 400 || response.getStatus() == 401 || response.getStatus() == 403);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/Config.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/Config.java
new file mode 100644
index 0000000000000000000000000000000000000000..df20f5a62c81173181af03535e5522fc9af1f94e
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/Config.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.google.common.base.Strings;
+
+import java.util.Base64;
+
+public class Config {
+    public String HostUrl;
+    public String securePushUrl;
+    public String PushUrl;
+    public String OsduTenant;
+    public String subscriptionId;
+    public String ClientTenant;
+    public String SUBSCRIBER_SECRET = System.getProperty("SUBSCRIBER_SECRET", System.getenv("SUBSCRIBER_SECRET"));
+    private static Config config = new Config();
+
+    public static Config Instance() {
+        config.ClientTenant = getEnvironmentVariableOrDefaultValue("CLIENT_TENANT","nonexistenttenant");
+        config.OsduTenant = getEnvironmentVariableOrDefaultValue("OSDU_TENANT","opendes");
+        String custom_push_url = System.getProperty("REGISTER_CUSTOM_PUSH_URL1", System.getenv("REGISTER_CUSTOM_PUSH_URL1"));
+        config.subscriptionId = getEnvironmentVariableOrDefaultValue("SUBSCRIPTION_ID",
+                   genSubscriptionId(custom_push_url));
+
+        config.HostUrl = System.getProperty("REGISTER_BASE_URL", System.getenv("REGISTER_BASE_URL"));
+        config.securePushUrl = config.HostUrl;
+        config.PushUrl = config.HostUrl;
+
+        return config;
+    }
+
+    private static String getEnvironmentVariableOrDefaultValue(String key, String defaultValue) {
+        String environmentVariable = getEnvironmentVariable(key);
+        if (environmentVariable == null) {
+            environmentVariable = defaultValue;
+        }
+        return environmentVariable;
+    }
+
+    private static String getEnvironmentVariable(String propertyKey) {
+        return System.getProperty(propertyKey, System.getenv(propertyKey));
+    }
+
+    private static String genSubscriptionId(String custom_push_url)
+    {
+        return Base64.getEncoder().encodeToString(("records-changed"+ custom_push_url).getBytes());
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/ConsumptionApiTemplate.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/ConsumptionApiTemplate.java
new file mode 100644
index 0000000000000000000000000000000000000000..c111c3af2e0e066ddc65738f35d17adff8f7ad61
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/ConsumptionApiTemplate.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.sun.jersey.api.client.ClientResponse;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opengroup.osdu.register.ddms.DeleteDdmsDescriptor;
+
+import static org.junit.Assert.assertEquals;
+
+public abstract class ConsumptionApiTemplate extends BaseTestTemplate {
+
+    public ConsumptionApiTemplate(RestDescriptor getDescriptor, RestDescriptor deleteDescriptor, RestDescriptor createDescriptor) {
+        super(getDescriptor);
+        this.createDescriptor = createDescriptor;
+        this.deleteDescriptor = deleteDescriptor;
+    }
+
+    private RestDescriptor createDescriptor;
+    private RestDescriptor deleteDescriptor;
+    private String id = "gettest" + System.currentTimeMillis();
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+
+    protected String getRegressionId() {
+        return "ZGF0YS1jaGFuZ2UtdjFodHRwczovL215ZW5kcG9pbnQuY29t";
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        deleteDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        createDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        createDescriptor.run(ext, testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 307;
+    }
+
+
+    @Test
+    public void should_return404_when_accessingDataThatDoesntExist() throws Exception {
+        deleteResource();
+        ClientResponse response = descriptor.run(getId(), testUtils.getOpsAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 404, response.getStatus());
+    }
+
+    @Test
+    public void should_return20X_when_retrievingExistingResource_RegressionTest() throws Exception {
+        new DeleteDdmsDescriptor().run(getRegressionId(), testUtils.getOpsAccessToken());
+
+        createDescriptor.run(getRegressionId(), testUtils.getOpsAccessToken());
+        ClientResponse response = descriptor.run(getRegressionId(), testUtils.getOpsAccessToken());
+        assertEquals(error(""), expectedOkResponseCode(), response.getStatus());
+        validate20XResponse(response, descriptor);
+
+        new DeleteDdmsDescriptor().run(getRegressionId(), testUtils.getOpsAccessToken());
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/CreateApiTestTemplate.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/CreateApiTestTemplate.java
new file mode 100644
index 0000000000000000000000000000000000000000..096dc625d96dacc9898eb9fa9476d47176b62244
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/CreateApiTestTemplate.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.sun.jersey.api.client.ClientResponse;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class CreateApiTestTemplate extends BaseTestTemplate {
+    private final TestPayloadReader reader = new TestPayloadReader();
+
+    public CreateApiTestTemplate(RestDescriptor deleteDescriptor, RestDescriptor createDescriptor) {
+        super(createDescriptor);
+        this.deleteDescriptor = deleteDescriptor;
+    }
+
+    private String id = "createtest" + System.currentTimeMillis();
+    private RestDescriptor deleteDescriptor;
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        deleteDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        deleteDescriptor.run(ext, testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected void createResource() {
+        //do nothing
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 201;
+    }
+
+    @Test
+    public void should_return40XResponseCode_when_makingRequest_withInvalidPayload() throws Exception {
+        ClientResponse response = descriptor.runWithCustomPayload(getId(), reader.getCreateRequestPayload("createDdmsApi/invalidCreateDdmsRequestBody.json", getId(), Config.Instance().OsduTenant), testUtils.getOpsAccessToken());
+        assertEquals(400, response.getStatus());
+        deleteResource();
+    }
+
+    @Test
+    public void should_onlyCreateMax1Resource_and_return409ForTheRest_when_creatingTheSameResourceInParallel() throws Exception {
+        ExecutorService executor = Executors.newFixedThreadPool(8);
+        List<Callable<ClientResponse>> tasks = new ArrayList<>();
+
+        for (int i = 0; i < 8; i++) {
+            Callable<ClientResponse> task = () -> {
+                try {
+                    return descriptor.run(getId(), testUtils.getOpsAccessToken());
+                } catch (Exception ex) {
+                    return null;
+                }
+            };
+            tasks.add(task);
+        }
+
+        List<Future<ClientResponse>> responses = executor.invokeAll(tasks);
+        executor.shutdown();
+        executor.awaitTermination(20, TimeUnit.SECONDS);
+
+        int sucessResponseCount = 0;
+        int non409ErrorResponseCount = 0;
+        for (Future<ClientResponse> future : responses) {
+            if (future.get().getStatus() == expectedOkResponseCode())
+                sucessResponseCount++;
+            else if (future.get().getStatus() != 409)
+                non409ErrorResponseCount++;
+        }
+
+        deleteResource();
+
+        assertTrue(error("Expected 1 successful response. Actual " + sucessResponseCount), sucessResponseCount <= 1);
+        assertEquals(error("Unexpected error response returned"), 0, non409ErrorResponseCount);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/DeleteApiTestTemplate.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/DeleteApiTestTemplate.java
new file mode 100644
index 0000000000000000000000000000000000000000..f10d907d794f71dd8ad2838c4e6dfe1920d24ac7
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/DeleteApiTestTemplate.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.sun.jersey.api.client.ClientResponse;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public abstract class DeleteApiTestTemplate extends BaseTestTemplate {
+
+    public DeleteApiTestTemplate(RestDescriptor deleteDescriptor, RestDescriptor createDescriptor) {
+        super(deleteDescriptor);
+        this.createDescriptor = createDescriptor;
+    }
+
+    private RestDescriptor createDescriptor;
+    private String id = "deletetest" + System.currentTimeMillis();
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+    @Override
+    protected void validate20XResponse(ClientResponse response, RestDescriptor descriptor) {
+        //do nothing
+    }
+
+    @Override
+    protected void deleteResource() {
+        //do nothingthis api deletes the resources
+    }
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        //do nothing
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        createDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        createDescriptor.run(ext, testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 204;
+    }
+
+    @Test
+    public void should_beAbleToRunApiInParallel() throws Exception {
+        createResource();
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        List<Callable<ClientResponse>> tasks = new ArrayList<>();
+
+        for (int i = 0; i < 10; i++) {
+            Callable<ClientResponse> task = () -> {
+                try {
+                    return descriptor.run(getId(), testUtils.getOpsAccessToken());
+                } catch (Exception ex) {
+                    return null;
+                }
+            };
+            tasks.add(task);
+        }
+
+        List<Future<ClientResponse>> responses = executor.invokeAll(tasks);
+        executor.shutdown();
+        executor.awaitTermination(30, TimeUnit.SECONDS);
+        List<Integer> errors = new ArrayList<>();
+        int sucessResponseCount = 0;
+        int non404or409ErrorResponseCount = 0;
+        for (Future<ClientResponse> future : responses) {
+            if (future.get() == null)
+                fail(String.format("Failed to get response in time for %s %s    %s", descriptor.getHttpMethod(), descriptor.getPath(), descriptor.getArg()));
+            if (future.get().getStatus() == expectedOkResponseCode())
+                sucessResponseCount++;
+            else if (future.get().getStatus() != 409 && future.get().getStatus() != 404) {
+                non404or409ErrorResponseCount++;
+                errors.add(future.get().getStatus());
+            }
+        }
+
+        assertTrue(error("Expected 1 successful response. Actual " + sucessResponseCount), sucessResponseCount <= 1);
+        assertEquals(error("Unexpected error response returned " + errors.toString()), 0, non404or409ErrorResponseCount);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/HealthCheckTest.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/HealthCheckTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b585c865513b2f05a338ab4202d883b8b39c6f2e
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/HealthCheckTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017-2024, 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.register.util;
+
+import com.sun.jersey.api.client.ClientResponse;
+import org.junit.Test;
+import org.springframework.http.HttpMethod;
+
+import static org.junit.Assert.assertEquals;
+
+public abstract class HealthCheckTest extends BaseTestTemplate {
+
+    public HealthCheckTest(RestDescriptor getDescriptor) {
+        super(getDescriptor);
+    }
+
+    private String id = "healthtest" + System.currentTimeMillis();
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+    }
+
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+
+    @Test
+    public void should_returnTrailingOk() throws Exception {
+        ClientResponse response =
+                TestUtils.send("api/register/v1/ah/liveness_check/", HttpMethod.GET.name(), this.testUtils.getOpsAccessToken(), "", "");
+        assertEquals(expectedOkResponseCode(), response.getStatus());
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/OpenIDTokenProvider.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/OpenIDTokenProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..76fd1558dd825bfb1ab6b8ca5c2e5da70ca2da98
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/OpenIDTokenProvider.java
@@ -0,0 +1,138 @@
+/*
+  Copyright 2002-2022 Google LLC
+  Copyright 2002-2022 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.register.util;
+
+import com.nimbusds.oauth2.sdk.*;
+import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
+import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
+import com.nimbusds.oauth2.sdk.auth.Secret;
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser;
+import net.minidev.json.JSONObject;
+import org.opengroup.osdu.register.config.OpenIDProviderConfig;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Objects;
+
+public class OpenIDTokenProvider {
+
+  private static final OpenIDProviderConfig openIDProviderConfig = OpenIDProviderConfig.Instance();
+  private static final String ID_TOKEN = "id_token";
+  private final AuthorizationGrant clientGrant = new ClientCredentialsGrant();
+  private final URI tokenEndpointURI;
+  private final Scope scope;
+  private final ClientAuthentication opsClientAuthentication;
+  private final ClientAuthentication adminClientAuthentication;
+  private final ClientAuthentication editorClientAuthentication;
+  private final ClientAuthentication noAccessClientAuthentication;
+
+  public OpenIDTokenProvider() {
+    this.tokenEndpointURI = openIDProviderConfig.getProviderMetadata().getTokenEndpointURI();
+    this.scope = new Scope(openIDProviderConfig.getScopes());
+    this.opsClientAuthentication =
+        new ClientSecretBasic(
+            new ClientID(openIDProviderConfig.getOpsClientId()),
+            new Secret(openIDProviderConfig.getOpsClientSecret())
+        );
+    this.adminClientAuthentication =
+        new ClientSecretBasic(
+            new ClientID(openIDProviderConfig.getAdminClientId()),
+            new Secret(openIDProviderConfig.getAdminClientSecret())
+        );
+    this.editorClientAuthentication =
+        new ClientSecretBasic(
+            new ClientID(openIDProviderConfig.getEditorClientId()),
+            new Secret(openIDProviderConfig.getEditorClientSecret())
+        );
+    this.noAccessClientAuthentication =
+        new ClientSecretBasic(
+            new ClientID(openIDProviderConfig.getNoAccessClientId()),
+            new Secret(openIDProviderConfig.getNoAccessClientSecret())
+        );
+  }
+
+  public String getOpsAccessToken() {
+    try {
+      TokenRequest request =
+          new TokenRequest(this.tokenEndpointURI, this.opsClientAuthentication, this.clientGrant,
+              this.scope);
+      return requestToken(request);
+    } catch (ParseException | IOException e) {
+      throw new RuntimeException(
+          "Unable get credentials from OPS_OPENID_PROVIDER_CLIENT_ID variables", e);
+    }
+  }
+
+  public String getAdminAccessToken() {
+    try {
+      TokenRequest request =
+          new TokenRequest(this.tokenEndpointURI, this.adminClientAuthentication, this.clientGrant,
+              this.scope);
+      return requestToken(request);
+    } catch (ParseException | IOException e) {
+      throw new RuntimeException(
+          "Unable get credentials from ADMIN_OPENID_PROVIDER_CLIENT_ID variables", e);
+    }
+  }
+
+  public String getEditorAccessToken() {
+    try {
+      TokenRequest request =
+          new TokenRequest(this.tokenEndpointURI, this.editorClientAuthentication, this.clientGrant,
+              this.scope);
+      return requestToken(request);
+    } catch (ParseException | IOException e) {
+      throw new RuntimeException(
+          "Unable get credentials from EDITOR_OPENID_PROVIDER_CLIENT_ID variables", e);
+    }
+  }
+
+  public String getNoAccessToken() {
+    try {
+      TokenRequest request =
+          new TokenRequest(this.tokenEndpointURI, this.noAccessClientAuthentication,
+              this.clientGrant, this.scope);
+      return requestToken(request);
+    } catch (ParseException | IOException e) {
+      throw new RuntimeException(
+          "Unable get credentials from ACCESS_OPENID_PROVIDER_CLIENT_ID variables", e);
+    }
+  }
+
+  private String requestToken(TokenRequest tokenRequest) throws ParseException, IOException {
+
+    TokenResponse parse = OIDCTokenResponseParser.parse(tokenRequest.toHTTPRequest().send());
+
+    if (!parse.indicatesSuccess()) {
+      throw new RuntimeException(
+          "Unable get credentials variables, response:" + parse.toErrorResponse().toJSONObject().toJSONString()
+      );
+    }
+
+    JSONObject jsonObject = parse.toSuccessResponse().toJSONObject();
+    String idTokenValue = jsonObject.getAsString(ID_TOKEN);
+    if (Objects.isNull(idTokenValue) || idTokenValue.isEmpty()) {
+      throw new RuntimeException(
+          "Unable get credentials variables, response:" + parse.toErrorResponse().toJSONObject().toJSONString()
+      );
+    }
+    return idTokenValue;
+  }
+
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/RestDescriptor.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/RestDescriptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b669de96f2366f29f836ce47a5119f8abe8989f9
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/RestDescriptor.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+public abstract class RestDescriptor {
+    private String arg = "";
+
+    public String getArg() {
+        return arg;
+    }
+
+    public abstract String getPath();
+
+    public abstract String getHttpMethod();
+
+    public abstract String getValidBody();
+
+    public String getQuery() {
+        return "";
+    }
+
+    public RestDescriptor() {
+    }
+
+    public ClientResponse runHttp(String arg, String accessToken) throws Exception {
+        this.arg = arg;
+        return TestUtils.sendHttp(getPath(), getHttpMethod(), accessToken, getValidBody(), getQuery());
+    }
+
+    public ClientResponse run(String arg, String token) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery());
+    }
+
+    public ClientResponse runWithCustomPayload(String arg, String body, String accessToken) throws Exception {
+        this.arg = arg;
+        return TestUtils.send(getPath(), getHttpMethod(), accessToken, body, getQuery());
+    }
+
+    public ClientResponse runOnCustomerTenant(String id, String token) throws Exception {
+        this.arg = id;
+        return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), TestUtils.getCustomerTenantHeaders());
+    }
+
+    public ClientResponse runOptions(String id, String accessToken) throws Exception {
+        this.arg = id;
+        return TestUtils.send(getPath(), "OPTIONS", accessToken, "", "");
+    }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/RetrieveApiTestTemplate.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/RetrieveApiTestTemplate.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc83aeff743d8b3b16a99fb818774cd531d8b761
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/RetrieveApiTestTemplate.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.sun.jersey.api.client.ClientResponse;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class RetrieveApiTestTemplate extends BaseTestTemplate {
+
+    public RetrieveApiTestTemplate(RestDescriptor getDescriptor, RestDescriptor deleteDescriptor, RestDescriptor createDescriptor) {
+        super(getDescriptor);
+        this.createDescriptor = createDescriptor;
+        this.deleteDescriptor = deleteDescriptor;
+    }
+
+    protected RestDescriptor createDescriptor;
+    protected RestDescriptor deleteDescriptor;
+    private String id = "retrievetest" + System.currentTimeMillis();
+
+    @Override
+    protected String getId() {
+        return id;
+    }
+
+    @Override
+    protected void deleteResource() throws Exception {
+        deleteDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected void deleteResourcewitharg(String ext) throws Exception {
+        deleteDescriptor.run(ext, testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected void createResource() throws Exception {
+        createDescriptor.run(getId(), testUtils.getOpsAccessToken());
+    }
+    @Override
+    protected void createResourcewitharg(String ext) throws Exception {
+        createDescriptor.run(ext, testUtils.getOpsAccessToken());
+    }
+
+    @Override
+    protected int expectedOkResponseCode() {
+        return 200;
+    }
+
+
+    @Test
+    public void should_return404_when_accessingDataThatDoesntExist() throws Exception {
+        deleteResource();
+        ClientResponse response = descriptor.run(getId(), testUtils.getOpsAccessToken());
+        assertEquals(error(response.getEntity(String.class)), 404, response.getStatus());
+    }
+
+    @Test
+    public void should_beAbleToRunApiInParallel() throws Exception {
+        createResource();
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        List<Callable<ClientResponse>> tasks = new ArrayList<>();
+
+        for (int i = 0; i < 10; i++) {
+            Callable<ClientResponse> task = () -> {
+                try {
+                    return descriptor.run(getId(), testUtils.getOpsAccessToken());
+                } catch (Exception ex) {
+                    return null;
+                }
+            };
+            tasks.add(task);
+        }
+
+        List<Future<ClientResponse>> responses = executor.invokeAll(tasks);
+        executor.shutdown();
+        executor.awaitTermination(10, TimeUnit.SECONDS);
+
+        deleteResource();
+        int sucessResponseCount = 0;
+        int errorResponseCount = 0;
+        for (Future<ClientResponse> future : responses) {
+            if (future.get().getStatus() == expectedOkResponseCode())
+                sucessResponseCount++;
+            else
+                errorResponseCount++;
+        }
+
+        assertEquals(error("Expected all successful responses. Actual " + sucessResponseCount), 10, sucessResponseCount);
+        assertEquals(error("Unexpected error response returned"), 0, errorResponseCount);
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestBase.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac8baf276eca113dcf204db3b8c649cfae99c072
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestBase.java
@@ -0,0 +1,10 @@
+package org.opengroup.osdu.register.util;
+
+public abstract class TestBase {
+
+    protected TestUtils testUtils = null;
+
+    public abstract void setup() throws Exception;
+
+    public abstract void tearDown() throws Exception;
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestHttpClient.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestHttpClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1ed4c02bad752469a5ba4b2356f51a334f6a41e
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestHttpClient.java
@@ -0,0 +1,75 @@
+/*
+  Copyright 2002-2022 Google LLC
+  Copyright 2002-2022 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.register.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+@Slf4j
+public class TestHttpClient extends TestUtils {
+
+  public static final String OPS_TOKEN = "OPS_TOKEN";
+  public static final String PRIVILEGED_USER_TOKEN  = "PRIVILEGED_USER_TOKEN";
+  public static final String EDITOR_TOKEN = "EDITOR_TOKEN";
+  public static final String NO_ACCESS_USER_TOKEN = "NO_ACCESS_USER_TOKEN";
+
+  private OpenIDTokenProvider tokenProvider = null;
+
+  public TestHttpClient() {
+    opsToken = System.getProperty(OPS_TOKEN, System.getenv(OPS_TOKEN));
+    admToken = System.getProperty(PRIVILEGED_USER_TOKEN , System.getenv(PRIVILEGED_USER_TOKEN ));
+    editorToken = System.getProperty(EDITOR_TOKEN, System.getenv(EDITOR_TOKEN));
+    noAccessToken = System.getProperty(NO_ACCESS_USER_TOKEN, System.getenv(NO_ACCESS_USER_TOKEN));
+
+    if (StringUtils.isAnyEmpty(opsToken, admToken, noAccessToken, editorToken)) {
+      tokenProvider = new OpenIDTokenProvider();
+    }
+  }
+
+  @Override
+  public String getOpsAccessToken() {
+    if (StringUtils.isEmpty(opsToken)) {
+        opsToken = tokenProvider.getOpsAccessToken();
+    }
+    return "Bearer " + opsToken;
+  }
+
+  @Override
+  public String getAdmAccessToken() {
+    if (StringUtils.isEmpty(admToken)) {
+        admToken = tokenProvider.getAdminAccessToken();
+    }
+    return "Bearer " + admToken;
+  }
+
+  @Override
+  public String getEditorAccessToken() {
+    if (StringUtils.isEmpty(editorToken)) {
+      editorToken = tokenProvider.getEditorAccessToken();
+    }
+    return "Bearer " + editorToken;
+  }
+
+  @Override
+  public String getNoDataAccessToken() {
+    if (StringUtils.isEmpty(noAccessToken)) {
+        noAccessToken = tokenProvider.getNoAccessToken();
+    }
+    return "Bearer " + noAccessToken;
+  }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestPayloadReader.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestPayloadReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..ceaa5efe8b1f871130edb9bc121d7f5897e49e1d
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestPayloadReader.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.net.URL;
+
+@Slf4j
+public class TestPayloadReader {
+
+    public String getCreateRequestPayload(String path, String ddmsId, String tenantId) {
+        String reqBody = this.getTestPayload(path);
+        return reqBody.replace("{DDMS-ID}", ddmsId).replace("{TENANT-ID}", tenantId);
+    }
+
+    public String getTestPayload(String path) {
+        try {
+            URL url = Resources.getResource(path);
+            return Resources.toString(url, Charsets.UTF_8);
+        } catch (IOException e) {
+            log.error("Unable to read " + path+" error: ", e);
+            return "";
+        }
+    }
+}
diff --git a/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestUtils.java b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..30d62c106d26be9b3eb1ba4457f0e5af23273f38
--- /dev/null
+++ b/register-acceptance-test/src/test/java/org/opengroup/osdu/register/util/TestUtils.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2017-2020, 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.register.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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 lombok.extern.slf4j.Slf4j;
+
+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 javax.ws.rs.core.Response;
+import java.net.URL;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+
+@Slf4j
+public abstract class TestUtils {
+
+    protected static String opsToken = null;
+    protected static String admToken = null;
+    protected static String editorToken = null;
+    protected static String noAccessToken = null;
+
+    public static String getApiPath(String api) throws Exception {
+        String baseUrl = Config.Instance().HostUrl;
+        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 getOpsAccessToken() throws Exception;
+
+    public abstract String getAdmAccessToken() throws Exception;
+
+    public abstract String getEditorAccessToken() throws Exception;
+
+    public abstract String getNoDataAccessToken() throws Exception;
+
+    public static ClientResponse send(String path, String httpMethod, String token, String requestBody, String query)
+            throws Exception {
+
+        Map<String, String> headers = getOsduTenantHeaders();
+
+        return send(path, httpMethod, token, requestBody, query, headers);
+    }
+
+    public static ClientResponse sendHttp(String path, String httpMethod, String token, String requestBody, String query)
+            throws Exception {
+
+        Map<String, String> headers = getOsduTenantHeaders();
+
+        return send(path, httpMethod, token, requestBody, query, headers, true);
+    }
+
+    public static Map<String, String> getOsduTenantHeaders() {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("data-partition-id", getOsduTenant());
+        headers.put("correlation-id", UUID.randomUUID().toString());
+        return headers;
+    }
+
+    public static Map<String, String> getCustomerTenantHeaders() {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("data-partition-id", getCustomerTenant());
+        headers.put("correlation-id", UUID.randomUUID().toString());
+        return headers;
+    }
+
+    public static ClientResponse send(String path, String httpMethod, String token, String requestBody, String query,
+                                      Map<String, String> headers)
+            throws Exception {
+        return send(path, httpMethod, token, requestBody, query, headers, false);
+    }
+
+    public static ClientResponse send(String path, String httpMethod, String token, String requestBody, String query,
+                                      Map<String, String> headers, boolean isHttp)
+            throws Exception {
+
+        ClientResponse response = null;
+        Client client = getClient();
+        client.setConnectTimeout(300000);
+        client.setReadTimeout(300000);
+        client.setFollowRedirects(false);
+        String url = getApiPath(path + query);
+        WebResource webResource = client.resource(isHttp ? url.replaceFirst("https", "http") : url);
+        int count = 1;
+        int MaxRetry = 3;
+        while (count < MaxRetry) {
+            try {
+                headers.put("correlation-id", headers.getOrDefault("correlation-id", UUID.randomUUID().toString()));
+                WebResource.Builder builder = webResource.type(MediaType.APPLICATION_JSON)
+                        .header("Authorization", token);
+                headers.forEach((k, v) -> builder.header(k, v));
+                //removing Auth header before logging
+                headers.remove("Authorization");
+                ObjectMapper objectMapper = new ObjectMapper();;
+                objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+                JsonNode rootNode = null;
+                if (requestBody != null) {
+                    rootNode = objectMapper.readTree(requestBody);
+                    if (rootNode!= null && rootNode.has("secret")) {
+                        ((ObjectNode) rootNode).remove("secret");
+                    }
+                }
+                log.info(String.format("\nRequest URL: %s %s\nRequest Headers: %s\nRequest Body: %s", httpMethod, url, headers, objectMapper.writeValueAsString(rootNode)));
+                log.info(String.format("Attempt: #%s/%s, CorrelationId: %s", count, MaxRetry, headers.get("correlation-id")));
+                response = builder.method(httpMethod, ClientResponse.class, requestBody);
+                if (response.getStatusInfo().getFamily().equals(Response.Status.Family.valueOf("SERVER_ERROR"))) {
+                    count++;
+                    Thread.sleep(5000);
+                    continue;
+                } else {
+                    break;
+                }
+            } catch (Exception ex) {
+                log.error("Exception While Making Request: ", ex);
+                count++;
+                if (count == MaxRetry) {
+                    throw new AssertionError("Error: Send request error", ex);
+                }
+            } finally {
+                //log response body
+                if (response != null) {
+                    log.info(String.format("\nThis is the response received : \n%s\nResponse Headers: %s\nResponse Status code: %s", response, response.getHeaders(), response.getStatus()));
+                }
+            }
+        }
+        return response;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
+        String json = response.getEntity(String.class);
+        log.info(json);
+
+        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();
+    }
+}
diff --git a/register-acceptance-test/src/test/resources/actionApi/invalidFilterEntityTypeTestAction.json b/register-acceptance-test/src/test/resources/actionApi/invalidFilterEntityTypeTestAction.json
new file mode 100644
index 0000000000000000000000000000000000000000..98075de47a5c5fb082ed9f223236e8b3f98323cf
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/actionApi/invalidFilterEntityTypeTestAction.json
@@ -0,0 +1,19 @@
+{
+  "action": {
+    "id": "petrel-launch-project",
+    "name": "Petrel Project",
+    "url": "https://myapp.osdu.opengroup.org/action/{data.uri:^(?:[^\\/]*(?:\\/(?:\\/[^\\/]*\\/?)?)?([^?]+)(?:\\??.+)?)$}",
+    "filter": {
+      "entityType": [""],
+      "source": ["petrel"],
+      "version": ["*"]
+    }
+  },
+  "testPayload": {
+    "id": "common:regularheightfield:123456",
+    "kind": "common:petrel:regularheightfield:1.0.0",
+    "data": {
+      "uri": "https://myproj.com/abc123"
+    }
+  }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/actionApi/invalidNameTestAction.json b/register-acceptance-test/src/test/resources/actionApi/invalidNameTestAction.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb6b58ec23edef203567b61daf4e568581fe3587
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/actionApi/invalidNameTestAction.json
@@ -0,0 +1,21 @@
+{
+  "action": {
+    "id": "petrel-launch-project",
+    "name": "",
+    "description": "This action launches the Petrel projects landing page that holds the selected data.",
+    "url": "https://myapp.osdu.opengroup.org/action/{data.uri:^(?:[^\\/]*(?:\\/(?:\\/[^\\/]*\\/?)?)?([^?]+)(?:\\??.+)?)$}",
+    "img": "https://mycdn.com/img.png",
+    "filter": {
+      "entityType": ["regularheightfield", "project"],
+      "source": ["petrel"],
+      "version": ["*"]
+    }
+  },
+  "testPayload": {
+    "id": "common:regularheightfield:123456",
+    "kind": "common:petrel:regularheightfield:1.0.0",
+    "data": {
+      "uri": "https://myproj.com/abc123"
+    }
+  }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/actionApi/invalidUrlTestActionPayload.json b/register-acceptance-test/src/test/resources/actionApi/invalidUrlTestActionPayload.json
new file mode 100644
index 0000000000000000000000000000000000000000..4c7d5383283590253ec5bd74d9f11d3a054a3e43
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/actionApi/invalidUrlTestActionPayload.json
@@ -0,0 +1,14 @@
+{
+  "action": {
+    "id": "petrel-launch-project",
+    "name": "Petrel Project",
+    "description": "This action launches the Petrel projects landing page that holds the selected data.",
+    "url": "htt://myapp.osdu.opengroup.org/action /{data.missing:(?:[^\\/]*(?:\\/(?:\\/[^\\/]*\\/?)?)?([^?]+)(?:\\??.+)?)$}",
+    "img": "https://mycdn.com/img.png",
+    "filter": {
+      "entityType": ["regularheightfield", "project"],
+      "source": ["petrel"],
+      "version": ["*"]
+    }
+  }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/actionApi/nonHttpsTestAction.json b/register-acceptance-test/src/test/resources/actionApi/nonHttpsTestAction.json
new file mode 100644
index 0000000000000000000000000000000000000000..2ddb110d642953ab5e263c239a66415c30a7e48d
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/actionApi/nonHttpsTestAction.json
@@ -0,0 +1,21 @@
+{
+  "action": {
+    "id": "petrel-launch-project",
+    "name": "Petrel Project",
+    "description": "This action launches the Petrel projects landing page that holds the selected data.",
+    "url": "http://myapp.osdu.opengroup.org/action/{data.uri:^(?:[^\\/]*(?:\\/(?:\\/[^\\/]*\\/?)?)?([^?]+)(?:\\??.+)?)$}",
+    "img": "https://mycdn.com/img.png",
+    "filter": {
+      "entityType": ["regularheightfield", "project"],
+      "source": ["petrel"],
+      "version": ["*"]
+    }
+  },
+  "testPayload": {
+    "id": "common:regularheightfield:123456",
+    "kind": "common:petrel:regularheightfield:1.0.0",
+    "data": {
+      "uri": "https://myproj.com/abc123"
+    }
+  }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/actionApi/validTestAction.json b/register-acceptance-test/src/test/resources/actionApi/validTestAction.json
new file mode 100644
index 0000000000000000000000000000000000000000..3988400614c74abea2494574e46f113b7ba2ee94
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/actionApi/validTestAction.json
@@ -0,0 +1,21 @@
+{
+  "action": {
+    "id": "petrel-launch-project",
+    "name": "Petrel Project",
+    "description": "This action launches the Petrel projects landing page that holds the selected data.",
+    "url": "https://myapp.osdu.opengroup.org/action/{data.uri:^(?:[^\\/]*(?:\\/(?:\\/[^\\/]*\\/?)?)?([^?]+)(?:\\??.+)?)$}",
+    "img": "https://mycdn.com/img.png",
+    "filter": {
+      "entityType": ["regularheightfield", "project"],
+      "source": ["petrel"],
+      "version": ["*"]
+    }
+  },
+  "testPayload": {
+    "id": "common:regularheightfield:123456",
+    "kind": "common:petrel:regularheightfield:1.0.0",
+    "data": {
+      "uri": "https://myproj.com/abc123"
+    }
+  }
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/createDdmsApi/invalidCreateDdmsRequestBody.json b/register-acceptance-test/src/test/resources/createDdmsApi/invalidCreateDdmsRequestBody.json
new file mode 100644
index 0000000000000000000000000000000000000000..18997c3dcb72803000538c0add48ef3d00dc9338
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/createDdmsApi/invalidCreateDdmsRequestBody.json
@@ -0,0 +1,86 @@
+{
+  "id": "{DDMS-ID}",
+  "name": "logDDMS",
+  "interfaces": [
+    {
+      "entityType": "",
+      "schema": {
+        "openapi": "3.0.0",
+        "info": {
+          "description": "This is a sample Wellbore domain DM service.",
+          "version": "1.0.0",
+          "title": "DELFI Data Ecosystem Wellbore Domain DM Service",
+          "contact": {
+            "email": "osdu-sre@opengroup.org"
+          }
+        },
+        "servers": [
+          {
+            "url": "https://subsurface.data.osdu.opengroup.org/v1"
+          }
+        ],
+        "tags": [
+          {
+            "name": "wellbore",
+            "description": "Wellbore data type services"
+          }
+        ],
+        "paths": {
+          "/wellbore/{wellboreId}": {
+            "delete": {
+              "tags": [
+                "wellbore"
+              ],
+              "summary": "Find wellbore by ID",
+              "description": "Returns a single wellbore",
+              "operationId": "getWellboreById",
+              "x-ddms-retrieve-entity": true,
+              "parameters": [
+                {
+                  "name": "wellboreId",
+                  "in": "path",
+                  "description": "ID of wellbore to return",
+                  "required": true,
+                  "schema": {
+                    "type": "string"
+                  }
+                }
+              ],
+              "responses": {
+                "200": {
+                  "description": "successful operation",
+                  "content": {
+                    "application/json": {
+                      "schema": {
+                        "$ref": "#/components/schemas/wellbore"
+                      }
+                    }
+                  }
+                },
+                "400": {
+                  "description": "Invalid ID supplied"
+                },
+                "401": {
+                  "description": "Not authorized"
+                },
+                "404": {
+                  "description": "Wellbore not found"
+                },
+                "405": {
+                  "description": "Validation exception"
+                }
+              }
+            }
+          }
+        },
+        "components": {
+          "schemas": {
+            "wellbore": {
+              "title": "Wellbore",
+              "type": "object"
+            }
+          }
+        }
+      }
+    }]
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/createDdmsApi/validCreateDdmsRequestBody.json b/register-acceptance-test/src/test/resources/createDdmsApi/validCreateDdmsRequestBody.json
new file mode 100644
index 0000000000000000000000000000000000000000..7d1fb8b03bdc9d505377a7a3933cb2646d61f479
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/createDdmsApi/validCreateDdmsRequestBody.json
@@ -0,0 +1,97 @@
+{
+  "id": "{DDMS-ID}",
+  "name": "logDDMS",
+  "description": "My test ddms.",
+  "contactEmail": "test@test.com",
+  "interfaces": [
+    {
+      "entityType": "wellbore",
+      "schema": {
+        "openapi": "3.0.0",
+        "info": {
+          "description": "This is a sample Wellbore domain DM service.",
+          "version": "1.0.0",
+          "title": "DELFI Data Ecosystem Wellbore Domain DM Service",
+          "contact": {
+            "email": "osdu-sre@opengroup.org"
+          }
+        },
+        "servers": [
+          {
+            "url": "https://subsurface.data.osdu.opengroup.org/v1"
+          }
+        ],
+        "tags": [
+          {
+            "name": "wellbore",
+            "description": "Wellbore data type services"
+          }
+        ],
+        "paths": {
+          "/wellbore/{wellboreId}": {
+            "get": {
+              "tags": [
+                "wellbore"
+              ],
+              "summary": "Find wellbore by ID",
+              "description": "Returns a single wellbore",
+              "operationId": "getWellboreById",
+              "x-ddms-retrieve-entity": true,
+              "parameters": [
+                {
+                  "name": "wellboreId",
+                  "in": "path",
+                  "description": "ID of wellbore to return",
+                  "required": true,
+                  "schema": {
+                    "type": "string"
+                  }
+                }
+              ],
+              "responses": {
+                "200": {
+                  "description": "successful operation",
+                  "content": {
+                    "application/json": {
+                      "schema": {
+                        "$ref": "#/components/schemas/wellbore"
+                      }
+                    }
+                  }
+                },
+                "400": {
+                  "description": "Invalid ID supplied"
+                },
+                "401": {
+                  "description": "Not authorized"
+                },
+                "404": {
+                  "description": "Wellbore not found"
+                },
+                "405": {
+                  "description": "Validation exception"
+                }
+              }
+            }
+          }
+        },
+        "components": {
+          "schemas": {
+            "wellbore": {
+              "title": "Wellbore",
+              "type": "object",
+              "properties": {
+                "country": {
+                  "example": [
+                    "United States of America",
+                    "Bolivia (Plurinational State of)"
+                  ],
+                  "title": "Country"
+                }
+              }
+            }
+          }
+        }
+      }
+    }]
+}
\ No newline at end of file
diff --git a/register-acceptance-test/src/test/resources/workflow/registerDiscoverConsumeWorkflowRequestBody.json b/register-acceptance-test/src/test/resources/workflow/registerDiscoverConsumeWorkflowRequestBody.json
new file mode 100644
index 0000000000000000000000000000000000000000..ffceaee522d280f5ac0d4916afe4176427f5027b
--- /dev/null
+++ b/register-acceptance-test/src/test/resources/workflow/registerDiscoverConsumeWorkflowRequestBody.json
@@ -0,0 +1,97 @@
+{
+  "id": "{DDMS-ID}",
+  "name": "ddms-workflow",
+  "description": "My test ddms.",
+  "contactEmail": "osdu-sre@opengroup.org",
+  "interfaces": [
+    {
+      "entityType": "registerDiscoverConsume",
+      "schema": {
+        "openapi": "3.0.0",
+        "info": {
+          "description": "This is a sample Wellbore domain DM service.",
+          "version": "1.0.0",
+          "title": "DELFI Data Ecosystem Wellbore Domain DM Service",
+          "contact": {
+            "email": "osdu-sre@opengroup.org"
+          }
+        },
+        "servers": [
+          {
+            "url": "https://subsurface.data.osdu.opengroup.org/v1"
+          }
+        ],
+        "tags": [
+          {
+            "name": "wellbore",
+            "description": "Wellbore data type services"
+          }
+        ],
+        "paths": {
+          "/wellbore/{wellboreId}": {
+            "get": {
+              "tags": [
+                "wellbore"
+              ],
+              "summary": "Find wellbore by ID",
+              "description": "Returns a single wellbore",
+              "operationId": "getWellboreById",
+              "x-ddms-retrieve-entity": true,
+              "parameters": [
+                {
+                  "name": "wellboreId",
+                  "in": "path",
+                  "description": "ID of wellbore to return",
+                  "required": true,
+                  "schema": {
+                    "type": "string"
+                  }
+                }
+              ],
+              "responses": {
+                "200": {
+                  "description": "successful operation",
+                  "content": {
+                    "application/json": {
+                      "schema": {
+                        "$ref": "#/components/schemas/wellbore"
+                      }
+                    }
+                  }
+                },
+                "400": {
+                  "description": "Invalid ID supplied"
+                },
+                "401": {
+                  "description": "Not authorized"
+                },
+                "404": {
+                  "description": "Wellbore not found"
+                },
+                "405": {
+                  "description": "Validation exception"
+                }
+              }
+            }
+          }
+        },
+        "components": {
+          "schemas": {
+            "wellbore": {
+              "title": "Wellbore",
+              "type": "object",
+              "properties": {
+                "country": {
+                  "example": [
+                    "United States of America",
+                    "Bolivia (Plurinational State of)"
+                  ],
+                  "title": "Country"
+                }
+              }
+            }
+          }
+        }
+      }
+    }]
+}
\ No newline at end of file