diff --git a/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalExceptionMapper.java b/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalExceptionMapper.java
index eef26642158be23a7b095a98ce824ede5b3b8307..2730e644394f91d2bcb1557fb815d18596103fbf 100644
--- a/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalExceptionMapper.java
+++ b/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalExceptionMapper.java
@@ -14,20 +14,21 @@
 
 package org.opengroup.osdu.legal.middleware;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.gson.Gson;
 import java.util.ArrayList;
 import java.util.List;
-
+import javassist.NotFoundException;
+import javax.inject.Inject;
 import javax.validation.ConstraintViolation;
 import javax.validation.ConstraintViolationException;
 import javax.validation.ValidationException;
-import javax.inject.Inject;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
-
-import com.google.gson.Gson;
-import javassist.NotFoundException;
 import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.AppException;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.Order;
 import org.springframework.http.HttpHeaders;
@@ -36,21 +37,14 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.lang.NonNull;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.web.HttpRequestMethodNotSupportedException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.context.request.WebRequest;
 import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
 
-import org.opengroup.osdu.core.common.model.http.AppException;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-
 @Order(Ordered.HIGHEST_PRECEDENCE)
-@ControllerAdvice
-@RestController
+@RestControllerAdvice
 public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
 
 	private static final Gson gson = new Gson();
@@ -74,7 +68,7 @@ public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
 		return this.getErrorResponse(
 				new AppException(HttpStatus.BAD_REQUEST.value(), "Bad JSON format", e.getMessage()));
 	}
-	
+
 	@ExceptionHandler(UnrecognizedPropertyException.class)
 	protected ResponseEntity<Object> handleValidationException(UnrecognizedPropertyException e) {
 		return this.getErrorResponse(
@@ -124,13 +118,24 @@ public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
 	protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(@NonNull HttpRequestMethodNotSupportedException e,
 																		 @NonNull HttpHeaders headers,
 																		 @NonNull HttpStatus status,
-																		 @NonNull WebRequest request) {
-		return this.getErrorResponse(
+        															 @NonNull WebRequest request) {
+	  return this.getErrorResponse(
 				new AppException(HttpStatus.METHOD_NOT_ALLOWED.value(), "Method not found.",
 						"Method not found.", e));
 	}
 
-	private ResponseEntity<Object> getErrorResponse(AppException e) {
+  @Override
+  @NonNull
+  protected ResponseEntity<Object> handleMethodArgumentNotValid(@NonNull MethodArgumentNotValidException e,
+                                                                @NonNull HttpHeaders headers,
+                                                                @NonNull HttpStatus status,
+                                                                @NonNull WebRequest request) {
+    return this.getErrorResponse(
+        new AppException(HttpStatus.BAD_REQUEST.value(), "Validation failed.",
+            "Validation failed.", e));
+  }
+
+	public ResponseEntity<Object> getErrorResponse(AppException e) {
 
 		String exceptionMsg = e.getError().getMessage();
 
@@ -140,6 +145,6 @@ public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
 			this.logger.warning(exceptionMsg, e);
 		}
 
-		return new ResponseEntity<Object>(gson.toJson(exceptionMsg), HttpStatus.resolve(e.getError().getCode()));
+      return new ResponseEntity<Object>(gson.toJson(exceptionMsg),HttpStatus.resolve(e.getError().getCode()));
 	}
 }
\ No newline at end of file
diff --git a/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalOtherExceptionMapper.java b/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalOtherExceptionMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae763156fbbc750e7547daadecaf8fae7a45f5d9
--- /dev/null
+++ b/legal-core/src/main/java/org/opengroup/osdu/legal/middleware/GlobalOtherExceptionMapper.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.legal.middleware;
+
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class GlobalOtherExceptionMapper {
+
+  private GlobalExceptionMapper mapper;
+
+  public GlobalOtherExceptionMapper(GlobalExceptionMapper mapper) {
+    this.mapper = mapper;
+  }
+
+  @ExceptionHandler(Exception.class)
+  protected ResponseEntity<Object> handleGeneralException(Exception e) {
+    return mapper.getErrorResponse(
+        new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Server error.",
+            "An unknown error has occurred.", e));
+  }
+
+}
diff --git a/provider/legal-gcp/README.md b/provider/legal-gcp/README.md
index 5e62f6295d82b1fdabe4772e7e4308770162bead..7e9519743c3def3c63645539c6b7ed7001a7e3af 100644
--- a/provider/legal-gcp/README.md
+++ b/provider/legal-gcp/README.md
@@ -125,6 +125,7 @@ You will need to have the following environment variables defined.
 | `INTEGRATION_TESTER` | `********` | Service account for API calls. Note: this user must have entitlements configured already | yes | https://console.cloud.google.com/iam-admin/serviceaccounts |
 | `HOST_URL` | `http://localhsot:8080/api/legal/v1/` | - | yes | - |
 | `MY_TENANT` | `osdu` | OSDU tenant used for testing | yes | - |
+| `SKIP_HTTP_TESTS` | ex `true` | jetty server returns 403 when running locally when deployed jettyserver is not used and the app returns a 302 so just run against deployed version only when checking http -> https redirects. Use 'true' for Google Cloud Run | yes | - |
 
 **Entitlements configuration for integration accounts**
 
diff --git a/provider/legal-gcp/pom.xml b/provider/legal-gcp/pom.xml
index 05a0b9e363ec560eb442ff8d8813c2e280dec924..e48735275c9c5070c445889e0037a49bf205ed64 100644
--- a/provider/legal-gcp/pom.xml
+++ b/provider/legal-gcp/pom.xml
@@ -233,7 +233,26 @@
                 <configuration>
                   <version>1</version>
                 </configuration>
-              </plugin>
+            </plugin>
+            <plugin>
+				<groupId>org.jacoco</groupId>
+				<artifactId>jacoco-maven-plugin</artifactId>
+				<version>0.7.7.201606060606</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>prepare-agent</goal>
+						</goals>
+					</execution>
+					<execution>
+						<id>report</id>
+						<phase>prepare-package</phase>
+						<goals>
+							<goal>report</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
 		</plugins>
 	</build>
 </project>
diff --git a/testing/legal-test-core/pom.xml b/testing/legal-test-core/pom.xml
index d8608b4c6fed497d05f64b629bc977eeef5479ea..969651efa533300ddf0a0202579659675293be18 100644
--- a/testing/legal-test-core/pom.xml
+++ b/testing/legal-test-core/pom.xml
@@ -45,6 +45,12 @@
         <artifactId>pact-jvm-provider-junit_2.12</artifactId>
         <version>3.5.5</version>
     </dependency>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.18.2</version>
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
 
   <repositories>
diff --git a/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/AcceptanceBaseTest.java b/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/AcceptanceBaseTest.java
index 3266e212c49553c599d7086170d2c8b49a0ad252..12b72e4f4e89d81f6607971b12443a3eeecb4139 100644
--- a/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/AcceptanceBaseTest.java
+++ b/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/AcceptanceBaseTest.java
@@ -5,13 +5,14 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.opengroup.osdu.legal.util.Constants.DATA_PARTITION_ID;
 
+import com.sun.jersey.api.client.ClientResponse;
 import java.util.HashMap;
 import java.util.Map;
-
-import com.sun.jersey.api.client.ClientResponse;
-
+import java.util.Objects;
+import lombok.extern.java.Log;
 import org.junit.Test;
 
+@Log
 public abstract class AcceptanceBaseTest {
 
 	protected LegalTagUtils legalTagUtils;
@@ -84,17 +85,25 @@ public abstract class AcceptanceBaseTest {
 		return response;
 	}
 
-	protected ClientResponse validateAccess(int expectedResponse) throws Exception {
-		Map<String, String> headers = new HashMap<>();
-		headers.put(DATA_PARTITION_ID, LegalTagUtils.getMyDataPartition());
-
-		ClientResponse response = legalTagUtils.send(this.getApi(), this.getHttpMethod(), legalTagUtils.accessToken(), getBody(), getQuery(), headers);
-		assertEquals(expectedResponse, response.getStatus());
-		if(expectedResponse == 204)
-			assertNull(response.getType());
-		else if(response.getType() != null) {
-			assertTrue(response.getType().toString().toLowerCase().indexOf("application/json") >= 0);
-		}
-		return response;
-	}
+  protected ClientResponse validateAccess(int expectedResponse) throws Exception {
+    Map<String, String> headers = new HashMap<>();
+    headers.put(DATA_PARTITION_ID, LegalTagUtils.getMyDataPartition());
+
+    ClientResponse response = legalTagUtils
+        .send(this.getApi(), this.getHttpMethod(), legalTagUtils.accessToken(), getBody(),
+            getQuery(), headers);
+    log.info("Response status = " + response.getStatus());
+    assertEquals(expectedResponse, response.getStatus());
+    if (expectedResponse == 204) {
+      if (Objects.nonNull(response.getType())) {
+        log.info("Content-Type = " + response.getType().toString());
+        assertTrue(response.getType().toString().toLowerCase().indexOf("text/html") >= 0); //Google Cloud Run specific
+      } else {
+        assertNull(response.getType());
+      }
+    } else if (response.getType() != null) {
+      assertTrue(response.getType().toString().toLowerCase().indexOf("application/json") >= 0);
+    }
+    return response;
+  }
 }
\ No newline at end of file
diff --git a/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/TestUtils.java b/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/TestUtils.java
index 1f026e853325388feb0480b5e4622131c53f84f8..e61a6934736e6bdcd3e64eee597bcb97371b862b 100644
--- a/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/TestUtils.java
+++ b/testing/legal-test-core/src/main/java/org/opengroup/osdu/legal/util/TestUtils.java
@@ -18,6 +18,7 @@ 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 javax.ws.rs.core.MediaType;
 
 public class TestUtils {
 
@@ -77,19 +78,22 @@ public class TestUtils {
         return headers;
     }
 
-    public ClientResponse send(String path, String httpMethod, String token, String requestBody, String query, Map<String,String> headers) throws Exception {
+  public ClientResponse send(String path, String httpMethod, String token, String requestBody,
+      String query, Map<String, String> headers) throws Exception {
 
-        Client client = getClient();
-       // client.setConnectTimeout(5000);
-       // client.setReadTimeout(30000);
-        WebResource webResource = client.resource(getApiPath(path + query));
-        final WebResource.Builder builder = webResource.accept("application/json").type("application/json")
-                .header("Authorization", token);
-        headers.forEach((k, v) -> builder.header(k, v));
-        ClientResponse response = builder.method(httpMethod, ClientResponse.class, requestBody);
+    Client client = getClient();
+    WebResource webResource = client.resource(getApiPath(path + query));
 
-        return response;
-    }
+    final WebResource.Builder builder = webResource.getRequestBuilder();
+    builder.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).
+        header("Authorization", token);
+
+    headers.forEach(builder::header);
+
+    ClientResponse response = builder.method(httpMethod, ClientResponse.class, requestBody);
+
+    return response;
+  }
 
 	@SuppressWarnings("unchecked")
 	public <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
diff --git a/testing/legal-test-gcp/src/test/java/org/opengroup/osdu/legal/util/GCPLegalTagUtils.java b/testing/legal-test-gcp/src/test/java/org/opengroup/osdu/legal/util/GCPLegalTagUtils.java
index 0752f278cb6861e7cf2d6f4b7100f096a04f6fd1..af9a44b8410492abb8c814af80b631325050d91f 100644
--- a/testing/legal-test-gcp/src/test/java/org/opengroup/osdu/legal/util/GCPLegalTagUtils.java
+++ b/testing/legal-test-gcp/src/test/java/org/opengroup/osdu/legal/util/GCPLegalTagUtils.java
@@ -1,5 +1,10 @@
 package org.opengroup.osdu.legal.util;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Base64;
+
 import com.google.api.client.util.Strings;
 import com.google.auth.oauth2.GoogleCredentials;
 import com.google.cloud.storage.BlobId;
diff --git a/testing/pom.xml b/testing/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0299f5e71c65c621e972fcb0254b4609854a2353
--- /dev/null
+++ b/testing/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2017-2019, Schlumberger
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<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.legal</groupId>
+  <artifactId>os-legal-testing</artifactId>
+  <version>0.0.2-SNAPSHOT</version>
+	<description>Root Legal Service project</description>
+	<packaging>pom</packaging>
+
+	<licenses>
+		<license>
+			<name>Apache License, Version 2.0</name>
+			<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
+			<distribution>repo</distribution>
+		</license>
+	</licenses>
+	<modules>
+		<module>legal-test-core</module>
+		<module>legal-test-aws</module>
+		<module>legal-test-azure</module>
+		<module>legal-test-gcp</module>
+		<module>legal-test-ibm</module>
+	</modules>
+
+  <repositories>
+    <repository>
+      <id>${gitlab-server}</id>
+      <url>https://community.opengroup.org/api/v4/groups/17/-/packages/maven</url>
+    </repository>
+  </repositories>
+
+  <distributionManagement>
+    <repository>
+      <id>${gitlab-server}</id>
+      <url>https://community.opengroup.org/api/v4/projects/74/packages/maven</url>
+    </repository>
+    <snapshotRepository>
+      <id>${gitlab-server}</id>
+      <url>https://community.opengroup.org/api/v4/projects/74/packages/maven</url>
+    </snapshotRepository>
+  </distributionManagement>
+
+</project>