diff --git a/provider/indexer-gcp/pom.xml b/provider/indexer-gcp/pom.xml
index 7b936e801ba92f6025822260dd7a1a390af76865..09cc7e5240b1cfef8ffab0eb432888c8c8d9e640 100644
--- a/provider/indexer-gcp/pom.xml
+++ b/provider/indexer-gcp/pom.xml
@@ -43,7 +43,7 @@
         <dependency>
             <groupId>org.opengroup.osdu</groupId>
             <artifactId>core-lib-gcp</artifactId>
-            <version>0.1.17</version>
+            <version>0.3.21</version>
         </dependency>
 
         <dependency>
diff --git a/provider/indexer-gcp/src/main/appengine/app.yaml b/provider/indexer-gcp/src/main/appengine/app.yaml
index dee4515740c38e195f4afeada8a4b66471a32833..16d9a8ac495f04fa88c5ec438902c621dc08bf96 100644
--- a/provider/indexer-gcp/src/main/appengine/app.yaml
+++ b/provider/indexer-gcp/src/main/appengine/app.yaml
@@ -39,3 +39,4 @@ env_variables:
   LEGAL_HOSTNAME: "LEGAL_HOSTNAME_VAR"
   REGION: "REGION_VAR"
   SPRING_PROFILES_ACTIVE: 'ENVIRONMENT'
+
diff --git a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/di/AppengineLogFactory.java b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/di/AppengineLogFactory.java
deleted file mode 100644
index 66ae62f7a67f9c39327d897e945ef81d4e39e192..0000000000000000000000000000000000000000
--- a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/di/AppengineLogFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.opengroup.osdu.indexer.di;
-
-import org.opengroup.osdu.core.common.logging.ILogger;
-import org.opengroup.osdu.core.gcp.logging.logger.AppEngineLoggingProvider;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
-
-@ConditionalOnProperty(name="disable.appengine.log.factory", havingValue = "false", matchIfMissing = true )
-@Component
-@Primary
-@Lazy
-public class AppengineLogFactory implements FactoryBean<ILogger> {
-
-    private AppEngineLoggingProvider appEngineLoggingProvider = new AppEngineLoggingProvider();
-
-    @Override
-    public ILogger getObject() throws Exception {
-        return appEngineLoggingProvider.getLogger();
-    }
-
-    @Override
-    public Class<?> getObjectType() {
-        return ILogger.class;
-    }
-}
\ No newline at end of file
diff --git a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/di/DatastoreCredentialsCacheFactory.java b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/di/DatastoreCredentialsCacheFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..94e9d343b980c905ff0b72941e5232e40ff42e8d
--- /dev/null
+++ b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/di/DatastoreCredentialsCacheFactory.java
@@ -0,0 +1,22 @@
+package org.opengroup.osdu.indexer.di;
+
+import org.opengroup.osdu.core.common.cache.ICache;
+import org.opengroup.osdu.core.common.cache.VmCache;
+import org.opengroup.osdu.core.gcp.multitenancy.credentials.DatastoreCredential;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DatastoreCredentialsCacheFactory extends
+    AbstractFactoryBean<ICache<String, DatastoreCredential>> {
+
+  @Override
+  public Class<?> getObjectType() {
+    return ICache.class;
+  }
+
+  @Override
+  protected ICache<String, DatastoreCredential> createInstance() throws Exception {
+    return new VmCache<>(5 * 60, 20);
+  }
+}
diff --git a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/kms/KmsClient.java b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/kms/KmsClient.java
deleted file mode 100644
index 020efb85eede96cb8eebd1beec4b23ce2fa42b83..0000000000000000000000000000000000000000
--- a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/kms/KmsClient.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017-2019, Schlumberger
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.opengroup.osdu.indexer.kms;
-
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
-import com.google.api.client.http.HttpTransport;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.jackson2.JacksonFactory;
-import com.google.api.services.cloudkms.v1.CloudKMS;
-import com.google.api.services.cloudkms.v1.CloudKMSScopes;
-import com.google.api.services.cloudkms.v1.model.DecryptRequest;
-import com.google.api.services.cloudkms.v1.model.DecryptResponse;
-import com.google.api.services.cloudkms.v1.model.EncryptRequest;
-import com.google.api.services.cloudkms.v1.model.EncryptResponse;
-import org.opengroup.osdu.core.common.provider.interfaces.IKmsClient;
-import org.opengroup.osdu.core.common.search.Preconditions;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.annotation.RequestScope;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-@Component
-@RequestScope
-public class KmsClient implements IKmsClient {
-
-    @Value("${GOOGLE_CLOUD_PROJECT}")
-    private String GOOGLE_CLOUD_PROJECT;
-
-    @Value("${KMS_KEY}")
-    private String KMS_KEY;
-
-    @Value("${KEY_RING}")
-    private String KEY_RING;
-
-    private static final String KEY_NAME = "projects/%s/locations/global/keyRings/%s/cryptoKeys/%s";
-
-    /**
-     * Encrypts the given plaintext using the specified crypto key.
-     * Google KMS automatically uses the new primary key version to encrypt data, so this could be directly used for key rotation
-     */
-    public String encryptString(String textToBeEncrypted) throws IOException {
-        Preconditions.checkNotNullOrEmpty(textToBeEncrypted, "textToBeEncrypted cannot be null");
-
-        byte[] plaintext = textToBeEncrypted.getBytes(StandardCharsets.UTF_8);
-        String resourceName = String.format(KEY_NAME, GOOGLE_CLOUD_PROJECT, KEY_RING, KMS_KEY);
-        CloudKMS kms = createAuthorizedClient();
-        EncryptRequest request = new EncryptRequest().encodePlaintext(plaintext);
-        EncryptResponse response = kms.projects().locations().keyRings().cryptoKeys()
-                .encrypt(resourceName, request)
-                .execute();
-        return response.getCiphertext();
-    }
-
-    /**
-     * Decrypts the provided ciphertext with the specified crypto key.
-     * Google KMS automatically uses the correct key version to decrypt data, as long as the key version is not disabled
-     */
-    public String decryptString(String textToBeDecrypted) throws IOException {
-        Preconditions.checkNotNullOrEmpty(textToBeDecrypted, "textToBeDecrypted cannot be null");
-
-        CloudKMS kms = createAuthorizedClient();
-        String cryptoKeyName = String.format(KEY_NAME, GOOGLE_CLOUD_PROJECT, KEY_RING, KMS_KEY);
-        DecryptRequest request = new DecryptRequest().setCiphertext(textToBeDecrypted);
-        DecryptResponse response = kms.projects().locations().keyRings().cryptoKeys()
-                .decrypt(cryptoKeyName, request)
-                .execute();
-        return new String(response.decodePlaintext(), StandardCharsets.UTF_8).trim();
-    }
-
-    /**
-     * Creates an authorized CloudKMS client service using Application Default Credentials.
-     *
-     * @return an authorized CloudKMS client
-     * @throws IOException if there's an error getting the default credentials.
-     */
-    private CloudKMS createAuthorizedClient() throws IOException {
-        HttpTransport transport = new NetHttpTransport();
-        JsonFactory jsonFactory = new JacksonFactory();
-        GoogleCredential credential = GoogleCredential.getApplicationDefault();
-        if (credential.createScopedRequired()) {
-            credential = credential.createScoped(CloudKMSScopes.all());
-        }
-        return new CloudKMS.Builder(transport, jsonFactory, credential)
-                .setApplicationName("CloudKMS snippets")
-                .build();
-    }
-}
\ No newline at end of file
diff --git a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/DatastoreCredential.java b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/DatastoreCredential.java
deleted file mode 100644
index 5bde4448cfd77348818e0d04b312a1ca432f8dde..0000000000000000000000000000000000000000
--- a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/DatastoreCredential.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2017-2019, Schlumberger
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.opengroup.osdu.indexer.persistence;
-
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
-import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.jackson2.JacksonFactory;
-import com.google.api.services.iam.v1.Iam;
-import com.google.api.services.iam.v1.Iam.Projects.ServiceAccounts.SignJwt;
-import com.google.api.services.iam.v1.model.SignJwtRequest;
-import com.google.api.services.iam.v1.model.SignJwtResponse;
-import com.google.auth.oauth2.AccessToken;
-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.gson.JsonObject;
-import org.apache.commons.lang3.time.DateUtils;
-import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
-import org.opengroup.osdu.core.common.util.Crc32c;
-import org.opengroup.osdu.indexer.cache.DatastoreCredentialCache;
-
-import java.util.Date;
-
-public class DatastoreCredential extends GoogleCredentials {
-
-	private static final long serialVersionUID = 8344377091688956815L;
-	private static final JsonFactory JSON_FACTORY = new JacksonFactory();
-	private Iam iam;
-
-	private final TenantInfo tenant;
-	private final DatastoreCredentialCache cache;
-
-	protected DatastoreCredential(TenantInfo tenant, DatastoreCredentialCache cache) {
-		this.tenant = tenant;
-		this.cache = cache;
-	}
-
-	@Override
-	public AccessToken refreshAccessToken() {
-
-		String cacheKey = this.getCacheKey();
-
-		AccessToken accessToken = this.cache.get(cacheKey);
-
-		if (accessToken != null) {
-			return accessToken;
-		}
-
-		try {
-			SignJwtRequest signJwtRequest = new SignJwtRequest();
-			signJwtRequest.setPayload(this.getPayload());
-
-			String serviceAccountName = String.format("projects/-/serviceAccounts/%s", this.tenant.getServiceAccount());
-
-			SignJwt signJwt = this.getIam().projects().serviceAccounts().signJwt(serviceAccountName, signJwtRequest);
-
-			SignJwtResponse signJwtResponse = signJwt.execute();
-			String signedJwt = signJwtResponse.getSignedJwt();
-
-			accessToken = new AccessToken(signedJwt, DateUtils.addSeconds(new Date(), 3600));
-
-			this.cache.put(cacheKey, accessToken);
-
-			return accessToken;
-		} catch (Exception e) {
-			throw new RuntimeException("Error creating datastore credential", e);
-		}
-	}
-
-	private String getPayload() {
-		JsonObject payload = new JsonObject();
-		payload.addProperty("iss", this.tenant.getServiceAccount());
-		payload.addProperty("sub", this.tenant.getServiceAccount());
-		payload.addProperty("aud", "https://datastore.googleapis.com/google.datastore.v1.Datastore");
-		payload.addProperty("iat", System.currentTimeMillis() / 1000);
-
-		return payload.toString();
-	}
-
-	protected void setIam(Iam iam) {
-		this.iam = iam;
-	}
-
-	private Iam getIam() throws Exception {
-		if (this.iam == null) {
-
-			Iam.Builder builder = new Iam.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY,
-					GoogleCredential.getApplicationDefault()).setApplicationName("Search Service");
-
-			this.iam = builder.build();
-		}
-		return this.iam;
-	}
-
-	private String getCacheKey() {
-		return Crc32c.hashToBase64EncodedString(String.format("datastoreCredential:%s", this.tenant.getName()));
-	}
-}
\ No newline at end of file
diff --git a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/DatastoreFactory.java b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/DatastoreFactory.java
deleted file mode 100644
index 1a14870151f97f34e87e4967dd5e496cd3b24b3f..0000000000000000000000000000000000000000
--- a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/DatastoreFactory.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017-2019, Schlumberger
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.opengroup.osdu.indexer.persistence;
-
-import com.google.api.gax.retrying.RetrySettings;
-import com.google.cloud.TransportOptions;
-import com.google.cloud.datastore.Datastore;
-import com.google.cloud.datastore.DatastoreOptions;
-import com.google.cloud.http.HttpTransportOptions;
-import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
-import org.opengroup.osdu.indexer.cache.DatastoreCredentialCache;
-import org.springframework.stereotype.Component;
-import org.threeten.bp.Duration;
-
-import javax.inject.Inject;
-import java.util.HashMap;
-import java.util.Map;
-
-@Component
-public class DatastoreFactory {
-
-    @Inject
-    private DatastoreCredentialCache cache;
-
-    private static Map<String, Datastore> DATASTORE_CLIENTS = new HashMap<>();
-
-    private static final RetrySettings RETRY_SETTINGS = RetrySettings.newBuilder()
-            .setMaxAttempts(6)
-            .setInitialRetryDelay(Duration.ofSeconds(10))
-            .setMaxRetryDelay(Duration.ofSeconds(32))
-            .setRetryDelayMultiplier(2.0)
-            .setTotalTimeout(Duration.ofSeconds(50))
-            .setInitialRpcTimeout(Duration.ofSeconds(50))
-            .setRpcTimeoutMultiplier(1.0)
-            .setMaxRpcTimeout(Duration.ofSeconds(50))
-            .build();
-
-    private static final TransportOptions TRANSPORT_OPTIONS = HttpTransportOptions.newBuilder()
-            .setReadTimeout(30000)
-            .build();
-
-    public Datastore getDatastoreInstance(TenantInfo tenantInfo) {
-        if (DATASTORE_CLIENTS.get(tenantInfo.getName()) == null) {
-            Datastore googleDatastore = DatastoreOptions.newBuilder()
-                    .setCredentials(new DatastoreCredential(tenantInfo, this.cache))
-                    .setRetrySettings(RETRY_SETTINGS)
-                    .setTransportOptions(TRANSPORT_OPTIONS)
-                    .setNamespace(tenantInfo.getName())
-                    .setProjectId(tenantInfo.getProjectId())
-                    .build().getService();
-            DATASTORE_CLIENTS.put(tenantInfo.getName(), googleDatastore);
-        }
-        return DATASTORE_CLIENTS.get(tenantInfo.getName());
-    }
-}
diff --git a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/ElasticRepositoryDatastore.java b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/ElasticRepositoryDatastore.java
index 9c0b6b6eeb8f04001d16886385d6b244dc108fae..3562fff40e6499e282e758bfb976d1f0c424bc4b 100644
--- a/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/ElasticRepositoryDatastore.java
+++ b/provider/indexer-gcp/src/main/java/org/opengroup/osdu/indexer/persistence/ElasticRepositoryDatastore.java
@@ -26,6 +26,7 @@ import org.opengroup.osdu.core.common.model.http.AppException;
 import org.opengroup.osdu.core.common.provider.interfaces.IKmsClient;
 import org.opengroup.osdu.core.common.provider.interfaces.IElasticRepository;
 import org.opengroup.osdu.core.common.search.Preconditions;
+import org.opengroup.osdu.core.gcp.multitenancy.DatastoreFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import javax.inject.Inject;
@@ -52,7 +53,7 @@ public class ElasticRepositoryDatastore implements IElasticRepository {
     @Override
     public ClusterSettings getElasticClusterSettings(TenantInfo tenantInfo) {
 
-        Datastore googleDatastore = this.datastoreFactory.getDatastoreInstance(tenantInfo);
+        Datastore googleDatastore = this.datastoreFactory.getDatastore(tenantInfo);
         Key key = googleDatastore.newKeyFactory().setKind(ELASTIC_DATASTORE_KIND).newKey(ELASTIC_DATASTORE_ID);
         Entity datastoreEntity = googleDatastore.get(key);