From 6bfba9814bc98b93e7c870b792381c0de6bb1de9 Mon Sep 17 00:00:00 2001
From: Krisztian Molnar <krisztian_molnar@epam.com>
Date: Mon, 27 Jun 2022 13:39:01 +0200
Subject: [PATCH] changed all java files to LF (approved by dev team)

---
 .gitattributes                                |    2 +-
 .../osdu/indexer/api/RecordIndexerApi.java    |  272 ++--
 .../osdu/indexer/api/ReindexApi.java          |  128 +-
 .../service/AttributeParsingServiceImpl.java  |  466 +++----
 .../indexer/service/IndexSchemaService.java   |   86 +-
 .../service/IndexerMappingServiceImpl.java    |  802 ++++++------
 .../indexer/service/IndexerServiceImpl.java   | 1156 ++++++++---------
 .../service/StorageIndexerPayloadMapper.java  |  378 +++---
 .../indexer/service/StorageServiceImpl.java   |  466 +++----
 .../indexer/util/IndexerQueueTaskBuilder.java |  170 +--
 .../indexer/util/parser/BooleanParser.java    |   30 +-
 .../osdu/indexer/api/ReindexApiTest.java      |  154 +--
 .../util/parser/BooleanParserTest.java        |   52 +-
 .../indexer/azure/service/RetryPolicy.java    |  228 ++--
 .../service/UrlFetchServiceAzureImpl.java     |  196 +--
 .../azure/service/RetryPolicyTest.java        |  326 ++---
 .../service/UrlFetchServiceAzureImplTest.java |  262 ++--
 .../indexer/middleware/IndexFilterTest.java   |  106 +-
 .../service/IndexerMappingServiceTest.java    |  606 ++++-----
 .../indexer/service/ReindexServiceTest.java   |  300 ++---
 .../indexer/service/StorageServiceTest.java   |  508 ++++----
 .../ibm/util/GlobalExceptionMapper.java       |  142 +-
 .../ibm/util/IndexerQueueTaskBuilderIbm.java  |  316 ++---
 .../ibm/service/ReindexServiceTest.java       |  288 ++--
 .../ibm/service/StorageServiceTest.java       |  438 +++----
 25 files changed, 3939 insertions(+), 3939 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index 8e66562ab..ce3bfb293 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,2 @@
 * text=auto eol=lf
-*.java binary
+*.sh eol=lf
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java
index 1f8df5cf5..4cb1ef238 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/RecordIndexerApi.java
@@ -1,136 +1,136 @@
-// 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.api;
-
-import com.google.common.reflect.TypeToken;
-import com.google.gson.Gson;
-
-import com.google.gson.JsonParseException;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.java.Log;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.indexer.JobStatus;
-import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.core.common.model.indexer.SchemaChangedMessages;
-import org.opengroup.osdu.core.common.model.indexer.SchemaInfo;
-import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
-import org.opengroup.osdu.indexer.SwaggerDoc;
-import org.opengroup.osdu.indexer.service.IndexerService;
-import org.opengroup.osdu.indexer.service.ReindexService;
-import org.opengroup.osdu.indexer.service.SchemaService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.context.annotation.RequestScope;
-
-import javax.inject.Inject;
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.List;
-
-@Log
-@RestController
-@RequestMapping("/_dps/task-handlers")
-@RequestScope
-public class RecordIndexerApi {
-
-    @Inject
-    private IndexerService indexerService;
-    @Inject
-    private ReindexService reIndexService;
-    @Inject
-    private SchemaService schemaService;
-
-    // THIS IS AN INTERNAL USE API ONLY
-    // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY
-    @PostMapping(path = "/index-worker", consumes = "application/json")
-    @ApiOperation(hidden = true, value = "", notes = "")
-    public ResponseEntity<JobStatus> indexWorker (
-             @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY)
-             @Valid @RequestBody RecordChangedMessages recordChangedMessages) throws Exception {
-
-        if (recordChangedMessages.missingAccountId()) {
-            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Invalid tenant",
-                        String.format("Required header: '%s' not found", DpsHeaders.DATA_PARTITION_ID));
-        }
-        try {
-            if (recordChangedMessages == null) {
-                log.info("record change messages is null");
-            }
-
-            Type listType = new TypeToken<List<RecordInfo>>() {
-            }.getType();
-            List<RecordInfo> recordInfos = new Gson().fromJson(recordChangedMessages.getData(), listType);
-
-            if (recordInfos.size() == 0) {
-                log.info("none of record-change message can be deserialized");
-                return new ResponseEntity(HttpStatus.OK);
-            }
-            this.indexerService.processRecordChangedMessages(recordChangedMessages, recordInfos);
-            return new ResponseEntity(HttpStatus.OK);
-        } catch (AppException e) {
-            throw e;
-        } catch (JsonParseException e) {
-            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Request payload parsing error", "Unable to parse request payload.", e);
-        } catch (Exception e) {
-            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Unknown error", "An unknown error has occurred.", e);
-        }
-    }
-
-    // THIS IS AN INTERNAL USE API ONLY
-    // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY
-    @PostMapping("/reindex-worker")
-    @ApiOperation(hidden = true, value = "", notes = "")
-    public ResponseEntity<?> reindex(
-            @RequestBody @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY)
-            @Valid RecordReindexRequest recordReindexRequest) {
-        return new ResponseEntity<>(reIndexService.reindexRecords(recordReindexRequest, false), HttpStatus.OK);
-    }
-
-    // THIS IS AN INTERNAL USE API ONLY
-    // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY
-    @PostMapping("/schema-worker")
-    @ApiOperation(hidden = true, value = "", notes = "")
-    public ResponseEntity<?> schemaWorker(
-            @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY)
-            @Valid @RequestBody SchemaChangedMessages schemaChangedMessage) throws IOException {
-        if (schemaChangedMessage == null) {
-            log.warning("schema change messages is null");
-        }
-
-        if (schemaChangedMessage.missingAccountId()) {
-            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Invalid tenant",
-                    String.format("Required header: '%s' not found", DpsHeaders.DATA_PARTITION_ID));
-        }
-
-        try {
-            Type listType = new TypeToken<List<SchemaInfo>>() {}.getType();
-            List<SchemaInfo> schemaInfos = new Gson().fromJson(schemaChangedMessage.getData(), listType);
-
-            if (schemaInfos.size() == 0) {
-                log.warning("none of schema-change message can be deserialized");
-                return new ResponseEntity(org.springframework.http.HttpStatus.OK);
-            }
-            this.schemaService.processSchemaMessages(schemaInfos);
-            return new ResponseEntity(HttpStatus.OK);
-        } catch (JsonParseException e) {
-            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Request payload parsing error", "Unable to parse request payload.", e);
-        }
-    }
-}
+// 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.api;
+
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
+
+import com.google.gson.JsonParseException;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.java.Log;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.indexer.JobStatus;
+import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.core.common.model.indexer.SchemaChangedMessages;
+import org.opengroup.osdu.core.common.model.indexer.SchemaInfo;
+import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
+import org.opengroup.osdu.indexer.SwaggerDoc;
+import org.opengroup.osdu.indexer.service.IndexerService;
+import org.opengroup.osdu.indexer.service.ReindexService;
+import org.opengroup.osdu.indexer.service.SchemaService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.annotation.RequestScope;
+
+import javax.inject.Inject;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.List;
+
+@Log
+@RestController
+@RequestMapping("/_dps/task-handlers")
+@RequestScope
+public class RecordIndexerApi {
+
+    @Inject
+    private IndexerService indexerService;
+    @Inject
+    private ReindexService reIndexService;
+    @Inject
+    private SchemaService schemaService;
+
+    // THIS IS AN INTERNAL USE API ONLY
+    // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY
+    @PostMapping(path = "/index-worker", consumes = "application/json")
+    @ApiOperation(hidden = true, value = "", notes = "")
+    public ResponseEntity<JobStatus> indexWorker (
+             @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY)
+             @Valid @RequestBody RecordChangedMessages recordChangedMessages) throws Exception {
+
+        if (recordChangedMessages.missingAccountId()) {
+            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Invalid tenant",
+                        String.format("Required header: '%s' not found", DpsHeaders.DATA_PARTITION_ID));
+        }
+        try {
+            if (recordChangedMessages == null) {
+                log.info("record change messages is null");
+            }
+
+            Type listType = new TypeToken<List<RecordInfo>>() {
+            }.getType();
+            List<RecordInfo> recordInfos = new Gson().fromJson(recordChangedMessages.getData(), listType);
+
+            if (recordInfos.size() == 0) {
+                log.info("none of record-change message can be deserialized");
+                return new ResponseEntity(HttpStatus.OK);
+            }
+            this.indexerService.processRecordChangedMessages(recordChangedMessages, recordInfos);
+            return new ResponseEntity(HttpStatus.OK);
+        } catch (AppException e) {
+            throw e;
+        } catch (JsonParseException e) {
+            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Request payload parsing error", "Unable to parse request payload.", e);
+        } catch (Exception e) {
+            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Unknown error", "An unknown error has occurred.", e);
+        }
+    }
+
+    // THIS IS AN INTERNAL USE API ONLY
+    // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY
+    @PostMapping("/reindex-worker")
+    @ApiOperation(hidden = true, value = "", notes = "")
+    public ResponseEntity<?> reindex(
+            @RequestBody @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY)
+            @Valid RecordReindexRequest recordReindexRequest) {
+        return new ResponseEntity<>(reIndexService.reindexRecords(recordReindexRequest, false), HttpStatus.OK);
+    }
+
+    // THIS IS AN INTERNAL USE API ONLY
+    // THAT MEANS WE DON'T DOCUMENT IT IN SWAGGER, ACCESS IS LIMITED TO CLOUD TASK QUEUE CALLS ONLY
+    @PostMapping("/schema-worker")
+    @ApiOperation(hidden = true, value = "", notes = "")
+    public ResponseEntity<?> schemaWorker(
+            @NotNull(message = SwaggerDoc.REQUEST_VALIDATION_NOT_NULL_BODY)
+            @Valid @RequestBody SchemaChangedMessages schemaChangedMessage) throws IOException {
+        if (schemaChangedMessage == null) {
+            log.warning("schema change messages is null");
+        }
+
+        if (schemaChangedMessage.missingAccountId()) {
+            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Invalid tenant",
+                    String.format("Required header: '%s' not found", DpsHeaders.DATA_PARTITION_ID));
+        }
+
+        try {
+            Type listType = new TypeToken<List<SchemaInfo>>() {}.getType();
+            List<SchemaInfo> schemaInfos = new Gson().fromJson(schemaChangedMessage.getData(), listType);
+
+            if (schemaInfos.size() == 0) {
+                log.warning("none of schema-change message can be deserialized");
+                return new ResponseEntity(org.springframework.http.HttpStatus.OK);
+            }
+            this.schemaService.processSchemaMessages(schemaInfos);
+            return new ResponseEntity(HttpStatus.OK);
+        } catch (JsonParseException e) {
+            throw new AppException(org.apache.http.HttpStatus.SC_BAD_REQUEST, "Request payload parsing error", "Unable to parse request payload.", e);
+        }
+    }
+}
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/ReindexApi.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/ReindexApi.java
index 4f6a1f666..a4f38e31d 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/ReindexApi.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/api/ReindexApi.java
@@ -1,64 +1,64 @@
-// 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.api;
-
-import org.opengroup.osdu.core.common.model.search.SearchServiceRole;
-import org.opengroup.osdu.indexer.logging.AuditLogger;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.indexer.service.IndexSchemaService;
-import org.opengroup.osdu.indexer.service.ReindexService;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.context.annotation.RequestScope;
-
-import javax.inject.Inject;
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
-
-import java.io.IOException;
-
-import static java.util.Collections.singletonList;
-
-@RestController
-@RequestMapping("/reindex")
-@RequestScope
-public class ReindexApi {
-
-    @Inject
-    private ReindexService reIndexService;
-    @Inject
-    private IndexSchemaService indexSchemaService;
-    @Inject
-    private AuditLogger auditLogger;
-
-    @PreAuthorize("@authorizationFilter.hasPermission('" + SearchServiceRole.ADMIN + "')")
-    @PostMapping
-    public ResponseEntity<?> reindex(
-            @NotNull @Valid @RequestBody RecordReindexRequest recordReindexRequest,
-            @RequestParam(value = "force_clean", defaultValue = "false") boolean forceClean) throws IOException {
-        this.reIndexService.reindexRecords(recordReindexRequest, this.indexSchemaService.isStorageSchemaSyncRequired(recordReindexRequest.getKind(), forceClean));
-        this.auditLogger.getReindex(singletonList(recordReindexRequest.getKind()));
-        return new ResponseEntity<>(org.springframework.http.HttpStatus.OK);
-    }
-
-    @PreAuthorize("@authorizationFilter.hasPermission('" + SearchServiceRole.ADMIN + "')")
-    @PatchMapping
-    public ResponseEntity<String> fullReindex(@RequestParam(value = "force_clean", defaultValue = "false") boolean forceClean) throws IOException {
-        this.reIndexService.fullReindex(forceClean);
-        return new ResponseEntity<>(org.springframework.http.HttpStatus.OK);
-    }
-}
+// 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.api;
+
+import org.opengroup.osdu.core.common.model.search.SearchServiceRole;
+import org.opengroup.osdu.indexer.logging.AuditLogger;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.indexer.service.IndexSchemaService;
+import org.opengroup.osdu.indexer.service.ReindexService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.annotation.RequestScope;
+
+import javax.inject.Inject;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+import java.io.IOException;
+
+import static java.util.Collections.singletonList;
+
+@RestController
+@RequestMapping("/reindex")
+@RequestScope
+public class ReindexApi {
+
+    @Inject
+    private ReindexService reIndexService;
+    @Inject
+    private IndexSchemaService indexSchemaService;
+    @Inject
+    private AuditLogger auditLogger;
+
+    @PreAuthorize("@authorizationFilter.hasPermission('" + SearchServiceRole.ADMIN + "')")
+    @PostMapping
+    public ResponseEntity<?> reindex(
+            @NotNull @Valid @RequestBody RecordReindexRequest recordReindexRequest,
+            @RequestParam(value = "force_clean", defaultValue = "false") boolean forceClean) throws IOException {
+        this.reIndexService.reindexRecords(recordReindexRequest, this.indexSchemaService.isStorageSchemaSyncRequired(recordReindexRequest.getKind(), forceClean));
+        this.auditLogger.getReindex(singletonList(recordReindexRequest.getKind()));
+        return new ResponseEntity<>(org.springframework.http.HttpStatus.OK);
+    }
+
+    @PreAuthorize("@authorizationFilter.hasPermission('" + SearchServiceRole.ADMIN + "')")
+    @PatchMapping
+    public ResponseEntity<String> fullReindex(@RequestParam(value = "force_clean", defaultValue = "false") boolean forceClean) throws IOException {
+        this.reIndexService.fullReindex(forceClean);
+        return new ResponseEntity<>(org.springframework.http.HttpStatus.OK);
+    }
+}
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java
index b91282586..017a12608 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java
@@ -1,233 +1,233 @@
-// 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.service;
-
-import com.google.common.base.Strings;
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-import com.google.gson.reflect.TypeToken;
-import java.lang.reflect.Array;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.function.BiFunction;
-import javax.inject.Inject;
-import org.apache.http.HttpStatus;
-import org.opengroup.osdu.core.common.model.indexer.ElasticType;
-import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
-import org.opengroup.osdu.core.common.model.indexer.JobStatus;
-import org.opengroup.osdu.indexer.util.parser.BooleanParser;
-import org.opengroup.osdu.indexer.util.parser.DateTimeParser;
-import org.opengroup.osdu.indexer.util.parser.GeoShapeParser;
-import org.opengroup.osdu.indexer.util.parser.NumberParser;
-import org.springframework.stereotype.Service;
-import org.springframework.web.context.annotation.RequestScope;
-
-@Service
-@RequestScope
-public class AttributeParsingServiceImpl implements IAttributeParsingService {
-
-    @Inject
-    private NumberParser numberParser;
-    @Inject
-    private BooleanParser booleanParser;
-    @Inject
-    private DateTimeParser dateTimeParser;
-    @Inject
-    private GeoShapeParser geoShapeParser;
-    @Inject
-    private GeometryConversionService geometryConversionService;
-    @Inject
-    private JobStatus jobStatus;
-
-    @Override
-    public void tryParseValueArray(Class<?> attributeClass, String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        BiFunction<String, Object, ?> parser;
-        ElasticType elasticType = ElasticType.forValue(attributeClass.getSimpleName());
-        switch (elasticType) {
-            case DOUBLE:
-                parser = this.numberParser::parseDouble;
-                break;
-            case FLOAT:
-                parser = this.numberParser::parseFloat;
-                break;
-            case INTEGER:
-                parser = this.numberParser::parseInteger;
-                break;
-            case LONG:
-                parser = this.numberParser::parseLong;
-                break;
-            case BOOLEAN:
-                parser = this.booleanParser::parseBoolean;
-                break;
-            case DATE:
-                parser = this.dateTimeParser::parseDate;
-                // DateTime parser output is String
-                attributeClass = String.class;
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid array attribute type");
-        }
-
-        try {
-            List<String> parsedStringList = isArrayType(attributeVal);
-            List out = new ArrayList<>();
-            for (Object o : parsedStringList) {
-                out.add(parser.apply(attributeName, o));
-            }
-            Object parsedAttribute = toTypeArray(attributeClass, out);
-            dataMap.put(attributeName, parsedAttribute);
-        } catch (IllegalArgumentException e) {
-            this.jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
-        }
-    }
-
-    @Override
-    public void tryParseInteger(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        try {
-            int parsedInteger = this.numberParser.parseInteger(attributeName, attributeVal);
-            dataMap.put(attributeName, parsedInteger);
-        } catch (IllegalArgumentException e) {
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
-        }
-    }
-
-    @Override
-    public void tryParseLong(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        try {
-            long parsedLong = this.numberParser.parseLong(attributeName, attributeVal);
-            dataMap.put(attributeName, parsedLong);
-        } catch (IllegalArgumentException e) {
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
-        }
-    }
-
-    @Override
-    public void tryParseFloat(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        try {
-            float parsedFloat = this.numberParser.parseFloat(attributeName, attributeVal);
-            dataMap.put(attributeName, parsedFloat);
-        } catch (IllegalArgumentException e) {
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
-        }
-    }
-
-    @Override
-    public void tryParseDouble(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        try {
-            double parsedDouble = this.numberParser.parseDouble(attributeName, attributeVal);
-            dataMap.put(attributeName, parsedDouble);
-        } catch (IllegalArgumentException e) {
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
-        }
-    }
-
-    @Override
-    public void tryParseBoolean(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        boolean parsedBoolean = this.booleanParser.parseBoolean(attributeName, attributeVal);
-        dataMap.put(attributeName, parsedBoolean);
-    }
-
-    @Override
-    public void tryParseDate(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-        try {
-            String parsedDate = this.dateTimeParser.parseDate(attributeName, attributeVal);
-            if (parsedDate == null) return;
-            dataMap.put(attributeName, parsedDate);
-        } catch (IllegalArgumentException e) {
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
-        }
-    }
-
-    @Override
-    public void tryParseGeopoint(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-
-        try {
-            Type type = new TypeToken<Map<String, Double>>() {}.getType();
-            Map<String, Double> positionMap = new Gson().fromJson(attributeVal.toString(), type);
-
-            if (positionMap == null || positionMap.isEmpty()) return;
-
-            Map<String, Double> position = this.geometryConversionService.tryGetGeopoint(positionMap);
-
-            if (position == null || position.isEmpty()) return;
-
-            dataMap.put(attributeName, position);
-        } catch (JsonSyntaxException | IllegalArgumentException e) {
-            String parsingError = String.format("geo-point parsing error: %s attribute: %s | value: %s", e.getMessage(), attributeName, attributeVal);
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, parsingError, String.format("record-id: %s | %s", recordId, parsingError));
-        }
-    }
-
-    @Override
-    public void tryParseGeojson(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
-
-        try {
-            Type type = new TypeToken<Map<String, Object>>() {}.getType();
-            Map<String, Object> geoJsonMap = new Gson().fromJson(attributeVal.toString(), type);
-
-            if (geoJsonMap == null || geoJsonMap.isEmpty()) return;
-
-            Map<String, Object> parsedShape = this.geoShapeParser.parseGeoJson(geoJsonMap);
-
-            dataMap.put(attributeName, parsedShape);
-        } catch (JsonSyntaxException | IllegalArgumentException e) {
-            String parsingError = String.format("geo-json shape parsing error: %s attribute: %s", e.getMessage(), attributeName);
-            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, parsingError, String.format("record-id: %s | %s", recordId, parsingError));
-        }
-    }
-
-	@Override
-	public void tryParseNested(String recordId, String name, Object value, Map<String, Object> dataMap) {
-		dataMap.put(name,value);
-	}
-
-	@Override
-	public void tryParseObject(String recordId, String name, Object value, Map<String, Object> dataMap) {
-		dataMap.put(name,value);
-	}
-
-    @Override
-    public void tryParseFlattened(String recordId, String name, Object value, Map<String, Object> dataMap) {
-        dataMap.put(name,value);
-    }
-
-
-    private List<String> isArrayType(Object attributeVal) {
-        try {
-            String value = attributeVal == null ? null : String.valueOf(attributeVal);
-            if (attributeVal == null || Strings.isNullOrEmpty(value)) {
-                return Collections.EMPTY_LIST;
-            }
-
-            Gson converter = new Gson();
-            Type type = new TypeToken<List<String>>() {}.getType();
-            return converter.fromJson(value, type);
-        } catch (JsonSyntaxException e) {
-            throw new IllegalArgumentException("array parsing error, not a valid array");
-        }
-    }
-
-    private <N> N toTypeArray(Class<N> fieldClass, List<?> list) {
-        Object array = Array.newInstance(fieldClass, list.size());
-        for (int i = 0; i < list.size(); i++) {
-            Array.set(array, i, list.get(i));
-        }
-        return (N) array;
-    }
-}
-
+// 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.service;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Array;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import javax.inject.Inject;
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.core.common.model.indexer.ElasticType;
+import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
+import org.opengroup.osdu.core.common.model.indexer.JobStatus;
+import org.opengroup.osdu.indexer.util.parser.BooleanParser;
+import org.opengroup.osdu.indexer.util.parser.DateTimeParser;
+import org.opengroup.osdu.indexer.util.parser.GeoShapeParser;
+import org.opengroup.osdu.indexer.util.parser.NumberParser;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.annotation.RequestScope;
+
+@Service
+@RequestScope
+public class AttributeParsingServiceImpl implements IAttributeParsingService {
+
+    @Inject
+    private NumberParser numberParser;
+    @Inject
+    private BooleanParser booleanParser;
+    @Inject
+    private DateTimeParser dateTimeParser;
+    @Inject
+    private GeoShapeParser geoShapeParser;
+    @Inject
+    private GeometryConversionService geometryConversionService;
+    @Inject
+    private JobStatus jobStatus;
+
+    @Override
+    public void tryParseValueArray(Class<?> attributeClass, String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        BiFunction<String, Object, ?> parser;
+        ElasticType elasticType = ElasticType.forValue(attributeClass.getSimpleName());
+        switch (elasticType) {
+            case DOUBLE:
+                parser = this.numberParser::parseDouble;
+                break;
+            case FLOAT:
+                parser = this.numberParser::parseFloat;
+                break;
+            case INTEGER:
+                parser = this.numberParser::parseInteger;
+                break;
+            case LONG:
+                parser = this.numberParser::parseLong;
+                break;
+            case BOOLEAN:
+                parser = this.booleanParser::parseBoolean;
+                break;
+            case DATE:
+                parser = this.dateTimeParser::parseDate;
+                // DateTime parser output is String
+                attributeClass = String.class;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid array attribute type");
+        }
+
+        try {
+            List<String> parsedStringList = isArrayType(attributeVal);
+            List out = new ArrayList<>();
+            for (Object o : parsedStringList) {
+                out.add(parser.apply(attributeName, o));
+            }
+            Object parsedAttribute = toTypeArray(attributeClass, out);
+            dataMap.put(attributeName, parsedAttribute);
+        } catch (IllegalArgumentException e) {
+            this.jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
+        }
+    }
+
+    @Override
+    public void tryParseInteger(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        try {
+            int parsedInteger = this.numberParser.parseInteger(attributeName, attributeVal);
+            dataMap.put(attributeName, parsedInteger);
+        } catch (IllegalArgumentException e) {
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
+        }
+    }
+
+    @Override
+    public void tryParseLong(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        try {
+            long parsedLong = this.numberParser.parseLong(attributeName, attributeVal);
+            dataMap.put(attributeName, parsedLong);
+        } catch (IllegalArgumentException e) {
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
+        }
+    }
+
+    @Override
+    public void tryParseFloat(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        try {
+            float parsedFloat = this.numberParser.parseFloat(attributeName, attributeVal);
+            dataMap.put(attributeName, parsedFloat);
+        } catch (IllegalArgumentException e) {
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
+        }
+    }
+
+    @Override
+    public void tryParseDouble(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        try {
+            double parsedDouble = this.numberParser.parseDouble(attributeName, attributeVal);
+            dataMap.put(attributeName, parsedDouble);
+        } catch (IllegalArgumentException e) {
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
+        }
+    }
+
+    @Override
+    public void tryParseBoolean(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        boolean parsedBoolean = this.booleanParser.parseBoolean(attributeName, attributeVal);
+        dataMap.put(attributeName, parsedBoolean);
+    }
+
+    @Override
+    public void tryParseDate(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+        try {
+            String parsedDate = this.dateTimeParser.parseDate(attributeName, attributeVal);
+            if (parsedDate == null) return;
+            dataMap.put(attributeName, parsedDate);
+        } catch (IllegalArgumentException e) {
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, e.getMessage(), String.format("record-id: %s | %s", recordId, e.getMessage()));
+        }
+    }
+
+    @Override
+    public void tryParseGeopoint(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+
+        try {
+            Type type = new TypeToken<Map<String, Double>>() {}.getType();
+            Map<String, Double> positionMap = new Gson().fromJson(attributeVal.toString(), type);
+
+            if (positionMap == null || positionMap.isEmpty()) return;
+
+            Map<String, Double> position = this.geometryConversionService.tryGetGeopoint(positionMap);
+
+            if (position == null || position.isEmpty()) return;
+
+            dataMap.put(attributeName, position);
+        } catch (JsonSyntaxException | IllegalArgumentException e) {
+            String parsingError = String.format("geo-point parsing error: %s attribute: %s | value: %s", e.getMessage(), attributeName, attributeVal);
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, parsingError, String.format("record-id: %s | %s", recordId, parsingError));
+        }
+    }
+
+    @Override
+    public void tryParseGeojson(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) {
+
+        try {
+            Type type = new TypeToken<Map<String, Object>>() {}.getType();
+            Map<String, Object> geoJsonMap = new Gson().fromJson(attributeVal.toString(), type);
+
+            if (geoJsonMap == null || geoJsonMap.isEmpty()) return;
+
+            Map<String, Object> parsedShape = this.geoShapeParser.parseGeoJson(geoJsonMap);
+
+            dataMap.put(attributeName, parsedShape);
+        } catch (JsonSyntaxException | IllegalArgumentException e) {
+            String parsingError = String.format("geo-json shape parsing error: %s attribute: %s", e.getMessage(), attributeName);
+            jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, parsingError, String.format("record-id: %s | %s", recordId, parsingError));
+        }
+    }
+
+	@Override
+	public void tryParseNested(String recordId, String name, Object value, Map<String, Object> dataMap) {
+		dataMap.put(name,value);
+	}
+
+	@Override
+	public void tryParseObject(String recordId, String name, Object value, Map<String, Object> dataMap) {
+		dataMap.put(name,value);
+	}
+
+    @Override
+    public void tryParseFlattened(String recordId, String name, Object value, Map<String, Object> dataMap) {
+        dataMap.put(name,value);
+    }
+
+
+    private List<String> isArrayType(Object attributeVal) {
+        try {
+            String value = attributeVal == null ? null : String.valueOf(attributeVal);
+            if (attributeVal == null || Strings.isNullOrEmpty(value)) {
+                return Collections.EMPTY_LIST;
+            }
+
+            Gson converter = new Gson();
+            Type type = new TypeToken<List<String>>() {}.getType();
+            return converter.fromJson(value, type);
+        } catch (JsonSyntaxException e) {
+            throw new IllegalArgumentException("array parsing error, not a valid array");
+        }
+    }
+
+    private <N> N toTypeArray(Class<N> fieldClass, List<?> list) {
+        Object array = Array.newInstance(fieldClass, list.size());
+        for (int i = 0; i < list.size(); i++) {
+            Array.set(array, i, list.get(i));
+        }
+        return (N) array;
+    }
+}
+
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexSchemaService.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexSchemaService.java
index e474feef6..d19833f25 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexSchemaService.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexSchemaService.java
@@ -1,43 +1,43 @@
-// 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.service;
-
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.ElasticsearchStatusException;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
-import org.opengroup.osdu.core.common.model.indexer.OperationType;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.Map;
-
-public interface IndexSchemaService {
-
-    IndexSchema getIndexerInputSchema(String kind, List<String> errors) throws AppException, UnsupportedEncodingException, URISyntaxException;
-
-    IndexSchema getIndexerInputSchema(String kind, boolean invalidateCached) throws AppException, UnsupportedEncodingException, URISyntaxException;
-
-    void processSchemaMessages(Map<String, OperationType> schemaMsgs) throws IOException;
-
-    void processSchemaUpsertEvent(RestHighLevelClient restClient, String kind) throws IOException, ElasticsearchStatusException, URISyntaxException;
-
-    void syncIndexMappingWithStorageSchema(String kind) throws ElasticsearchException, IOException, AppException, URISyntaxException;
-
-    boolean isStorageSchemaSyncRequired(String kind, boolean forceClean) throws IOException;
-}
+// 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.service;
+
+import org.elasticsearch.ElasticsearchException;
+import org.elasticsearch.ElasticsearchStatusException;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
+import org.opengroup.osdu.core.common.model.indexer.OperationType;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+
+public interface IndexSchemaService {
+
+    IndexSchema getIndexerInputSchema(String kind, List<String> errors) throws AppException, UnsupportedEncodingException, URISyntaxException;
+
+    IndexSchema getIndexerInputSchema(String kind, boolean invalidateCached) throws AppException, UnsupportedEncodingException, URISyntaxException;
+
+    void processSchemaMessages(Map<String, OperationType> schemaMsgs) throws IOException;
+
+    void processSchemaUpsertEvent(RestHighLevelClient restClient, String kind) throws IOException, ElasticsearchStatusException, URISyntaxException;
+
+    void syncIndexMappingWithStorageSchema(String kind) throws ElasticsearchException, IOException, AppException, URISyntaxException;
+
+    boolean isStorageSchemaSyncRequired(String kind, boolean forceClean) throws IOException;
+}
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java
index 13738aefa..c10da49c0 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceImpl.java
@@ -1,402 +1,402 @@
-// 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.service;
-
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import com.lambdaworks.redis.RedisException;
-import org.apache.http.HttpStatus;
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.action.support.master.AcknowledgedResponse;
-import org.elasticsearch.client.Request;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.Response;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.client.indices.GetFieldMappingsRequest;
-import org.elasticsearch.client.indices.GetFieldMappingsResponse;
-import org.elasticsearch.client.indices.PutMappingRequest;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.common.xcontent.XContentType;
-import org.elasticsearch.index.reindex.BulkByScrollResponse;
-import org.elasticsearch.index.reindex.UpdateByQueryRequest;
-import org.opengroup.osdu.core.common.Constants;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
-import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
-import org.opengroup.osdu.core.common.search.ElasticIndexNameResolver;
-import org.opengroup.osdu.core.common.search.Preconditions;
-import org.opengroup.osdu.indexer.cache.PartitionSafeIndexCache;
-import org.opengroup.osdu.indexer.model.Kind;
-import org.opengroup.osdu.indexer.util.ElasticClientHandler;
-import org.opengroup.osdu.indexer.util.TypeMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Inject;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.*;
-
-@Service
-public class IndexerMappingServiceImpl extends MappingServiceImpl implements IMappingService {
-
-    @Inject
-    private JaxRsDpsLog log;
-    @Inject
-    private ElasticClientHandler elasticClientHandler;
-    @Autowired
-    private PartitionSafeIndexCache indexCache;
-    @Autowired
-    private IMappingService mappingService;
-    @Autowired
-    private ElasticIndexNameResolver elasticIndexNameResolver;
-
-    private static TimeValue REQUEST_TIMEOUT = TimeValue.timeValueMinutes(1);
-
-
-    /**
-     * Create a new type in Elasticsearch
-     *
-     * @param client Elasticsearch client
-     * @param index  Index name
-     * @param merge  Try to merge mapping if type already exists
-     * @throws IOException if cannot create mapping
-     */
-    public String createMapping(RestHighLevelClient client, IndexSchema schema, String index, boolean merge) throws IOException {
-
-        Map<String, Object> mappingMap = this.getIndexMappingFromRecordSchema(schema);
-        String mapping = new Gson().toJson(mappingMap, Map.class);
-        this.createMappingWithJson(client, index, schema.getType(), mapping, merge);
-        return mapping;
-    }
-
-    /*
-     * Read schema mapping
-     *
-     * @param schema Index schema
-     * @param type   Mapping type
-     * @return String JSON representation of type and elastic type
-     *
-     * sample index mapping:
-     * "properties": {
-     *      all meta attributes
-     *      "acl": {
-     *          "properties": {
-                    mapping of all roles
-     *          }
-     *      },
-     *      "legal": {
-     *          "properties": {
-     *              mapping of all legal properties
-     *          }
-     *      }
-     *      "data": {
-     *          "properties": {
-     *              all data-source attributes
-     *           }
-     *       }
-     *  }
-     * */
-    public Map<String, Object> getIndexMappingFromRecordSchema(IndexSchema schema) {
-
-        // entire property block
-        Map<String, Object> properties = new HashMap<>();
-
-        // meta  attribute
-        Map<String, Object> metaMapping = this.getMetaMapping(schema);
-
-        // data-source attributes
-        Map<String, Object> dataMapping = this.getDataMapping(schema);
-        if (!dataMapping.isEmpty()) {
-            // inner properties.data.properties block
-            Map<String, Object> dataProperties = new HashMap<>();
-            dataProperties.put(Constants.PROPERTIES, dataMapping);
-
-            // data & meta block
-            properties.put(Constants.DATA, dataProperties);
-        }
-        properties.putAll(metaMapping);
-
-        // entire document properties block
-        Map<String, Object> documentMapping = new HashMap<>();
-        documentMapping.put(Constants.PROPERTIES, properties);
-
-        // don't add dynamic mapping
-        documentMapping.put("dynamic", false);
-        return documentMapping;
-    }
-
-    private Map<String, Object> getMetaMapping(IndexSchema schema) {
-        Map<String, Object> metaMapping = new HashMap<>();
-        Kind kind = new Kind(schema.getKind());
-
-        for (Map.Entry<String, Object> entry : schema.getMetaSchema().entrySet()) {
-            if (entry.getKey() == RecordMetaAttribute.AUTHORITY.getValue()) {
-                metaMapping.put(entry.getKey(), TypeMapper.getMetaAttributeIndexerMapping(entry.getKey(), kind.getAuthority()));
-            } else if (entry.getKey() == RecordMetaAttribute.SOURCE.getValue()) {
-                metaMapping.put(entry.getKey(), TypeMapper.getMetaAttributeIndexerMapping(entry.getKey(), kind.getSource()));
-            } else {
-                metaMapping.put(entry.getKey(), TypeMapper.getMetaAttributeIndexerMapping(entry.getKey(), null));
-            }
-        }
-        return metaMapping;
-    }
-
-    private Map<String, Object> getDataMapping(IndexSchema schema) {
-        Map<String, Object> dataMapping = new HashMap<>();
-        if (schema.getDataSchema() == null || schema.getDataSchema().isEmpty()) return dataMapping;
-
-        for (Map.Entry<String, Object> entry : schema.getDataSchema().entrySet()) {
-            dataMapping.put(entry.getKey(), TypeMapper.getDataAttributeIndexerMapping(entry.getValue()));
-        }
-        return dataMapping;
-    }
-
-    @Override
-    public void updateIndexMappingForIndicesOfSameType(Set<String> indices, String fieldName) throws Exception {
-        try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) {
-            if(!updateMappingToEnableKeywordIndexingForField(restClient,indices,fieldName)){
-                throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error updating index mapping.", String.format("Failed to get confirmation from elastic server mapping update for indices: %s", indices));
-            }
-        }
-    }
-
-    @Override
-    public void syncIndexMappingIfRequired(RestHighLevelClient restClient, IndexSchema schema) throws Exception {
-        String index = this.elasticIndexNameResolver.getIndexNameFromKind(schema.getKind());
-        final String cacheKey = String.format("metaAttributeMappingSynced-%s", index);
-
-        try {
-            Boolean mappingSynced = (Boolean) this.indexCache.get(cacheKey);
-            if (mappingSynced != null && mappingSynced) return;
-        } catch (RedisException ex) {
-            //In case the format of cache changes then clean the cache
-            this.indexCache.delete(cacheKey);
-        }
-
-        String jsonResponse = this.mappingService.getIndexMapping(restClient, index);
-        Type type = new TypeToken<Map<String, Object>>() {}.getType();
-        Map<String, Object> mappings = new Gson().fromJson(jsonResponse, type);
-
-        if (mappings == null || mappings.isEmpty()) return;
-
-        Map<String, Object> props = (Map<String, Object>) mappings.get("properties");
-
-        if (props == null || props.isEmpty()) return;
-
-        List<String> missing = new ArrayList<>();
-        for (String attribute : TypeMapper.getMetaAttributesKeys()) {
-            if (props.containsKey(attribute)) continue;
-            missing.add(attribute);
-        }
-
-        if (missing.isEmpty()) {
-            this.indexCache.put(cacheKey, true);
-            return;
-        }
-
-        Map<String, Object> properties = new HashMap<>();
-        Kind kind = new Kind(schema.getKind());
-        for (String attribute : missing) {
-            if (attribute == RecordMetaAttribute.AUTHORITY.getValue()) {
-                properties.put(attribute, TypeMapper.getMetaAttributeIndexerMapping(attribute, kind.getAuthority()));
-            } else if (attribute == RecordMetaAttribute.SOURCE.getValue()) {
-                properties.put(attribute, TypeMapper.getMetaAttributeIndexerMapping(attribute, kind.getSource()));
-            } else {
-                properties.put(attribute, TypeMapper.getMetaAttributeIndexerMapping(attribute, null));
-            }
-        }
-
-        Map<String, Object> documentMapping = new HashMap<>();
-        documentMapping.put(Constants.PROPERTIES, properties);
-
-        String mapping = new Gson().toJson(documentMapping, Map.class);
-        this.createMappingWithJson(restClient, index, "_doc", mapping, true);
-
-        this.indexCache.put(cacheKey, true);
-    }
-
-    private boolean updateMappingToEnableKeywordIndexingForField(RestHighLevelClient client, Set<String> indicesSet, String fieldName) throws IOException {
-        String[] indices = indicesSet.toArray(new String[indicesSet.size()]);
-        Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> indexMappingMap = getIndexFieldMap(new String[]{"data."+fieldName}, client, indices);
-        boolean failure = false;
-        for (String index : indicesSet) {
-            if (indexMappingMap.get(index)!=null && updateMappingForAllIndicesOfSameTypeToEnableKeywordIndexingForField(client, index, indexMappingMap.get(index), fieldName)) {
-                log.info(String.format("Updated field: %s | index:  %s", fieldName, index));
-            } else {
-                failure=true;
-                log.warning(String.format("Failed to update field: %s | index  %s", fieldName, index));
-            }
-        }
-        return !failure;
-    }
-
-    private Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> getIndexFieldMap(String[] fieldNames, RestHighLevelClient client, String[] indices) throws IOException  {
-        Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> indexMappingMap = new HashMap<>();
-        GetFieldMappingsRequest request = new GetFieldMappingsRequest();
-        request.indices(indices);
-        request.fields(fieldNames);
-        try {
-            GetFieldMappingsResponse response = client.indices().getFieldMapping(request, RequestOptions.DEFAULT);
-            if (response != null && !response.mappings().isEmpty()) {
-                final Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappings = response.mappings();
-                for (String index : indices) {
-                    if (mappings != null && !mappings.isEmpty()) {
-                        indexMappingMap.put(index, mappings);
-                    }
-                }
-            }
-
-            return indexMappingMap;
-        } catch (ElasticsearchException e) {
-            log.error(String.format("Failed to get indices: %s. | Error: %s", Arrays.toString(indices), e));
-            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error getting indices.", String.format("Failed to get indices error: %s", Arrays.toString(indices)));
-        }
-    }
-
-    private boolean updateMappingForAllIndicesOfSameTypeToEnableKeywordIndexingForField(
-            RestHighLevelClient client, String index, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> indexMapping, String fieldName) throws IOException {
-
-        PutMappingRequest request = new PutMappingRequest(index);
-        String type = indexMapping.keySet().iterator().next();
-        if(type.isEmpty()) {
-        	log.error(String.format("Could not find type of the mappings for index: %s.", index));
-            return false;
-        }
-
-        request.setTimeout(REQUEST_TIMEOUT);
-        Map<String, GetFieldMappingsResponse.FieldMappingMetadata> metaData = indexMapping.get(type);
-        if(metaData==null || metaData.get("data." + fieldName)==null) {
-            log.error(String.format("Could not find field: %s in the mapping of index: %s.", fieldName, index));
-            return false;
-        }
-
-        GetFieldMappingsResponse.FieldMappingMetadata fieldMetaData = metaData.get("data." + fieldName);
-        Map<String, Object> source = fieldMetaData.sourceAsMap();
-        if(!source.containsKey(fieldName)){
-            log.error(String.format("Could not find field: %s in the mapping of index: %s.", fieldName, index));
-            return false;
-        }
-
-        //Index the field with additional keyword type
-        Map<String, Object> keywordMap = new HashMap<>();
-        keywordMap.put(Constants.TYPE, "keyword");
-        Map<String, Object> fieldIndexTypeMap = new HashMap<>();
-        fieldIndexTypeMap.put("keyword", keywordMap);
-        Map<String, Object> dataFieldMap = (Map<String, Object>) source.get(fieldName);
-        dataFieldMap.put("fields", fieldIndexTypeMap);
-        Map<String, Object> dataProperties = new HashMap<>();
-        dataProperties.put(fieldName, dataFieldMap);
-        Map<String, Object> mapping = new HashMap<>();
-        mapping.put(Constants.PROPERTIES, dataProperties);
-        Map<String, Object> data = new HashMap<>();
-        data.put(Constants.DATA,mapping);
-        Map<String, Object> properties = new HashMap<>();
-        properties.put(Constants.PROPERTIES, data);
-
-        request.source(new Gson().toJson(properties), XContentType.JSON);
-
-        try {
-            AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
-            boolean isIndicesUpdated = updateIndices(client, index);
-            return response.isAcknowledged() && isIndicesUpdated;
-
-        } catch (Exception e) {
-            log.error(String.format("Could not update mapping of index: %s. | Error: %s", index, e));
-            return false;
-        }
-    }
-
-    private boolean updateIndices(RestHighLevelClient client, String index) throws IOException {
-        UpdateByQueryRequest request = new UpdateByQueryRequest(index);
-        request.setConflicts("proceed");
-        BulkByScrollResponse response = client.updateByQuery(request, RequestOptions.DEFAULT);
-        if(!response.getBulkFailures().isEmpty()) {
-        	log.error(String.format("Could not update index: %s.",index));
-        	return false;
-        }
-		return true;
-    }
-
-    /**
-     * Create a new type in Elasticsearch
-     *
-     * @param client  Elasticsearch client
-     * @param index   Index name
-     * @param type    Type name
-     * @param mapping Mapping if any, null if no specific mapping
-     * @param merge   Try to merge mapping if type already exists
-     * @throws IOException if cannot create index mapping with input json
-     */
-    private void createMappingWithJson(RestHighLevelClient client, String index, String type, String mapping, boolean merge)
-            throws IOException {
-
-        boolean mappingExist = isTypeExist(client, index, type);
-        if (merge || !mappingExist) {
-            createTypeWithMappingInElasticsearch(client, index, type, mapping);
-        }
-    }
-
-    /**
-     * Check if a type already exists
-     *
-     * @param client Elasticsearch client
-     * @param index  Index name
-     * @param type   Type name
-     * @return true if type already exists
-     * @throws IOException in case Elasticsearch responded with a status code that indicated an error
-     */
-    public boolean isTypeExist(RestHighLevelClient client, String index, String type) throws IOException {
-
-        Request request = new Request("HEAD", "/" + index + "/_mapping/" + type);
-        Response response = client.getLowLevelClient().performRequest(request);
-        return response.getStatusLine().getStatusCode() == 200;
-    }
-
-    /**
-     * Create a new type in Elasticsearch
-     *
-     * @param client  Elasticsearch client
-     * @param index   Index name
-     * @param type    Type name
-     * @param mapping Mapping if any, null if no specific mapping
-     * @throws IOException if mapping cannot be created
-     */
-    private Boolean createTypeWithMappingInElasticsearch(RestHighLevelClient client, String index, String type, String mapping) throws IOException {
-
-        Preconditions.checkNotNull(client, "client cannot be null");
-        Preconditions.checkNotNull(index, "index cannot be null");
-        Preconditions.checkNotNull(type, "type cannot be null");
-
-        try {
-            if (mapping != null) {
-                PutMappingRequest request = new PutMappingRequest(index);
-                request.source(mapping, XContentType.JSON);
-                request.setTimeout(REQUEST_TIMEOUT);
-                AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
-                return response.isAcknowledged();
-            }
-        } catch (ElasticsearchException e) {
-            throw new AppException(
-                    e.status().getStatus(),
-                    e.getMessage(),
-                    String.format("Could not create type mapping %s/%s.", index, type),
-                    String.format("Failed creating mapping: %s", mapping),
-                    e);
-        }
-        return false;
-    }
+// 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.service;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.lambdaworks.redis.RedisException;
+import org.apache.http.HttpStatus;
+import org.elasticsearch.ElasticsearchException;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.client.indices.GetFieldMappingsRequest;
+import org.elasticsearch.client.indices.GetFieldMappingsResponse;
+import org.elasticsearch.client.indices.PutMappingRequest;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.index.reindex.BulkByScrollResponse;
+import org.elasticsearch.index.reindex.UpdateByQueryRequest;
+import org.opengroup.osdu.core.common.Constants;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
+import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
+import org.opengroup.osdu.core.common.search.ElasticIndexNameResolver;
+import org.opengroup.osdu.core.common.search.Preconditions;
+import org.opengroup.osdu.indexer.cache.PartitionSafeIndexCache;
+import org.opengroup.osdu.indexer.model.Kind;
+import org.opengroup.osdu.indexer.util.ElasticClientHandler;
+import org.opengroup.osdu.indexer.util.TypeMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.*;
+
+@Service
+public class IndexerMappingServiceImpl extends MappingServiceImpl implements IMappingService {
+
+    @Inject
+    private JaxRsDpsLog log;
+    @Inject
+    private ElasticClientHandler elasticClientHandler;
+    @Autowired
+    private PartitionSafeIndexCache indexCache;
+    @Autowired
+    private IMappingService mappingService;
+    @Autowired
+    private ElasticIndexNameResolver elasticIndexNameResolver;
+
+    private static TimeValue REQUEST_TIMEOUT = TimeValue.timeValueMinutes(1);
+
+
+    /**
+     * Create a new type in Elasticsearch
+     *
+     * @param client Elasticsearch client
+     * @param index  Index name
+     * @param merge  Try to merge mapping if type already exists
+     * @throws IOException if cannot create mapping
+     */
+    public String createMapping(RestHighLevelClient client, IndexSchema schema, String index, boolean merge) throws IOException {
+
+        Map<String, Object> mappingMap = this.getIndexMappingFromRecordSchema(schema);
+        String mapping = new Gson().toJson(mappingMap, Map.class);
+        this.createMappingWithJson(client, index, schema.getType(), mapping, merge);
+        return mapping;
+    }
+
+    /*
+     * Read schema mapping
+     *
+     * @param schema Index schema
+     * @param type   Mapping type
+     * @return String JSON representation of type and elastic type
+     *
+     * sample index mapping:
+     * "properties": {
+     *      all meta attributes
+     *      "acl": {
+     *          "properties": {
+                    mapping of all roles
+     *          }
+     *      },
+     *      "legal": {
+     *          "properties": {
+     *              mapping of all legal properties
+     *          }
+     *      }
+     *      "data": {
+     *          "properties": {
+     *              all data-source attributes
+     *           }
+     *       }
+     *  }
+     * */
+    public Map<String, Object> getIndexMappingFromRecordSchema(IndexSchema schema) {
+
+        // entire property block
+        Map<String, Object> properties = new HashMap<>();
+
+        // meta  attribute
+        Map<String, Object> metaMapping = this.getMetaMapping(schema);
+
+        // data-source attributes
+        Map<String, Object> dataMapping = this.getDataMapping(schema);
+        if (!dataMapping.isEmpty()) {
+            // inner properties.data.properties block
+            Map<String, Object> dataProperties = new HashMap<>();
+            dataProperties.put(Constants.PROPERTIES, dataMapping);
+
+            // data & meta block
+            properties.put(Constants.DATA, dataProperties);
+        }
+        properties.putAll(metaMapping);
+
+        // entire document properties block
+        Map<String, Object> documentMapping = new HashMap<>();
+        documentMapping.put(Constants.PROPERTIES, properties);
+
+        // don't add dynamic mapping
+        documentMapping.put("dynamic", false);
+        return documentMapping;
+    }
+
+    private Map<String, Object> getMetaMapping(IndexSchema schema) {
+        Map<String, Object> metaMapping = new HashMap<>();
+        Kind kind = new Kind(schema.getKind());
+
+        for (Map.Entry<String, Object> entry : schema.getMetaSchema().entrySet()) {
+            if (entry.getKey() == RecordMetaAttribute.AUTHORITY.getValue()) {
+                metaMapping.put(entry.getKey(), TypeMapper.getMetaAttributeIndexerMapping(entry.getKey(), kind.getAuthority()));
+            } else if (entry.getKey() == RecordMetaAttribute.SOURCE.getValue()) {
+                metaMapping.put(entry.getKey(), TypeMapper.getMetaAttributeIndexerMapping(entry.getKey(), kind.getSource()));
+            } else {
+                metaMapping.put(entry.getKey(), TypeMapper.getMetaAttributeIndexerMapping(entry.getKey(), null));
+            }
+        }
+        return metaMapping;
+    }
+
+    private Map<String, Object> getDataMapping(IndexSchema schema) {
+        Map<String, Object> dataMapping = new HashMap<>();
+        if (schema.getDataSchema() == null || schema.getDataSchema().isEmpty()) return dataMapping;
+
+        for (Map.Entry<String, Object> entry : schema.getDataSchema().entrySet()) {
+            dataMapping.put(entry.getKey(), TypeMapper.getDataAttributeIndexerMapping(entry.getValue()));
+        }
+        return dataMapping;
+    }
+
+    @Override
+    public void updateIndexMappingForIndicesOfSameType(Set<String> indices, String fieldName) throws Exception {
+        try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) {
+            if(!updateMappingToEnableKeywordIndexingForField(restClient,indices,fieldName)){
+                throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error updating index mapping.", String.format("Failed to get confirmation from elastic server mapping update for indices: %s", indices));
+            }
+        }
+    }
+
+    @Override
+    public void syncIndexMappingIfRequired(RestHighLevelClient restClient, IndexSchema schema) throws Exception {
+        String index = this.elasticIndexNameResolver.getIndexNameFromKind(schema.getKind());
+        final String cacheKey = String.format("metaAttributeMappingSynced-%s", index);
+
+        try {
+            Boolean mappingSynced = (Boolean) this.indexCache.get(cacheKey);
+            if (mappingSynced != null && mappingSynced) return;
+        } catch (RedisException ex) {
+            //In case the format of cache changes then clean the cache
+            this.indexCache.delete(cacheKey);
+        }
+
+        String jsonResponse = this.mappingService.getIndexMapping(restClient, index);
+        Type type = new TypeToken<Map<String, Object>>() {}.getType();
+        Map<String, Object> mappings = new Gson().fromJson(jsonResponse, type);
+
+        if (mappings == null || mappings.isEmpty()) return;
+
+        Map<String, Object> props = (Map<String, Object>) mappings.get("properties");
+
+        if (props == null || props.isEmpty()) return;
+
+        List<String> missing = new ArrayList<>();
+        for (String attribute : TypeMapper.getMetaAttributesKeys()) {
+            if (props.containsKey(attribute)) continue;
+            missing.add(attribute);
+        }
+
+        if (missing.isEmpty()) {
+            this.indexCache.put(cacheKey, true);
+            return;
+        }
+
+        Map<String, Object> properties = new HashMap<>();
+        Kind kind = new Kind(schema.getKind());
+        for (String attribute : missing) {
+            if (attribute == RecordMetaAttribute.AUTHORITY.getValue()) {
+                properties.put(attribute, TypeMapper.getMetaAttributeIndexerMapping(attribute, kind.getAuthority()));
+            } else if (attribute == RecordMetaAttribute.SOURCE.getValue()) {
+                properties.put(attribute, TypeMapper.getMetaAttributeIndexerMapping(attribute, kind.getSource()));
+            } else {
+                properties.put(attribute, TypeMapper.getMetaAttributeIndexerMapping(attribute, null));
+            }
+        }
+
+        Map<String, Object> documentMapping = new HashMap<>();
+        documentMapping.put(Constants.PROPERTIES, properties);
+
+        String mapping = new Gson().toJson(documentMapping, Map.class);
+        this.createMappingWithJson(restClient, index, "_doc", mapping, true);
+
+        this.indexCache.put(cacheKey, true);
+    }
+
+    private boolean updateMappingToEnableKeywordIndexingForField(RestHighLevelClient client, Set<String> indicesSet, String fieldName) throws IOException {
+        String[] indices = indicesSet.toArray(new String[indicesSet.size()]);
+        Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> indexMappingMap = getIndexFieldMap(new String[]{"data."+fieldName}, client, indices);
+        boolean failure = false;
+        for (String index : indicesSet) {
+            if (indexMappingMap.get(index)!=null && updateMappingForAllIndicesOfSameTypeToEnableKeywordIndexingForField(client, index, indexMappingMap.get(index), fieldName)) {
+                log.info(String.format("Updated field: %s | index:  %s", fieldName, index));
+            } else {
+                failure=true;
+                log.warning(String.format("Failed to update field: %s | index  %s", fieldName, index));
+            }
+        }
+        return !failure;
+    }
+
+    private Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> getIndexFieldMap(String[] fieldNames, RestHighLevelClient client, String[] indices) throws IOException  {
+        Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> indexMappingMap = new HashMap<>();
+        GetFieldMappingsRequest request = new GetFieldMappingsRequest();
+        request.indices(indices);
+        request.fields(fieldNames);
+        try {
+            GetFieldMappingsResponse response = client.indices().getFieldMapping(request, RequestOptions.DEFAULT);
+            if (response != null && !response.mappings().isEmpty()) {
+                final Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappings = response.mappings();
+                for (String index : indices) {
+                    if (mappings != null && !mappings.isEmpty()) {
+                        indexMappingMap.put(index, mappings);
+                    }
+                }
+            }
+
+            return indexMappingMap;
+        } catch (ElasticsearchException e) {
+            log.error(String.format("Failed to get indices: %s. | Error: %s", Arrays.toString(indices), e));
+            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error getting indices.", String.format("Failed to get indices error: %s", Arrays.toString(indices)));
+        }
+    }
+
+    private boolean updateMappingForAllIndicesOfSameTypeToEnableKeywordIndexingForField(
+            RestHighLevelClient client, String index, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> indexMapping, String fieldName) throws IOException {
+
+        PutMappingRequest request = new PutMappingRequest(index);
+        String type = indexMapping.keySet().iterator().next();
+        if(type.isEmpty()) {
+        	log.error(String.format("Could not find type of the mappings for index: %s.", index));
+            return false;
+        }
+
+        request.setTimeout(REQUEST_TIMEOUT);
+        Map<String, GetFieldMappingsResponse.FieldMappingMetadata> metaData = indexMapping.get(type);
+        if(metaData==null || metaData.get("data." + fieldName)==null) {
+            log.error(String.format("Could not find field: %s in the mapping of index: %s.", fieldName, index));
+            return false;
+        }
+
+        GetFieldMappingsResponse.FieldMappingMetadata fieldMetaData = metaData.get("data." + fieldName);
+        Map<String, Object> source = fieldMetaData.sourceAsMap();
+        if(!source.containsKey(fieldName)){
+            log.error(String.format("Could not find field: %s in the mapping of index: %s.", fieldName, index));
+            return false;
+        }
+
+        //Index the field with additional keyword type
+        Map<String, Object> keywordMap = new HashMap<>();
+        keywordMap.put(Constants.TYPE, "keyword");
+        Map<String, Object> fieldIndexTypeMap = new HashMap<>();
+        fieldIndexTypeMap.put("keyword", keywordMap);
+        Map<String, Object> dataFieldMap = (Map<String, Object>) source.get(fieldName);
+        dataFieldMap.put("fields", fieldIndexTypeMap);
+        Map<String, Object> dataProperties = new HashMap<>();
+        dataProperties.put(fieldName, dataFieldMap);
+        Map<String, Object> mapping = new HashMap<>();
+        mapping.put(Constants.PROPERTIES, dataProperties);
+        Map<String, Object> data = new HashMap<>();
+        data.put(Constants.DATA,mapping);
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(Constants.PROPERTIES, data);
+
+        request.source(new Gson().toJson(properties), XContentType.JSON);
+
+        try {
+            AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
+            boolean isIndicesUpdated = updateIndices(client, index);
+            return response.isAcknowledged() && isIndicesUpdated;
+
+        } catch (Exception e) {
+            log.error(String.format("Could not update mapping of index: %s. | Error: %s", index, e));
+            return false;
+        }
+    }
+
+    private boolean updateIndices(RestHighLevelClient client, String index) throws IOException {
+        UpdateByQueryRequest request = new UpdateByQueryRequest(index);
+        request.setConflicts("proceed");
+        BulkByScrollResponse response = client.updateByQuery(request, RequestOptions.DEFAULT);
+        if(!response.getBulkFailures().isEmpty()) {
+        	log.error(String.format("Could not update index: %s.",index));
+        	return false;
+        }
+		return true;
+    }
+
+    /**
+     * Create a new type in Elasticsearch
+     *
+     * @param client  Elasticsearch client
+     * @param index   Index name
+     * @param type    Type name
+     * @param mapping Mapping if any, null if no specific mapping
+     * @param merge   Try to merge mapping if type already exists
+     * @throws IOException if cannot create index mapping with input json
+     */
+    private void createMappingWithJson(RestHighLevelClient client, String index, String type, String mapping, boolean merge)
+            throws IOException {
+
+        boolean mappingExist = isTypeExist(client, index, type);
+        if (merge || !mappingExist) {
+            createTypeWithMappingInElasticsearch(client, index, type, mapping);
+        }
+    }
+
+    /**
+     * Check if a type already exists
+     *
+     * @param client Elasticsearch client
+     * @param index  Index name
+     * @param type   Type name
+     * @return true if type already exists
+     * @throws IOException in case Elasticsearch responded with a status code that indicated an error
+     */
+    public boolean isTypeExist(RestHighLevelClient client, String index, String type) throws IOException {
+
+        Request request = new Request("HEAD", "/" + index + "/_mapping/" + type);
+        Response response = client.getLowLevelClient().performRequest(request);
+        return response.getStatusLine().getStatusCode() == 200;
+    }
+
+    /**
+     * Create a new type in Elasticsearch
+     *
+     * @param client  Elasticsearch client
+     * @param index   Index name
+     * @param type    Type name
+     * @param mapping Mapping if any, null if no specific mapping
+     * @throws IOException if mapping cannot be created
+     */
+    private Boolean createTypeWithMappingInElasticsearch(RestHighLevelClient client, String index, String type, String mapping) throws IOException {
+
+        Preconditions.checkNotNull(client, "client cannot be null");
+        Preconditions.checkNotNull(index, "index cannot be null");
+        Preconditions.checkNotNull(type, "type cannot be null");
+
+        try {
+            if (mapping != null) {
+                PutMappingRequest request = new PutMappingRequest(index);
+                request.source(mapping, XContentType.JSON);
+                request.setTimeout(REQUEST_TIMEOUT);
+                AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
+                return response.isAcknowledged();
+            }
+        } catch (ElasticsearchException e) {
+            throw new AppException(
+                    e.status().getStatus(),
+                    e.getMessage(),
+                    String.format("Could not create type mapping %s/%s.", index, type),
+                    String.format("Failed creating mapping: %s", mapping),
+                    e);
+        }
+        return false;
+    }
 }
\ No newline at end of file
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java
index 6bec8964f..63ea7062d 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/IndexerServiceImpl.java
@@ -1,578 +1,578 @@
-// 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.service;
-
-import com.google.common.base.Strings;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import org.apache.http.HttpStatus;
-import org.elasticsearch.ElasticsearchStatusException;
-import org.elasticsearch.action.DocWriteRequest;
-import org.elasticsearch.action.bulk.BulkItemResponse;
-import org.elasticsearch.action.bulk.BulkRequest;
-import org.elasticsearch.action.bulk.BulkResponse;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.update.UpdateRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.common.xcontent.XContentType;
-import org.elasticsearch.rest.RestStatus;
-import org.opengroup.osdu.core.common.Constants;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.entitlements.Acl;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.http.RequestStatus;
-import org.opengroup.osdu.core.common.model.indexer.*;
-import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
-import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
-import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
-import org.opengroup.osdu.core.common.search.ElasticIndexNameResolver;
-import org.opengroup.osdu.indexer.logging.AuditLogger;
-import org.opengroup.osdu.indexer.provider.interfaces.IPublisher;
-import org.opengroup.osdu.indexer.util.ElasticClientHandler;
-import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Inject;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-@Service
-@Primary
-public class IndexerServiceImpl implements IndexerService {
-
-    private static final TimeValue BULK_REQUEST_TIMEOUT = TimeValue.timeValueMinutes(1);
-
-    private static final List<RestStatus> RETRY_ELASTIC_EXCEPTION = new ArrayList<>(Arrays.asList(RestStatus.TOO_MANY_REQUESTS, RestStatus.BAD_GATEWAY, RestStatus.SERVICE_UNAVAILABLE));
-
-    private final Gson gson = new GsonBuilder().serializeNulls().create();
-
-    @Inject
-    private JaxRsDpsLog jaxRsDpsLog;
-    @Inject
-    private AuditLogger auditLogger;
-    @Inject
-    private StorageService storageService;
-    @Inject
-    private IndexSchemaService schemaService;
-    @Inject
-    private IndicesService indicesService;
-    @Inject
-    private IMappingService mappingService;
-    @Inject
-    private IPublisher progressPublisher;
-    @Inject
-    private ElasticClientHandler elasticClientHandler;
-    @Inject
-    private IndexerQueueTaskBuilder indexerQueueTaskBuilder;
-    @Inject
-    private ElasticIndexNameResolver elasticIndexNameResolver;
-    @Inject
-    private StorageIndexerPayloadMapper storageIndexerPayloadMapper;
-    @Inject
-    private IRequestInfo requestInfo;
-    @Inject
-    private JobStatus jobStatus;
-
-    private DpsHeaders headers;
-
-    @Override
-    public JobStatus processRecordChangedMessages(RecordChangedMessages message, List<RecordInfo> recordInfos) throws Exception {
-
-        // this should not happen
-        if (recordInfos.size() == 0) return null;
-
-        String errorMessage = "";
-        List<String> retryRecordIds = new LinkedList<>();
-
-        // get auth header with service account Authorization
-        this.headers = this.requestInfo.getHeadersWithDwdAuthZ();
-
-        // initialize status for all messages.
-        this.jobStatus.initialize(recordInfos);
-
-        try {
-            auditLogger.indexStarted(recordInfos.stream()
-                    .map(RecordInfo::getKind)
-                    .collect(Collectors.toList()));
-
-            // get upsert records
-            Map<String, Map<String, OperationType>> upsertRecordMap = RecordInfo.getUpsertRecordIds(recordInfos);
-            if (upsertRecordMap != null && !upsertRecordMap.isEmpty()) {
-                List<String> upsertFailureRecordIds = processUpsertRecords(upsertRecordMap);
-                retryRecordIds.addAll(upsertFailureRecordIds);
-            }
-
-            // get delete records
-            Map<String, List<String>> deleteRecordMap = RecordInfo.getDeleteRecordIds(recordInfos);
-            if (deleteRecordMap != null && !deleteRecordMap.isEmpty()) {
-                List<String> deleteFailureRecordIds = processDeleteRecords(deleteRecordMap);
-                retryRecordIds.addAll(deleteFailureRecordIds);
-            }
-
-            // process legacy storage schema change messages
-            Map<String, OperationType> schemaMsgs = RecordInfo.getSchemaMsgs(recordInfos);
-            if (schemaMsgs != null && !schemaMsgs.isEmpty()) {
-                this.schemaService.processSchemaMessages(schemaMsgs);
-            }
-
-            // process failed records
-            if (retryRecordIds.size() > 0) {
-                retryAndEnqueueFailedRecords(recordInfos, retryRecordIds, message);
-            }
-        } catch (IOException e) {
-            errorMessage = e.getMessage();
-            throw new AppException(HttpStatus.SC_GATEWAY_TIMEOUT, "Internal communication failure", errorMessage, e);
-        } catch (AppException e) {
-            errorMessage = e.getMessage();
-            throw e;
-        } catch (Exception e) {
-            errorMessage = "error indexing records";
-            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error", "An unknown error has occurred.", e);
-        } finally {
-            this.jobStatus.finalizeRecordStatus(errorMessage);
-            this.updateAuditLog();
-            this.progressPublisher.publishStatusChangedTagsToTopic(this.headers, this.jobStatus);
-        }
-
-        return jobStatus;
-    }
-
-    @Override
-    public void processSchemaMessages(List<RecordInfo> recordInfos) throws IOException {
-        Map<String, OperationType> schemaMsgs = RecordInfo.getSchemaMsgs(recordInfos);
-        if (schemaMsgs != null && !schemaMsgs.isEmpty()) {
-            try (RestHighLevelClient restClient = elasticClientHandler.createRestClient()) {
-                schemaMsgs.entrySet().forEach(msg -> {
-                    try {
-                        processSchemaEvents(restClient, msg);
-                    } catch (IOException | ElasticsearchStatusException e) {
-                        throw new AppException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR.value(), "unable to process schema delete", e.getMessage());
-                    }
-                });
-            }
-        }
-    }
-
-    private void processSchemaEvents(RestHighLevelClient restClient,
-                                     Map.Entry<String, OperationType> msg) throws IOException, ElasticsearchStatusException {
-        String kind = msg.getKey();
-        String index = elasticIndexNameResolver.getIndexNameFromKind(kind);
-
-        boolean indexExist = indicesService.isIndexExist(restClient, index);
-        if (indexExist && msg.getValue() == OperationType.purge_schema) {
-            indicesService.deleteIndex(restClient, index);
-        }
-    }
-
-    private List<String> processUpsertRecords(Map<String, Map<String, OperationType>> upsertRecordMap) throws Exception {
-        // get schema for kind
-        Map<String, IndexSchema> schemas = this.getSchema(upsertRecordMap);
-
-        if (schemas.isEmpty()) return new LinkedList<>();
-
-        // get recordIds with valid upsert index-status
-        List<String> recordIds = this.jobStatus.getIdsByValidUpsertIndexingStatus();
-
-        if (recordIds.isEmpty()) return new LinkedList<>();
-
-        // get records via storage api
-        Records storageRecords = this.storageService.getStorageRecords(recordIds);
-        List<String> failedOrRetryRecordIds = new LinkedList<>(storageRecords.getMissingRetryRecords());
-
-        // map storage records to indexer payload
-        RecordIndexerPayload recordIndexerPayload = this.getIndexerPayload(upsertRecordMap, schemas, storageRecords);
-
-        jaxRsDpsLog.info(String.format("records change messages received : %s | valid storage bulk records: %s | valid index payload: %s", recordIds.size(), storageRecords.getRecords().size(), recordIndexerPayload.getRecords().size()));
-
-        // index records
-        failedOrRetryRecordIds.addAll(processElasticMappingAndUpsertRecords(recordIndexerPayload));
-
-        return failedOrRetryRecordIds;
-    }
-
-    private Map<String, IndexSchema> getSchema(Map<String, Map<String, OperationType>> upsertRecordMap) {
-
-        Map<String, IndexSchema> schemas = new HashMap<>();
-
-        try {
-            for (Map.Entry<String, Map<String, OperationType>> entry : upsertRecordMap.entrySet()) {
-
-                String kind = entry.getKey();
-                List<String> errors = new ArrayList<>();
-                IndexSchema schemaObj = this.schemaService.getIndexerInputSchema(kind, errors);
-                if (!errors.isEmpty()) {
-                    this.jobStatus.addOrUpdateRecordStatus(entry.getValue().keySet(), IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, String.join("|", errors), String.format("error  | kind: %s", kind));
-                } else if (schemaObj.isDataSchemaMissing()) {
-                    this.jobStatus.addOrUpdateRecordStatus(entry.getValue().keySet(), IndexingStatus.WARN, HttpStatus.SC_NOT_FOUND, "schema not found", String.format("schema not found | kind: %s", kind));
-                }
-
-                schemas.put(kind, schemaObj);
-            }
-        } catch (AppException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Get schema error", "An error has occurred while getting schema", e);
-        }
-
-        return schemas;
-    }
-
-    private RecordIndexerPayload getIndexerPayload(Map<String, Map<String, OperationType>> upsertRecordMap, Map<String, IndexSchema> kindSchemaMap, Records records) {
-        List<Records.Entity> storageValidRecords = records.getRecords();
-        List<RecordIndexerPayload.Record> indexerPayload = new ArrayList<>();
-        List<IndexSchema> schemas = new ArrayList<>();
-
-        for (Records.Entity storageRecord : storageValidRecords) {
-
-            Map<String, OperationType> idOperationMap = upsertRecordMap.get(storageRecord.getKind());
-
-            // skip if storage returned record with same id but different kind
-            if (idOperationMap == null) {
-                String message = String.format("storage service returned incorrect record | requested kind: %s | received kind: %s", this.jobStatus.getRecordKindById(storageRecord.getId()), storageRecord.getKind());
-                this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.SKIP, RequestStatus.STORAGE_CONFLICT, message, String.format("%s | record-id: %s", message, storageRecord.getId()));
-                continue;
-            }
-
-            IndexSchema schema = kindSchemaMap.get(storageRecord.getKind());
-            schemas.add(schema);
-
-            // skip indexing of records if data block is empty
-            RecordIndexerPayload.Record document = prepareIndexerPayload(schema, storageRecord, idOperationMap);
-            if (document != null) {
-                indexerPayload.add(document);
-            }
-        }
-
-        // this should only happen if storage service returned WRONG records with kind for all the records in the messages
-        if (indexerPayload.isEmpty()) {
-            throw new AppException(RequestStatus.STORAGE_CONFLICT, "Indexer error", "upsert record failed, storage service returned incorrect records");
-        }
-
-        return RecordIndexerPayload.builder().records(indexerPayload).schemas(schemas).build();
-    }
-
-    private RecordIndexerPayload.Record prepareIndexerPayload(IndexSchema schemaObj, Records.Entity storageRecord, Map<String, OperationType> idToOperationMap) {
-
-        RecordIndexerPayload.Record document = null;
-
-        try {
-            Map<String, Object> storageRecordData = storageRecord.getData();
-            document = new RecordIndexerPayload.Record();
-            if (storageRecordData == null || storageRecordData.isEmpty()) {
-                String message = "empty or null data block found in the storage record";
-                this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.WARN, HttpStatus.SC_NOT_FOUND, message, String.format("record-id: %s | %s", storageRecord.getId(), message));
-            } else if (schemaObj.isDataSchemaMissing()) {
-                document.setSchemaMissing(true);
-            } else {
-                Map<String, Object> dataMap = this.storageIndexerPayloadMapper.mapDataPayload(schemaObj, storageRecordData, storageRecord.getId());
-                if (dataMap.isEmpty()) {
-                    document.setMappingMismatch(true);
-                    String message = String.format("complete schema mismatch: none of the data attribute can be mapped | data: %s", storageRecordData);
-                    this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.WARN, HttpStatus.SC_NOT_FOUND, message, String.format("record-id: %s | %s", storageRecord.getId(), message));
-                }
-                document.setData(dataMap);
-            }
-        } catch (AppException e) {
-            this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.FAIL, HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
-            jaxRsDpsLog.warning(String.format("record-id: %s | %s", storageRecord.getId(), e.getMessage()), e);
-        } catch (Exception e) {
-            this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.FAIL, HttpStatus.SC_INTERNAL_SERVER_ERROR, String.format("error parsing records against schema, error-message: %s", e.getMessage()));
-            jaxRsDpsLog.error(String.format("record-id: %s | error parsing records against schema, error-message: %s", storageRecord.getId(), e.getMessage()), e);
-        }
-
-        try {
-            // index individual parts of kind
-            String[] kindParts = storageRecord.getKind().split(":");
-            String authority = kindParts[0];
-            String source = kindParts[1];
-            String type = kindParts[2];
-            document.setKind(storageRecord.getKind());
-            document.setNamespace(authority + ":" + source);
-            document.setAuthority(authority);
-            document.setSource(source);
-            document.setType(type);
-            document.setId(storageRecord.getId());
-            document.setVersion(storageRecord.getVersion());
-            document.setAcl(storageRecord.getAcl());
-            document.setLegal(storageRecord.getLegal());
-            if (storageRecord.getTags() != null) {
-                document.setTags(storageRecord.getTags());
-            }
-            document.setCreateUser(storageRecord.getCreateUser());
-            document.setCreateTime(storageRecord.getCreateTime());
-            if (!Strings.isNullOrEmpty(storageRecord.getModifyUser())) {
-                document.setModifyUser(storageRecord.getModifyUser());
-            }
-            if (!Strings.isNullOrEmpty(storageRecord.getModifyTime())) {
-                document.setModifyTime(storageRecord.getModifyTime());
-            }
-            RecordStatus recordStatus = this.jobStatus.getJobStatusByRecordId(storageRecord.getId());
-            if (recordStatus.getIndexProgress().getStatusCode() == 0) {
-                recordStatus.getIndexProgress().setStatusCode(HttpStatus.SC_OK);
-            }
-            document.setIndexProgress(recordStatus.getIndexProgress());
-            if (storageRecord.getAncestry() != null) document.setAncestry(storageRecord.getAncestry());
-            document.setOperationType(idToOperationMap.get(storageRecord.getId()));
-        } catch (Exception e) {
-            this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.FAIL, HttpStatus.SC_INTERNAL_SERVER_ERROR, String.format("error parsing meta data, error-message: %s", e.getMessage()));
-            jaxRsDpsLog.error(String.format("record-id: %s | error parsing meta data, error-message: %s", storageRecord.getId(), e.getMessage()), e);
-        }
-        return document;
-    }
-
-    private List<String> processElasticMappingAndUpsertRecords(RecordIndexerPayload recordIndexerPayload) throws Exception {
-
-        try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) {
-            List<IndexSchema> schemas = recordIndexerPayload.getSchemas();
-            if (schemas == null || schemas.isEmpty()) {
-                return new LinkedList<>();
-            }
-
-            // process the schema
-            this.cacheOrCreateElasticMapping(schemas, restClient);
-
-            // process the records
-            return this.upsertRecords(recordIndexerPayload.getRecords(), restClient);
-        }
-    }
-
-    private void cacheOrCreateElasticMapping(List<IndexSchema> schemas, RestHighLevelClient restClient) throws Exception {
-
-        for (IndexSchema schema : schemas) {
-            String index = this.elasticIndexNameResolver.getIndexNameFromKind(schema.getKind());
-
-            // check if index exist and sync meta attribute schema if required
-            if (this.indicesService.isIndexReady(restClient, index)) {
-                this.mappingService.syncIndexMappingIfRequired(restClient, schema);
-                continue;
-            }
-
-            // create index
-            Map<String, Object> mapping = this.mappingService.getIndexMappingFromRecordSchema(schema);
-            if (!this.indicesService.createIndex(restClient, index, null, schema.getType(), mapping)) {
-                throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error creating index.", String.format("Failed to get confirmation from elastic server for index: %s", index));
-            }
-        }
-    }
-
-    private List<String> upsertRecords(List<RecordIndexerPayload.Record> records, RestHighLevelClient restClient) throws AppException {
-        if (records == null || records.isEmpty()) return new LinkedList<>();
-
-        BulkRequest bulkRequest = new BulkRequest();
-        bulkRequest.timeout(BULK_REQUEST_TIMEOUT);
-
-        for (RecordIndexerPayload.Record record : records) {
-            if ((record.getData() == null || record.getData().isEmpty()) && !record.skippedDataIndexing()) {
-                // it will come here when schema is missing
-                // TODO: rollback once we know what is causing the problem
-                jaxRsDpsLog.warning(String.format("data not found for record: %s", record));
-            }
-
-            OperationType operation = record.getOperationType();
-            Map<String, Object> sourceMap = getSourceMap(record);
-            String index = this.elasticIndexNameResolver.getIndexNameFromKind(record.getKind());
-
-            if (operation == OperationType.create) {
-                IndexRequest indexRequest = new IndexRequest(index).id(record.getId()).source(this.gson.toJson(sourceMap), XContentType.JSON);
-                bulkRequest.add(indexRequest);
-            } else if (operation == OperationType.update) {
-                UpdateRequest updateRequest = new UpdateRequest(index, "_doc", record.getId()).doc(this.gson.toJson(sourceMap), XContentType.JSON).docAsUpsert(true);
-                bulkRequest.add(updateRequest);
-            }
-        }
-
-        return processBulkRequest(restClient, bulkRequest);
-    }
-
-    private List<String> processDeleteRecords(Map<String, List<String>> deleteRecordMap) throws Exception {
-        BulkRequest bulkRequest = new BulkRequest();
-        bulkRequest.timeout(BULK_REQUEST_TIMEOUT);
-
-        for (Map.Entry<String, List<String>> record : deleteRecordMap.entrySet()) {
-
-            String index = this.elasticIndexNameResolver.getIndexNameFromKind(record.getKey());
-
-            for (String id : record.getValue()) {
-                DeleteRequest deleteRequest = new DeleteRequest(index, id);
-                bulkRequest.add(deleteRequest);
-            }
-        }
-
-        try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) {
-            return processBulkRequest(restClient, bulkRequest);
-        }
-    }
-
-    private List<String> processBulkRequest(RestHighLevelClient restClient, BulkRequest bulkRequest) throws AppException {
-
-        List<String> failureRecordIds = new LinkedList<>();
-        if (bulkRequest.numberOfActions() == 0) return failureRecordIds;
-        int failedRequestStatus = 500;
-        Exception failedRequestCause = null;
-
-        try {
-            long startTime = System.currentTimeMillis();
-            BulkResponse bulkResponse = restClient.bulk(bulkRequest, RequestOptions.DEFAULT);
-            long stopTime = System.currentTimeMillis();
-
-            // log failed bulk requests
-            ArrayList<String> bulkFailures = new ArrayList<>();
-            int succeededResponses = 0;
-            int failedResponses = 0;
-
-            for (BulkItemResponse bulkItemResponse : bulkResponse.getItems()) {
-                if (bulkItemResponse.isFailed()) {
-                    BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
-                    bulkFailures.add(String.format("elasticsearch bulk service status: %s | id: %s | message: %s", failure.getStatus(), failure.getId(), failure.getMessage()));
-                    this.jobStatus.addOrUpdateRecordStatus(bulkItemResponse.getId(), IndexingStatus.FAIL, failure.getStatus().getStatus(), bulkItemResponse.getFailureMessage());
-                    if (canIndexerRetry(bulkItemResponse)) {
-                        failureRecordIds.add(bulkItemResponse.getId());
-
-                        if (failedRequestCause == null) {
-                            failedRequestCause = failure.getCause();
-                            failedRequestStatus = failure.getStatus().getStatus();
-                        }
-                    }
-
-                    failedResponses++;
-                } else {
-                    succeededResponses++;
-                    this.jobStatus.addOrUpdateRecordStatus(bulkItemResponse.getId(), IndexingStatus.SUCCESS, HttpStatus.SC_OK, "Indexed Successfully");
-                }
-            }
-            if (!bulkFailures.isEmpty()) this.jaxRsDpsLog.warning(bulkFailures);
-
-            jaxRsDpsLog.info(String.format("records in elasticsearch service bulk request: %s | successful: %s | failed: %s | time taken for bulk request: %d milliseconds", bulkRequest.numberOfActions(), succeededResponses, failedResponses, stopTime-startTime));
-
-            // retry entire message if all records are failing
-            if (bulkRequest.numberOfActions() == failureRecordIds.size()) throw new AppException(failedRequestStatus,  "Elastic error", failedRequestCause.getMessage(), failedRequestCause);
-        } catch (IOException e) {
-            // throw explicit 504 for IOException
-            throw new AppException(HttpStatus.SC_GATEWAY_TIMEOUT, "Elastic error", "Request cannot be completed in specified time.", e);
-        } catch (ElasticsearchStatusException e) {
-            throw new AppException(e.status().getStatus(), "Elastic error", e.getMessage(), e);
-        } catch (Exception e) {
-            if (e instanceof AppException) {
-                throw e;
-            }
-            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error indexing records.", e);
-        }
-        return failureRecordIds;
-    }
-
-    private Map<String, Object> getSourceMap(RecordIndexerPayload.Record record) {
-
-        Map<String, Object> indexerPayload = new HashMap<>();
-
-        // get the key and get the corresponding object from the individualRecord object
-        if (record.getData() != null) {
-            Map<String, Object> data = new HashMap<>();
-            for (Map.Entry<String, Object> entry : record.getData().entrySet()) {
-                data.put(entry.getKey(), entry.getValue());
-            }
-            indexerPayload.put(Constants.DATA, data);
-        }
-
-        indexerPayload.put(RecordMetaAttribute.ID.getValue(), record.getId());
-        indexerPayload.put(RecordMetaAttribute.KIND.getValue(), record.getKind());
-        indexerPayload.put(RecordMetaAttribute.AUTHORITY.getValue(), record.getAuthority());
-        indexerPayload.put(RecordMetaAttribute.SOURCE.getValue(), record.getSource());
-        indexerPayload.put(RecordMetaAttribute.NAMESPACE.getValue(), record.getNamespace());
-        indexerPayload.put(RecordMetaAttribute.TYPE.getValue(), record.getType());
-        indexerPayload.put(RecordMetaAttribute.VERSION.getValue(), record.getVersion());
-        indexerPayload.put(RecordMetaAttribute.ACL.getValue(), record.getAcl());
-        indexerPayload.put(RecordMetaAttribute.TAGS.getValue(), record.getTags());
-        indexerPayload.put(RecordMetaAttribute.X_ACL.getValue(), Acl.flattenAcl(record.getAcl()));
-        indexerPayload.put(RecordMetaAttribute.LEGAL.getValue(), record.getLegal());
-        indexerPayload.put(RecordMetaAttribute.INDEX_STATUS.getValue(), record.getIndexProgress());
-        if (record.getAncestry() != null) {
-            indexerPayload.put(RecordMetaAttribute.ANCESTRY.getValue(), record.getAncestry());
-        }
-        indexerPayload.put(RecordMetaAttribute.CREATE_USER.getValue(), record.getCreateUser());
-        indexerPayload.put(RecordMetaAttribute.CREATE_TIME.getValue(), record.getCreateTime());
-        if (!Strings.isNullOrEmpty(record.getModifyUser())) {
-            indexerPayload.put(RecordMetaAttribute.MODIFY_USER.getValue(), record.getModifyUser());
-        }
-        if (!Strings.isNullOrEmpty(record.getModifyTime())) {
-            indexerPayload.put(RecordMetaAttribute.MODIFY_TIME.getValue(), record.getModifyTime());
-        }
-        return indexerPayload;
-    }
-
-    private boolean canIndexerRetry(BulkItemResponse bulkItemResponse) {
-        if (RETRY_ELASTIC_EXCEPTION.contains(bulkItemResponse.status())) return true;
-
-        if ((bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE || bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE)
-                && bulkItemResponse.status() == RestStatus.NOT_FOUND) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private void retryAndEnqueueFailedRecords(List<RecordInfo> recordInfos, List<String> failuresRecordIds, RecordChangedMessages message) throws IOException {
-
-        jaxRsDpsLog.info(String.format("queuing bulk failed records back to task-queue for retry | count: %s | records: %s", failuresRecordIds.size(), failuresRecordIds));
-        List<RecordInfo> retryRecordInfos = new LinkedList<>();
-        for (String recordId : failuresRecordIds) {
-            for (RecordInfo origMessage : recordInfos) {
-                if (origMessage.getId().equalsIgnoreCase(recordId)) {
-                    retryRecordInfos.add(origMessage);
-                }
-            }
-        }
-
-        RecordChangedMessages newMessage = RecordChangedMessages.builder()
-                .messageId(message.getMessageId())
-                .publishTime(message.getPublishTime())
-                .data(this.gson.toJson(retryRecordInfos))
-                .attributes(message.getAttributes()).build();
-
-        String payLoad = this.gson.toJson(newMessage);
-        this.indexerQueueTaskBuilder.createWorkerTask(payLoad, this.headers);
-    }
-
-    private void updateAuditLog() {
-        logAuditEvents(OperationType.create, this.auditLogger::indexCreateRecordSuccess, this.auditLogger::indexCreateRecordFail);
-        logAuditEvents(OperationType.update, this.auditLogger::indexUpdateRecordSuccess, this.auditLogger::indexUpdateRecordFail);
-        logAuditEvents(OperationType.purge, this.auditLogger::indexPurgeRecordSuccess, this.auditLogger::indexPurgeRecordFail);
-        logAuditEvents(OperationType.delete, this.auditLogger::indexDeleteRecordSuccess, this.auditLogger::indexDeleteRecordFail);
-    }
-
-    private void logAuditEvents(OperationType operationType, Consumer<List<String>> successEvent, Consumer<List<String>> failedEvent) {
-        List<RecordStatus> succeededRecords = this.jobStatus.getRecordStatuses(IndexingStatus.SUCCESS, operationType);
-        if (!succeededRecords.isEmpty()) {
-            successEvent.accept(succeededRecords.stream().map(RecordStatus::succeededAuditLogMessage).collect(Collectors.toList()));
-        }
-        List<RecordStatus> skippedRecords = this.jobStatus.getRecordStatuses(IndexingStatus.SKIP, operationType);
-        List<RecordStatus> failedRecords = this.jobStatus.getRecordStatuses(IndexingStatus.FAIL, operationType);
-        failedRecords.addAll(skippedRecords);
-        if (!failedRecords.isEmpty()) {
-            failedEvent.accept(failedRecords.stream().map(RecordStatus::failedAuditLogMessage).collect(Collectors.toList()));
-        }
-    }
-}
+// 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.service;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.http.HttpStatus;
+import org.elasticsearch.ElasticsearchStatusException;
+import org.elasticsearch.action.DocWriteRequest;
+import org.elasticsearch.action.bulk.BulkItemResponse;
+import org.elasticsearch.action.bulk.BulkRequest;
+import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.delete.DeleteRequest;
+import org.elasticsearch.action.index.IndexRequest;
+import org.elasticsearch.action.update.UpdateRequest;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.rest.RestStatus;
+import org.opengroup.osdu.core.common.Constants;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.entitlements.Acl;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.http.RequestStatus;
+import org.opengroup.osdu.core.common.model.indexer.*;
+import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
+import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
+import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
+import org.opengroup.osdu.core.common.search.ElasticIndexNameResolver;
+import org.opengroup.osdu.indexer.logging.AuditLogger;
+import org.opengroup.osdu.indexer.provider.interfaces.IPublisher;
+import org.opengroup.osdu.indexer.util.ElasticClientHandler;
+import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+@Service
+@Primary
+public class IndexerServiceImpl implements IndexerService {
+
+    private static final TimeValue BULK_REQUEST_TIMEOUT = TimeValue.timeValueMinutes(1);
+
+    private static final List<RestStatus> RETRY_ELASTIC_EXCEPTION = new ArrayList<>(Arrays.asList(RestStatus.TOO_MANY_REQUESTS, RestStatus.BAD_GATEWAY, RestStatus.SERVICE_UNAVAILABLE));
+
+    private final Gson gson = new GsonBuilder().serializeNulls().create();
+
+    @Inject
+    private JaxRsDpsLog jaxRsDpsLog;
+    @Inject
+    private AuditLogger auditLogger;
+    @Inject
+    private StorageService storageService;
+    @Inject
+    private IndexSchemaService schemaService;
+    @Inject
+    private IndicesService indicesService;
+    @Inject
+    private IMappingService mappingService;
+    @Inject
+    private IPublisher progressPublisher;
+    @Inject
+    private ElasticClientHandler elasticClientHandler;
+    @Inject
+    private IndexerQueueTaskBuilder indexerQueueTaskBuilder;
+    @Inject
+    private ElasticIndexNameResolver elasticIndexNameResolver;
+    @Inject
+    private StorageIndexerPayloadMapper storageIndexerPayloadMapper;
+    @Inject
+    private IRequestInfo requestInfo;
+    @Inject
+    private JobStatus jobStatus;
+
+    private DpsHeaders headers;
+
+    @Override
+    public JobStatus processRecordChangedMessages(RecordChangedMessages message, List<RecordInfo> recordInfos) throws Exception {
+
+        // this should not happen
+        if (recordInfos.size() == 0) return null;
+
+        String errorMessage = "";
+        List<String> retryRecordIds = new LinkedList<>();
+
+        // get auth header with service account Authorization
+        this.headers = this.requestInfo.getHeadersWithDwdAuthZ();
+
+        // initialize status for all messages.
+        this.jobStatus.initialize(recordInfos);
+
+        try {
+            auditLogger.indexStarted(recordInfos.stream()
+                    .map(RecordInfo::getKind)
+                    .collect(Collectors.toList()));
+
+            // get upsert records
+            Map<String, Map<String, OperationType>> upsertRecordMap = RecordInfo.getUpsertRecordIds(recordInfos);
+            if (upsertRecordMap != null && !upsertRecordMap.isEmpty()) {
+                List<String> upsertFailureRecordIds = processUpsertRecords(upsertRecordMap);
+                retryRecordIds.addAll(upsertFailureRecordIds);
+            }
+
+            // get delete records
+            Map<String, List<String>> deleteRecordMap = RecordInfo.getDeleteRecordIds(recordInfos);
+            if (deleteRecordMap != null && !deleteRecordMap.isEmpty()) {
+                List<String> deleteFailureRecordIds = processDeleteRecords(deleteRecordMap);
+                retryRecordIds.addAll(deleteFailureRecordIds);
+            }
+
+            // process legacy storage schema change messages
+            Map<String, OperationType> schemaMsgs = RecordInfo.getSchemaMsgs(recordInfos);
+            if (schemaMsgs != null && !schemaMsgs.isEmpty()) {
+                this.schemaService.processSchemaMessages(schemaMsgs);
+            }
+
+            // process failed records
+            if (retryRecordIds.size() > 0) {
+                retryAndEnqueueFailedRecords(recordInfos, retryRecordIds, message);
+            }
+        } catch (IOException e) {
+            errorMessage = e.getMessage();
+            throw new AppException(HttpStatus.SC_GATEWAY_TIMEOUT, "Internal communication failure", errorMessage, e);
+        } catch (AppException e) {
+            errorMessage = e.getMessage();
+            throw e;
+        } catch (Exception e) {
+            errorMessage = "error indexing records";
+            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error", "An unknown error has occurred.", e);
+        } finally {
+            this.jobStatus.finalizeRecordStatus(errorMessage);
+            this.updateAuditLog();
+            this.progressPublisher.publishStatusChangedTagsToTopic(this.headers, this.jobStatus);
+        }
+
+        return jobStatus;
+    }
+
+    @Override
+    public void processSchemaMessages(List<RecordInfo> recordInfos) throws IOException {
+        Map<String, OperationType> schemaMsgs = RecordInfo.getSchemaMsgs(recordInfos);
+        if (schemaMsgs != null && !schemaMsgs.isEmpty()) {
+            try (RestHighLevelClient restClient = elasticClientHandler.createRestClient()) {
+                schemaMsgs.entrySet().forEach(msg -> {
+                    try {
+                        processSchemaEvents(restClient, msg);
+                    } catch (IOException | ElasticsearchStatusException e) {
+                        throw new AppException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR.value(), "unable to process schema delete", e.getMessage());
+                    }
+                });
+            }
+        }
+    }
+
+    private void processSchemaEvents(RestHighLevelClient restClient,
+                                     Map.Entry<String, OperationType> msg) throws IOException, ElasticsearchStatusException {
+        String kind = msg.getKey();
+        String index = elasticIndexNameResolver.getIndexNameFromKind(kind);
+
+        boolean indexExist = indicesService.isIndexExist(restClient, index);
+        if (indexExist && msg.getValue() == OperationType.purge_schema) {
+            indicesService.deleteIndex(restClient, index);
+        }
+    }
+
+    private List<String> processUpsertRecords(Map<String, Map<String, OperationType>> upsertRecordMap) throws Exception {
+        // get schema for kind
+        Map<String, IndexSchema> schemas = this.getSchema(upsertRecordMap);
+
+        if (schemas.isEmpty()) return new LinkedList<>();
+
+        // get recordIds with valid upsert index-status
+        List<String> recordIds = this.jobStatus.getIdsByValidUpsertIndexingStatus();
+
+        if (recordIds.isEmpty()) return new LinkedList<>();
+
+        // get records via storage api
+        Records storageRecords = this.storageService.getStorageRecords(recordIds);
+        List<String> failedOrRetryRecordIds = new LinkedList<>(storageRecords.getMissingRetryRecords());
+
+        // map storage records to indexer payload
+        RecordIndexerPayload recordIndexerPayload = this.getIndexerPayload(upsertRecordMap, schemas, storageRecords);
+
+        jaxRsDpsLog.info(String.format("records change messages received : %s | valid storage bulk records: %s | valid index payload: %s", recordIds.size(), storageRecords.getRecords().size(), recordIndexerPayload.getRecords().size()));
+
+        // index records
+        failedOrRetryRecordIds.addAll(processElasticMappingAndUpsertRecords(recordIndexerPayload));
+
+        return failedOrRetryRecordIds;
+    }
+
+    private Map<String, IndexSchema> getSchema(Map<String, Map<String, OperationType>> upsertRecordMap) {
+
+        Map<String, IndexSchema> schemas = new HashMap<>();
+
+        try {
+            for (Map.Entry<String, Map<String, OperationType>> entry : upsertRecordMap.entrySet()) {
+
+                String kind = entry.getKey();
+                List<String> errors = new ArrayList<>();
+                IndexSchema schemaObj = this.schemaService.getIndexerInputSchema(kind, errors);
+                if (!errors.isEmpty()) {
+                    this.jobStatus.addOrUpdateRecordStatus(entry.getValue().keySet(), IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, String.join("|", errors), String.format("error  | kind: %s", kind));
+                } else if (schemaObj.isDataSchemaMissing()) {
+                    this.jobStatus.addOrUpdateRecordStatus(entry.getValue().keySet(), IndexingStatus.WARN, HttpStatus.SC_NOT_FOUND, "schema not found", String.format("schema not found | kind: %s", kind));
+                }
+
+                schemas.put(kind, schemaObj);
+            }
+        } catch (AppException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Get schema error", "An error has occurred while getting schema", e);
+        }
+
+        return schemas;
+    }
+
+    private RecordIndexerPayload getIndexerPayload(Map<String, Map<String, OperationType>> upsertRecordMap, Map<String, IndexSchema> kindSchemaMap, Records records) {
+        List<Records.Entity> storageValidRecords = records.getRecords();
+        List<RecordIndexerPayload.Record> indexerPayload = new ArrayList<>();
+        List<IndexSchema> schemas = new ArrayList<>();
+
+        for (Records.Entity storageRecord : storageValidRecords) {
+
+            Map<String, OperationType> idOperationMap = upsertRecordMap.get(storageRecord.getKind());
+
+            // skip if storage returned record with same id but different kind
+            if (idOperationMap == null) {
+                String message = String.format("storage service returned incorrect record | requested kind: %s | received kind: %s", this.jobStatus.getRecordKindById(storageRecord.getId()), storageRecord.getKind());
+                this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.SKIP, RequestStatus.STORAGE_CONFLICT, message, String.format("%s | record-id: %s", message, storageRecord.getId()));
+                continue;
+            }
+
+            IndexSchema schema = kindSchemaMap.get(storageRecord.getKind());
+            schemas.add(schema);
+
+            // skip indexing of records if data block is empty
+            RecordIndexerPayload.Record document = prepareIndexerPayload(schema, storageRecord, idOperationMap);
+            if (document != null) {
+                indexerPayload.add(document);
+            }
+        }
+
+        // this should only happen if storage service returned WRONG records with kind for all the records in the messages
+        if (indexerPayload.isEmpty()) {
+            throw new AppException(RequestStatus.STORAGE_CONFLICT, "Indexer error", "upsert record failed, storage service returned incorrect records");
+        }
+
+        return RecordIndexerPayload.builder().records(indexerPayload).schemas(schemas).build();
+    }
+
+    private RecordIndexerPayload.Record prepareIndexerPayload(IndexSchema schemaObj, Records.Entity storageRecord, Map<String, OperationType> idToOperationMap) {
+
+        RecordIndexerPayload.Record document = null;
+
+        try {
+            Map<String, Object> storageRecordData = storageRecord.getData();
+            document = new RecordIndexerPayload.Record();
+            if (storageRecordData == null || storageRecordData.isEmpty()) {
+                String message = "empty or null data block found in the storage record";
+                this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.WARN, HttpStatus.SC_NOT_FOUND, message, String.format("record-id: %s | %s", storageRecord.getId(), message));
+            } else if (schemaObj.isDataSchemaMissing()) {
+                document.setSchemaMissing(true);
+            } else {
+                Map<String, Object> dataMap = this.storageIndexerPayloadMapper.mapDataPayload(schemaObj, storageRecordData, storageRecord.getId());
+                if (dataMap.isEmpty()) {
+                    document.setMappingMismatch(true);
+                    String message = String.format("complete schema mismatch: none of the data attribute can be mapped | data: %s", storageRecordData);
+                    this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.WARN, HttpStatus.SC_NOT_FOUND, message, String.format("record-id: %s | %s", storageRecord.getId(), message));
+                }
+                document.setData(dataMap);
+            }
+        } catch (AppException e) {
+            this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.FAIL, HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+            jaxRsDpsLog.warning(String.format("record-id: %s | %s", storageRecord.getId(), e.getMessage()), e);
+        } catch (Exception e) {
+            this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.FAIL, HttpStatus.SC_INTERNAL_SERVER_ERROR, String.format("error parsing records against schema, error-message: %s", e.getMessage()));
+            jaxRsDpsLog.error(String.format("record-id: %s | error parsing records against schema, error-message: %s", storageRecord.getId(), e.getMessage()), e);
+        }
+
+        try {
+            // index individual parts of kind
+            String[] kindParts = storageRecord.getKind().split(":");
+            String authority = kindParts[0];
+            String source = kindParts[1];
+            String type = kindParts[2];
+            document.setKind(storageRecord.getKind());
+            document.setNamespace(authority + ":" + source);
+            document.setAuthority(authority);
+            document.setSource(source);
+            document.setType(type);
+            document.setId(storageRecord.getId());
+            document.setVersion(storageRecord.getVersion());
+            document.setAcl(storageRecord.getAcl());
+            document.setLegal(storageRecord.getLegal());
+            if (storageRecord.getTags() != null) {
+                document.setTags(storageRecord.getTags());
+            }
+            document.setCreateUser(storageRecord.getCreateUser());
+            document.setCreateTime(storageRecord.getCreateTime());
+            if (!Strings.isNullOrEmpty(storageRecord.getModifyUser())) {
+                document.setModifyUser(storageRecord.getModifyUser());
+            }
+            if (!Strings.isNullOrEmpty(storageRecord.getModifyTime())) {
+                document.setModifyTime(storageRecord.getModifyTime());
+            }
+            RecordStatus recordStatus = this.jobStatus.getJobStatusByRecordId(storageRecord.getId());
+            if (recordStatus.getIndexProgress().getStatusCode() == 0) {
+                recordStatus.getIndexProgress().setStatusCode(HttpStatus.SC_OK);
+            }
+            document.setIndexProgress(recordStatus.getIndexProgress());
+            if (storageRecord.getAncestry() != null) document.setAncestry(storageRecord.getAncestry());
+            document.setOperationType(idToOperationMap.get(storageRecord.getId()));
+        } catch (Exception e) {
+            this.jobStatus.addOrUpdateRecordStatus(storageRecord.getId(), IndexingStatus.FAIL, HttpStatus.SC_INTERNAL_SERVER_ERROR, String.format("error parsing meta data, error-message: %s", e.getMessage()));
+            jaxRsDpsLog.error(String.format("record-id: %s | error parsing meta data, error-message: %s", storageRecord.getId(), e.getMessage()), e);
+        }
+        return document;
+    }
+
+    private List<String> processElasticMappingAndUpsertRecords(RecordIndexerPayload recordIndexerPayload) throws Exception {
+
+        try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) {
+            List<IndexSchema> schemas = recordIndexerPayload.getSchemas();
+            if (schemas == null || schemas.isEmpty()) {
+                return new LinkedList<>();
+            }
+
+            // process the schema
+            this.cacheOrCreateElasticMapping(schemas, restClient);
+
+            // process the records
+            return this.upsertRecords(recordIndexerPayload.getRecords(), restClient);
+        }
+    }
+
+    private void cacheOrCreateElasticMapping(List<IndexSchema> schemas, RestHighLevelClient restClient) throws Exception {
+
+        for (IndexSchema schema : schemas) {
+            String index = this.elasticIndexNameResolver.getIndexNameFromKind(schema.getKind());
+
+            // check if index exist and sync meta attribute schema if required
+            if (this.indicesService.isIndexReady(restClient, index)) {
+                this.mappingService.syncIndexMappingIfRequired(restClient, schema);
+                continue;
+            }
+
+            // create index
+            Map<String, Object> mapping = this.mappingService.getIndexMappingFromRecordSchema(schema);
+            if (!this.indicesService.createIndex(restClient, index, null, schema.getType(), mapping)) {
+                throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error creating index.", String.format("Failed to get confirmation from elastic server for index: %s", index));
+            }
+        }
+    }
+
+    private List<String> upsertRecords(List<RecordIndexerPayload.Record> records, RestHighLevelClient restClient) throws AppException {
+        if (records == null || records.isEmpty()) return new LinkedList<>();
+
+        BulkRequest bulkRequest = new BulkRequest();
+        bulkRequest.timeout(BULK_REQUEST_TIMEOUT);
+
+        for (RecordIndexerPayload.Record record : records) {
+            if ((record.getData() == null || record.getData().isEmpty()) && !record.skippedDataIndexing()) {
+                // it will come here when schema is missing
+                // TODO: rollback once we know what is causing the problem
+                jaxRsDpsLog.warning(String.format("data not found for record: %s", record));
+            }
+
+            OperationType operation = record.getOperationType();
+            Map<String, Object> sourceMap = getSourceMap(record);
+            String index = this.elasticIndexNameResolver.getIndexNameFromKind(record.getKind());
+
+            if (operation == OperationType.create) {
+                IndexRequest indexRequest = new IndexRequest(index).id(record.getId()).source(this.gson.toJson(sourceMap), XContentType.JSON);
+                bulkRequest.add(indexRequest);
+            } else if (operation == OperationType.update) {
+                UpdateRequest updateRequest = new UpdateRequest(index, "_doc", record.getId()).doc(this.gson.toJson(sourceMap), XContentType.JSON).docAsUpsert(true);
+                bulkRequest.add(updateRequest);
+            }
+        }
+
+        return processBulkRequest(restClient, bulkRequest);
+    }
+
+    private List<String> processDeleteRecords(Map<String, List<String>> deleteRecordMap) throws Exception {
+        BulkRequest bulkRequest = new BulkRequest();
+        bulkRequest.timeout(BULK_REQUEST_TIMEOUT);
+
+        for (Map.Entry<String, List<String>> record : deleteRecordMap.entrySet()) {
+
+            String index = this.elasticIndexNameResolver.getIndexNameFromKind(record.getKey());
+
+            for (String id : record.getValue()) {
+                DeleteRequest deleteRequest = new DeleteRequest(index, id);
+                bulkRequest.add(deleteRequest);
+            }
+        }
+
+        try (RestHighLevelClient restClient = this.elasticClientHandler.createRestClient()) {
+            return processBulkRequest(restClient, bulkRequest);
+        }
+    }
+
+    private List<String> processBulkRequest(RestHighLevelClient restClient, BulkRequest bulkRequest) throws AppException {
+
+        List<String> failureRecordIds = new LinkedList<>();
+        if (bulkRequest.numberOfActions() == 0) return failureRecordIds;
+        int failedRequestStatus = 500;
+        Exception failedRequestCause = null;
+
+        try {
+            long startTime = System.currentTimeMillis();
+            BulkResponse bulkResponse = restClient.bulk(bulkRequest, RequestOptions.DEFAULT);
+            long stopTime = System.currentTimeMillis();
+
+            // log failed bulk requests
+            ArrayList<String> bulkFailures = new ArrayList<>();
+            int succeededResponses = 0;
+            int failedResponses = 0;
+
+            for (BulkItemResponse bulkItemResponse : bulkResponse.getItems()) {
+                if (bulkItemResponse.isFailed()) {
+                    BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
+                    bulkFailures.add(String.format("elasticsearch bulk service status: %s | id: %s | message: %s", failure.getStatus(), failure.getId(), failure.getMessage()));
+                    this.jobStatus.addOrUpdateRecordStatus(bulkItemResponse.getId(), IndexingStatus.FAIL, failure.getStatus().getStatus(), bulkItemResponse.getFailureMessage());
+                    if (canIndexerRetry(bulkItemResponse)) {
+                        failureRecordIds.add(bulkItemResponse.getId());
+
+                        if (failedRequestCause == null) {
+                            failedRequestCause = failure.getCause();
+                            failedRequestStatus = failure.getStatus().getStatus();
+                        }
+                    }
+
+                    failedResponses++;
+                } else {
+                    succeededResponses++;
+                    this.jobStatus.addOrUpdateRecordStatus(bulkItemResponse.getId(), IndexingStatus.SUCCESS, HttpStatus.SC_OK, "Indexed Successfully");
+                }
+            }
+            if (!bulkFailures.isEmpty()) this.jaxRsDpsLog.warning(bulkFailures);
+
+            jaxRsDpsLog.info(String.format("records in elasticsearch service bulk request: %s | successful: %s | failed: %s | time taken for bulk request: %d milliseconds", bulkRequest.numberOfActions(), succeededResponses, failedResponses, stopTime-startTime));
+
+            // retry entire message if all records are failing
+            if (bulkRequest.numberOfActions() == failureRecordIds.size()) throw new AppException(failedRequestStatus,  "Elastic error", failedRequestCause.getMessage(), failedRequestCause);
+        } catch (IOException e) {
+            // throw explicit 504 for IOException
+            throw new AppException(HttpStatus.SC_GATEWAY_TIMEOUT, "Elastic error", "Request cannot be completed in specified time.", e);
+        } catch (ElasticsearchStatusException e) {
+            throw new AppException(e.status().getStatus(), "Elastic error", e.getMessage(), e);
+        } catch (Exception e) {
+            if (e instanceof AppException) {
+                throw e;
+            }
+            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Elastic error", "Error indexing records.", e);
+        }
+        return failureRecordIds;
+    }
+
+    private Map<String, Object> getSourceMap(RecordIndexerPayload.Record record) {
+
+        Map<String, Object> indexerPayload = new HashMap<>();
+
+        // get the key and get the corresponding object from the individualRecord object
+        if (record.getData() != null) {
+            Map<String, Object> data = new HashMap<>();
+            for (Map.Entry<String, Object> entry : record.getData().entrySet()) {
+                data.put(entry.getKey(), entry.getValue());
+            }
+            indexerPayload.put(Constants.DATA, data);
+        }
+
+        indexerPayload.put(RecordMetaAttribute.ID.getValue(), record.getId());
+        indexerPayload.put(RecordMetaAttribute.KIND.getValue(), record.getKind());
+        indexerPayload.put(RecordMetaAttribute.AUTHORITY.getValue(), record.getAuthority());
+        indexerPayload.put(RecordMetaAttribute.SOURCE.getValue(), record.getSource());
+        indexerPayload.put(RecordMetaAttribute.NAMESPACE.getValue(), record.getNamespace());
+        indexerPayload.put(RecordMetaAttribute.TYPE.getValue(), record.getType());
+        indexerPayload.put(RecordMetaAttribute.VERSION.getValue(), record.getVersion());
+        indexerPayload.put(RecordMetaAttribute.ACL.getValue(), record.getAcl());
+        indexerPayload.put(RecordMetaAttribute.TAGS.getValue(), record.getTags());
+        indexerPayload.put(RecordMetaAttribute.X_ACL.getValue(), Acl.flattenAcl(record.getAcl()));
+        indexerPayload.put(RecordMetaAttribute.LEGAL.getValue(), record.getLegal());
+        indexerPayload.put(RecordMetaAttribute.INDEX_STATUS.getValue(), record.getIndexProgress());
+        if (record.getAncestry() != null) {
+            indexerPayload.put(RecordMetaAttribute.ANCESTRY.getValue(), record.getAncestry());
+        }
+        indexerPayload.put(RecordMetaAttribute.CREATE_USER.getValue(), record.getCreateUser());
+        indexerPayload.put(RecordMetaAttribute.CREATE_TIME.getValue(), record.getCreateTime());
+        if (!Strings.isNullOrEmpty(record.getModifyUser())) {
+            indexerPayload.put(RecordMetaAttribute.MODIFY_USER.getValue(), record.getModifyUser());
+        }
+        if (!Strings.isNullOrEmpty(record.getModifyTime())) {
+            indexerPayload.put(RecordMetaAttribute.MODIFY_TIME.getValue(), record.getModifyTime());
+        }
+        return indexerPayload;
+    }
+
+    private boolean canIndexerRetry(BulkItemResponse bulkItemResponse) {
+        if (RETRY_ELASTIC_EXCEPTION.contains(bulkItemResponse.status())) return true;
+
+        if ((bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE || bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE)
+                && bulkItemResponse.status() == RestStatus.NOT_FOUND) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private void retryAndEnqueueFailedRecords(List<RecordInfo> recordInfos, List<String> failuresRecordIds, RecordChangedMessages message) throws IOException {
+
+        jaxRsDpsLog.info(String.format("queuing bulk failed records back to task-queue for retry | count: %s | records: %s", failuresRecordIds.size(), failuresRecordIds));
+        List<RecordInfo> retryRecordInfos = new LinkedList<>();
+        for (String recordId : failuresRecordIds) {
+            for (RecordInfo origMessage : recordInfos) {
+                if (origMessage.getId().equalsIgnoreCase(recordId)) {
+                    retryRecordInfos.add(origMessage);
+                }
+            }
+        }
+
+        RecordChangedMessages newMessage = RecordChangedMessages.builder()
+                .messageId(message.getMessageId())
+                .publishTime(message.getPublishTime())
+                .data(this.gson.toJson(retryRecordInfos))
+                .attributes(message.getAttributes()).build();
+
+        String payLoad = this.gson.toJson(newMessage);
+        this.indexerQueueTaskBuilder.createWorkerTask(payLoad, this.headers);
+    }
+
+    private void updateAuditLog() {
+        logAuditEvents(OperationType.create, this.auditLogger::indexCreateRecordSuccess, this.auditLogger::indexCreateRecordFail);
+        logAuditEvents(OperationType.update, this.auditLogger::indexUpdateRecordSuccess, this.auditLogger::indexUpdateRecordFail);
+        logAuditEvents(OperationType.purge, this.auditLogger::indexPurgeRecordSuccess, this.auditLogger::indexPurgeRecordFail);
+        logAuditEvents(OperationType.delete, this.auditLogger::indexDeleteRecordSuccess, this.auditLogger::indexDeleteRecordFail);
+    }
+
+    private void logAuditEvents(OperationType operationType, Consumer<List<String>> successEvent, Consumer<List<String>> failedEvent) {
+        List<RecordStatus> succeededRecords = this.jobStatus.getRecordStatuses(IndexingStatus.SUCCESS, operationType);
+        if (!succeededRecords.isEmpty()) {
+            successEvent.accept(succeededRecords.stream().map(RecordStatus::succeededAuditLogMessage).collect(Collectors.toList()));
+        }
+        List<RecordStatus> skippedRecords = this.jobStatus.getRecordStatuses(IndexingStatus.SKIP, operationType);
+        List<RecordStatus> failedRecords = this.jobStatus.getRecordStatuses(IndexingStatus.FAIL, operationType);
+        failedRecords.addAll(skippedRecords);
+        if (!failedRecords.isEmpty()) {
+            failedEvent.accept(failedRecords.stream().map(RecordStatus::failedAuditLogMessage).collect(Collectors.toList()));
+        }
+    }
+}
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapper.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapper.java
index 55759face..ccedb93d6 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapper.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapper.java
@@ -1,190 +1,190 @@
-package org.opengroup.osdu.indexer.service;
-
-import static org.opengroup.osdu.indexer.service.IAttributeParsingService.DATA_GEOJSON_TAG;
-import static org.opengroup.osdu.indexer.service.IAttributeParsingService.RECORD_GEOJSON_TAG;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import javax.inject.Inject;
-import org.apache.commons.beanutils.NestedNullException;
-import org.apache.commons.beanutils.PropertyUtils;
-import org.apache.http.HttpStatus;
-import org.opengroup.osdu.core.common.Constants;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.indexer.ElasticType;
-import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
-import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
-import org.opengroup.osdu.core.common.model.indexer.JobStatus;
-import org.opengroup.osdu.indexer.schema.converter.config.SchemaConverterConfig;
-import org.springframework.stereotype.Component;
-
-@Component
-public class StorageIndexerPayloadMapper {
-
-	@Inject
-	private JaxRsDpsLog log;
-	@Inject
-	private IAttributeParsingService attributeParsingService;
-	@Inject
-	private JobStatus jobStatus;
-	@Inject
-	private SchemaConverterConfig schemaConfig;
-
-	public Map<String, Object> mapDataPayload(IndexSchema storageSchema, Map<String, Object> storageRecordData,
-		String recordId) {
-
-		Map<String, Object> dataCollectorMap = new HashMap<>();
-
-		if (storageSchema.isDataSchemaMissing()) {
-			this.log.warning(String.format("record-id: %s | schema mismatching: %s ", recordId, storageSchema.getKind()));
-			return dataCollectorMap;
-		}
-
-		mapDataPayload(storageSchema.getDataSchema(), storageRecordData, recordId, dataCollectorMap);
-
-		// add these once iterated over the list
-		storageSchema.getDataSchema().put(DATA_GEOJSON_TAG, ElasticType.GEO_SHAPE.getValue());
-		storageSchema.getDataSchema().remove(RECORD_GEOJSON_TAG);
-
-		return dataCollectorMap;
-	}
-
-	private Map<String, Object> mapDataPayload(Map<String, Object> dataSchema, Map<String, Object> storageRecordData,
-		String recordId, Map<String, Object> dataCollectorMap) {
-
-		// get the key and get the corresponding object from the storageRecord object
-		for (Map.Entry<String, Object> entry : dataSchema.entrySet()) {
-			String schemaPropertyName = entry.getKey();
-			Object storageRecordValue = getPropertyValue(recordId, storageRecordData, schemaPropertyName);
-			ElasticType elasticType = defineElasticType(entry.getValue());
-
-			if (Objects.isNull(elasticType)) {
-				this.jobStatus
-					.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST,
-						String.format("record-id: %s | %s for entry %s", recordId, "Not resolvable elastic type", schemaPropertyName));
-				continue;
-			}
-
-			if (schemaConfig.getProcessedArraysTypes().contains(elasticType.getValue().toLowerCase()) && Objects.nonNull(storageRecordValue)) {
-				processInnerProperties(recordId, dataCollectorMap, entry.getValue(), schemaPropertyName, (List<Map>) storageRecordValue);
-			}
-
-			if (storageRecordValue == null && !nullIndexedValueSupported(elasticType)) {
-				continue;
-			}
-
-			switch (elasticType) {
-				case KEYWORD:
-				case KEYWORD_ARRAY:
-				case TEXT:
-				case TEXT_ARRAY:
-					dataCollectorMap.put(schemaPropertyName, storageRecordValue);
-					break;
-				case INTEGER_ARRAY:
-					this.attributeParsingService.tryParseValueArray(Integer.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case INTEGER:
-					this.attributeParsingService.tryParseInteger(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case LONG_ARRAY:
-					this.attributeParsingService.tryParseValueArray(Long.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case LONG:
-					this.attributeParsingService.tryParseLong(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case FLOAT_ARRAY:
-					this.attributeParsingService.tryParseValueArray(Float.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case FLOAT:
-					this.attributeParsingService.tryParseFloat(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case DOUBLE_ARRAY:
-					this.attributeParsingService.tryParseValueArray(Double.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case DOUBLE:
-					this.attributeParsingService.tryParseDouble(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case BOOLEAN_ARRAY:
-					this.attributeParsingService.tryParseValueArray(Boolean.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case BOOLEAN:
-					this.attributeParsingService.tryParseBoolean(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case DATE_ARRAY:
-					this.attributeParsingService.tryParseValueArray(Date.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case DATE:
-					this.attributeParsingService.tryParseDate(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case GEO_POINT:
-					this.attributeParsingService.tryParseGeopoint(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case GEO_SHAPE:
-					this.attributeParsingService.tryParseGeojson(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case FLATTENED:
-					// flattened type inner properties will be added "as is" without parsing as they types not present in schema
-					this.attributeParsingService.tryParseFlattened(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case OBJECT:
-					// object type inner properties will be added "as is" without parsing as they types not present in schema
-					this.attributeParsingService.tryParseObject(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
-					break;
-				case UNDEFINED:
-					// don't do anything for now
-					break;
-			}
-		}
-
-		return dataCollectorMap;
-	}
-
-	private void processInnerProperties(String recordId, Map<String, Object> dataCollectorMap, Object schemaPropertyWithInnerProperties,
-		String name, List<Map> storageRecordValue) {
-		Map schemaPropertyMap = (Map) schemaPropertyWithInnerProperties;
-		Map innerProperties = (Map) schemaPropertyMap.get(Constants.PROPERTIES);
-		ArrayList<Map> innerPropertiesMappingCollector = new ArrayList<>();
-		storageRecordValue.forEach(recordData -> innerPropertiesMappingCollector.add(mapDataPayload(innerProperties, recordData, recordId, new HashMap<>())));
-		dataCollectorMap.put(name, innerPropertiesMappingCollector);
-	}
-
-	private ElasticType defineElasticType(Object entryValue) {
-		ElasticType elasticType = null;
-		if (entryValue instanceof String) {
-			elasticType = ElasticType.forValue(entryValue.toString());
-		} else if (entryValue instanceof Map) {
-			Map map = (Map) entryValue;
-			elasticType = ElasticType.forValue(map.get(Constants.TYPE).toString());
-		}
-		return elasticType;
-	}
-
-	private Object getPropertyValue(String recordId, Map<String, Object> storageRecordData, String propertyKey) {
-
-        try {
-            // try getting first level property using optimized collection
-            Object propertyVal = storageRecordData.get(propertyKey);
-            if (propertyVal != null) return propertyVal;
-
-            // use apache utils to get nested property
-            return PropertyUtils.getProperty(storageRecordData, propertyKey);
-        } catch (NestedNullException ignored) {
-            // property not found in record
-        } catch (NoSuchMethodException e) {
-            this.log.warning(String.format("record-id: %s | error fetching property: %s | error: %s", recordId, propertyKey, e.getMessage()));
-        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
-            this.log.warning(String.format("record-id: %s | error fetching property: %s | error: %s", recordId, propertyKey, e.getMessage()), e);
-        }
-        return null;
-    }
-
-    private boolean nullIndexedValueSupported(ElasticType type) {
-        return type == ElasticType.TEXT;
-    }
+package org.opengroup.osdu.indexer.service;
+
+import static org.opengroup.osdu.indexer.service.IAttributeParsingService.DATA_GEOJSON_TAG;
+import static org.opengroup.osdu.indexer.service.IAttributeParsingService.RECORD_GEOJSON_TAG;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import javax.inject.Inject;
+import org.apache.commons.beanutils.NestedNullException;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.core.common.Constants;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.indexer.ElasticType;
+import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
+import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
+import org.opengroup.osdu.core.common.model.indexer.JobStatus;
+import org.opengroup.osdu.indexer.schema.converter.config.SchemaConverterConfig;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StorageIndexerPayloadMapper {
+
+	@Inject
+	private JaxRsDpsLog log;
+	@Inject
+	private IAttributeParsingService attributeParsingService;
+	@Inject
+	private JobStatus jobStatus;
+	@Inject
+	private SchemaConverterConfig schemaConfig;
+
+	public Map<String, Object> mapDataPayload(IndexSchema storageSchema, Map<String, Object> storageRecordData,
+		String recordId) {
+
+		Map<String, Object> dataCollectorMap = new HashMap<>();
+
+		if (storageSchema.isDataSchemaMissing()) {
+			this.log.warning(String.format("record-id: %s | schema mismatching: %s ", recordId, storageSchema.getKind()));
+			return dataCollectorMap;
+		}
+
+		mapDataPayload(storageSchema.getDataSchema(), storageRecordData, recordId, dataCollectorMap);
+
+		// add these once iterated over the list
+		storageSchema.getDataSchema().put(DATA_GEOJSON_TAG, ElasticType.GEO_SHAPE.getValue());
+		storageSchema.getDataSchema().remove(RECORD_GEOJSON_TAG);
+
+		return dataCollectorMap;
+	}
+
+	private Map<String, Object> mapDataPayload(Map<String, Object> dataSchema, Map<String, Object> storageRecordData,
+		String recordId, Map<String, Object> dataCollectorMap) {
+
+		// get the key and get the corresponding object from the storageRecord object
+		for (Map.Entry<String, Object> entry : dataSchema.entrySet()) {
+			String schemaPropertyName = entry.getKey();
+			Object storageRecordValue = getPropertyValue(recordId, storageRecordData, schemaPropertyName);
+			ElasticType elasticType = defineElasticType(entry.getValue());
+
+			if (Objects.isNull(elasticType)) {
+				this.jobStatus
+					.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST,
+						String.format("record-id: %s | %s for entry %s", recordId, "Not resolvable elastic type", schemaPropertyName));
+				continue;
+			}
+
+			if (schemaConfig.getProcessedArraysTypes().contains(elasticType.getValue().toLowerCase()) && Objects.nonNull(storageRecordValue)) {
+				processInnerProperties(recordId, dataCollectorMap, entry.getValue(), schemaPropertyName, (List<Map>) storageRecordValue);
+			}
+
+			if (storageRecordValue == null && !nullIndexedValueSupported(elasticType)) {
+				continue;
+			}
+
+			switch (elasticType) {
+				case KEYWORD:
+				case KEYWORD_ARRAY:
+				case TEXT:
+				case TEXT_ARRAY:
+					dataCollectorMap.put(schemaPropertyName, storageRecordValue);
+					break;
+				case INTEGER_ARRAY:
+					this.attributeParsingService.tryParseValueArray(Integer.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case INTEGER:
+					this.attributeParsingService.tryParseInteger(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case LONG_ARRAY:
+					this.attributeParsingService.tryParseValueArray(Long.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case LONG:
+					this.attributeParsingService.tryParseLong(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case FLOAT_ARRAY:
+					this.attributeParsingService.tryParseValueArray(Float.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case FLOAT:
+					this.attributeParsingService.tryParseFloat(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case DOUBLE_ARRAY:
+					this.attributeParsingService.tryParseValueArray(Double.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case DOUBLE:
+					this.attributeParsingService.tryParseDouble(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case BOOLEAN_ARRAY:
+					this.attributeParsingService.tryParseValueArray(Boolean.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case BOOLEAN:
+					this.attributeParsingService.tryParseBoolean(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case DATE_ARRAY:
+					this.attributeParsingService.tryParseValueArray(Date.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case DATE:
+					this.attributeParsingService.tryParseDate(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case GEO_POINT:
+					this.attributeParsingService.tryParseGeopoint(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case GEO_SHAPE:
+					this.attributeParsingService.tryParseGeojson(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case FLATTENED:
+					// flattened type inner properties will be added "as is" without parsing as they types not present in schema
+					this.attributeParsingService.tryParseFlattened(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case OBJECT:
+					// object type inner properties will be added "as is" without parsing as they types not present in schema
+					this.attributeParsingService.tryParseObject(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+					break;
+				case UNDEFINED:
+					// don't do anything for now
+					break;
+			}
+		}
+
+		return dataCollectorMap;
+	}
+
+	private void processInnerProperties(String recordId, Map<String, Object> dataCollectorMap, Object schemaPropertyWithInnerProperties,
+		String name, List<Map> storageRecordValue) {
+		Map schemaPropertyMap = (Map) schemaPropertyWithInnerProperties;
+		Map innerProperties = (Map) schemaPropertyMap.get(Constants.PROPERTIES);
+		ArrayList<Map> innerPropertiesMappingCollector = new ArrayList<>();
+		storageRecordValue.forEach(recordData -> innerPropertiesMappingCollector.add(mapDataPayload(innerProperties, recordData, recordId, new HashMap<>())));
+		dataCollectorMap.put(name, innerPropertiesMappingCollector);
+	}
+
+	private ElasticType defineElasticType(Object entryValue) {
+		ElasticType elasticType = null;
+		if (entryValue instanceof String) {
+			elasticType = ElasticType.forValue(entryValue.toString());
+		} else if (entryValue instanceof Map) {
+			Map map = (Map) entryValue;
+			elasticType = ElasticType.forValue(map.get(Constants.TYPE).toString());
+		}
+		return elasticType;
+	}
+
+	private Object getPropertyValue(String recordId, Map<String, Object> storageRecordData, String propertyKey) {
+
+        try {
+            // try getting first level property using optimized collection
+            Object propertyVal = storageRecordData.get(propertyKey);
+            if (propertyVal != null) return propertyVal;
+
+            // use apache utils to get nested property
+            return PropertyUtils.getProperty(storageRecordData, propertyKey);
+        } catch (NestedNullException ignored) {
+            // property not found in record
+        } catch (NoSuchMethodException e) {
+            this.log.warning(String.format("record-id: %s | error fetching property: %s | error: %s", recordId, propertyKey, e.getMessage()));
+        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
+            this.log.warning(String.format("record-id: %s | error fetching property: %s | error: %s", recordId, propertyKey, e.getMessage()), e);
+        }
+        return null;
+    }
+
+    private boolean nullIndexedValueSupported(ElasticType type) {
+        return type == ElasticType.TEXT;
+    }
 }
\ No newline at end of file
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageServiceImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageServiceImpl.java
index 50363f976..1dcb6a091 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageServiceImpl.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/StorageServiceImpl.java
@@ -1,234 +1,234 @@
-// 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.service;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.api.client.http.HttpMethods;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.gson.Gson;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-import org.opengroup.osdu.core.common.model.http.RequestStatus;
-import org.opengroup.osdu.core.common.model.indexer.*;
-import org.opengroup.osdu.core.common.model.storage.ConversionStatus;
-import org.opengroup.osdu.core.common.model.storage.RecordIds;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.http.IUrlFetchService;
-import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
-import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
-import org.apache.http.HttpStatus;
-import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-import javax.inject.Inject;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import static org.opengroup.osdu.core.common.model.http.DpsHeaders.FRAME_OF_REFERENCE;
-import static org.opengroup.osdu.core.common.Constants.SLB_FRAME_OF_REFERENCE_VALUE;
-
-@Component
-public class StorageServiceImpl implements StorageService {
-
-    private final Gson gson = new Gson();
-
-    @Inject
-    private ObjectMapper objectMapper;
-    @Inject
-    private IUrlFetchService urlFetchService;
-    @Inject
-    private JobStatus jobStatus;
-    @Inject
-    private IRequestInfo requestInfo;
-    @Inject
-    private JaxRsDpsLog jaxRsDpsLog;
-    @Inject
-    private IndexerConfigurationProperties configurationProperties;
-
-    @Override
-    public Records getStorageRecords(List<String> ids) throws AppException, URISyntaxException {
-        List<Records.Entity> valid = new ArrayList<>();
-        List<String> notFound = new ArrayList<>();
-        List<ConversionStatus> conversionStatuses = new ArrayList<>();
-        List<String> missingRetryRecordIds = new ArrayList<>();
-
-        List<List<String>> batch = Lists.partition(ids, configurationProperties.getStorageRecordsBatchSize());
-        for (List<String> recordsBatch : batch) {
-            Records storageOut = this.getRecords(recordsBatch);
-            valid.addAll(storageOut.getRecords());
-            notFound.addAll(storageOut.getNotFound());
-            conversionStatuses.addAll(storageOut.getConversionStatuses());
-            missingRetryRecordIds.addAll(storageOut.getMissingRetryRecords());
-        }
-        return Records.builder().records(valid).notFound(notFound).conversionStatuses(conversionStatuses).missingRetryRecords(missingRetryRecordIds).build();
-    }
-
-    protected Records getRecords(List<String> ids) throws URISyntaxException {
-        // e.g. {"records":["test:10"]}
-        String body = this.gson.toJson(RecordIds.builder().records(ids).build());
-
-//        Map<String, String> headers = this.requestInfo.getHeadersMap();
-        DpsHeaders headers = this.requestInfo.getHeaders();
-        headers.put(FRAME_OF_REFERENCE, SLB_FRAME_OF_REFERENCE_VALUE);
-        FetchServiceHttpRequest request = FetchServiceHttpRequest
-                .builder()
-                .httpMethod(HttpMethods.POST)
-                .url(configurationProperties.getStorageQueryRecordForConversionHost())
-                .headers(headers)
-                .body(body).build();
-        HttpResponse response = this.urlFetchService.sendRequest(request);
-        return this.validateStorageResponse(response, ids);
-    }
-
-    private Records validateStorageResponse(HttpResponse response, List<String> ids) {
-        String bulkStorageData = response.getBody();
-
-        // retry entire payload -- storage service returned empty response
-        if (Strings.isNullOrEmpty(bulkStorageData)) {
-            throw new AppException(HttpStatus.SC_NOT_FOUND, "Invalid request", "Storage service returned empty response");
-        }
-
-        Records records = null;
-        try {
-            records = this.objectMapper.readValue(bulkStorageData, Records.class);
-        } catch (JsonProcessingException e) {
-            throw new AppException(RequestStatus.INVALID_RECORD, "Invalid request", "Successful Storage service response with wrong json", e);
-        }
-
-        // no retry possible, update record status as failed -- storage service cannot locate records
-        if (!records.getNotFound().isEmpty()) {
-            this.jobStatus.addOrUpdateRecordStatus(records.getNotFound(), IndexingStatus.FAIL, RequestStatus.INVALID_RECORD, "Storage service records not found", String.format("Storage service records not found: %s", String.join(",", records.getNotFound())));
-        }
-
-        List<Records.Entity> validRecords = records.getRecords();
-        if (validRecords.isEmpty()) {
-            // no need to retry, ack the CloudTask message -- nothing to process from RecordChangeMessage batch
-            if (response.isSuccessCode()) {
-                throw new AppException(RequestStatus.INVALID_RECORD, "Invalid request", "Successful Storage service response with no valid records");
-            }
-
-            // retry entire payload -- storage service returned empty valid records with non-success response-code
-            jaxRsDpsLog.warning(String.format("unable to proceed, valid storage record not found. | upstream response code: %s | record ids: %s", response.getResponseCode(), String.join(" | ", ids)));
-            throw new AppException(HttpStatus.SC_NOT_FOUND, "Invalid request", "Storage service error");
-        }
-
-        Map<String, List<String>> conversionStatus = getConversionErrors(records.getConversionStatuses());
-        for (Records.Entity storageRecord : validRecords) {
-            String recordId = storageRecord.getId();
-            if (conversionStatus.get(recordId) == null) {
-                continue;
-            }
-            for (String status : conversionStatus.get(recordId)) {
-                this.jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, status, String.format("record-id: %s | %s", recordId, status));
-            }
-        }
-
-        // retry missing records -- storage did not return response for all RecordChangeMessage record-ids
-        if (records.getTotalRecordCount() != ids.size()) {
-            List<String> missingRecords = this.getMissingRecords(records, ids);
-            records.setMissingRetryRecords(missingRecords);
-            this.jobStatus.addOrUpdateRecordStatus(missingRecords, IndexingStatus.FAIL, HttpStatus.SC_NOT_FOUND, "Partial response received from Storage service - missing records", String.format("Partial response received from Storage service: %s", String.join(",", missingRecords)));
-        }
-
-        return records;
-    }
-
-    private List<String> getMissingRecords(Records records, List<String> ids) {
-        List<String> validRecordIds = records.getRecords().stream().map(Records.Entity::getId).collect(Collectors.toList());
-        List<String> invalidRecordsIds = records.getNotFound();
-        List<String> requestedIds = new ArrayList<>(ids);
-        requestedIds.removeAll(validRecordIds);
-        requestedIds.removeAll(invalidRecordsIds);
-        return requestedIds;
-    }
-
-    private Map<String, List<String>> getConversionErrors(List<ConversionStatus> conversionStatuses) {
-        Map<String, List<String>> errorsByRecordId = new HashMap<>();
-        for (ConversionStatus conversionStatus : conversionStatuses) {
-            if (Strings.isNullOrEmpty(conversionStatus.getStatus())) continue;
-            if (conversionStatus.getStatus().equalsIgnoreCase("ERROR")) {
-                List<String> statuses = errorsByRecordId.getOrDefault(conversionStatus.getId(), new LinkedList<>());
-                statuses.addAll(conversionStatus.getErrors());
-                errorsByRecordId.put(conversionStatus.getId(), statuses);
-            }
-        }
-        return errorsByRecordId;
-    }
-
-    @Override
-    public RecordQueryResponse getRecordsByKind(RecordReindexRequest reindexRequest) throws URISyntaxException {
-        Map<String, String> queryParams = new HashMap<>();
-        queryParams.put(RecordMetaAttribute.KIND.getValue(), reindexRequest.getKind());
-        queryParams.put("limit", configurationProperties.getStorageRecordsByKindBatchSize().toString());
-        if (!Strings.isNullOrEmpty(reindexRequest.getCursor())) {
-            queryParams.put("cursor", reindexRequest.getCursor());
-        }
-
-        if(requestInfo == null)
-            throw  new AppException(HttpStatus.SC_NO_CONTENT, "Invalid header", "header can't be null");
-
-        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
-                .httpMethod(HttpMethods.GET)
-                .headers(this.requestInfo.getHeadersMap())
-                .url(configurationProperties.getStorageQueryRecordHost())
-                .queryParams(queryParams)
-                .build();
-
-        HttpResponse response = this.urlFetchService.sendRequest(request);
-        return this.gson.fromJson(response.getBody(), RecordQueryResponse.class);
-    }
-
-    @Override
-    public String getStorageSchema(String kind) throws URISyntaxException, UnsupportedEncodingException {
-        String url = String.format("%s/%s", configurationProperties.getStorageSchemaHost(), URLEncoder.encode(kind, StandardCharsets.UTF_8.toString()));
-        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
-                .httpMethod(HttpMethods.GET)
-                .headers(this.requestInfo.getHeadersMap())
-                .url(url)
-                .build();
-        HttpResponse response = this.urlFetchService.sendRequest(request);
-        return response.getResponseCode() != HttpStatus.SC_OK ? null : response.getBody();
-    }
-
-    @Override
-    public List<String> getAllKinds() throws URISyntaxException {
-        String url = configurationProperties.getStorageQueryKindsHost();
-        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
-            .httpMethod(HttpMethods.GET)
-            .headers(this.requestInfo.getHeadersMap())
-            .url(url)
-            .build();
-        HttpResponse response = this.urlFetchService.sendRequest(request);
-        JsonObject asJsonObject = new JsonParser().parse(response.getBody()).getAsJsonObject();
-        JsonElement results = asJsonObject.get("results");
-        return response.getResponseCode() != HttpStatus.SC_OK ? null : this.gson.fromJson(results,List.class);
-    }
+// 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.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.api.client.http.HttpMethods;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+import org.opengroup.osdu.core.common.model.http.RequestStatus;
+import org.opengroup.osdu.core.common.model.indexer.*;
+import org.opengroup.osdu.core.common.model.storage.ConversionStatus;
+import org.opengroup.osdu.core.common.model.storage.RecordIds;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.http.IUrlFetchService;
+import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
+import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.opengroup.osdu.core.common.model.http.DpsHeaders.FRAME_OF_REFERENCE;
+import static org.opengroup.osdu.core.common.Constants.SLB_FRAME_OF_REFERENCE_VALUE;
+
+@Component
+public class StorageServiceImpl implements StorageService {
+
+    private final Gson gson = new Gson();
+
+    @Inject
+    private ObjectMapper objectMapper;
+    @Inject
+    private IUrlFetchService urlFetchService;
+    @Inject
+    private JobStatus jobStatus;
+    @Inject
+    private IRequestInfo requestInfo;
+    @Inject
+    private JaxRsDpsLog jaxRsDpsLog;
+    @Inject
+    private IndexerConfigurationProperties configurationProperties;
+
+    @Override
+    public Records getStorageRecords(List<String> ids) throws AppException, URISyntaxException {
+        List<Records.Entity> valid = new ArrayList<>();
+        List<String> notFound = new ArrayList<>();
+        List<ConversionStatus> conversionStatuses = new ArrayList<>();
+        List<String> missingRetryRecordIds = new ArrayList<>();
+
+        List<List<String>> batch = Lists.partition(ids, configurationProperties.getStorageRecordsBatchSize());
+        for (List<String> recordsBatch : batch) {
+            Records storageOut = this.getRecords(recordsBatch);
+            valid.addAll(storageOut.getRecords());
+            notFound.addAll(storageOut.getNotFound());
+            conversionStatuses.addAll(storageOut.getConversionStatuses());
+            missingRetryRecordIds.addAll(storageOut.getMissingRetryRecords());
+        }
+        return Records.builder().records(valid).notFound(notFound).conversionStatuses(conversionStatuses).missingRetryRecords(missingRetryRecordIds).build();
+    }
+
+    protected Records getRecords(List<String> ids) throws URISyntaxException {
+        // e.g. {"records":["test:10"]}
+        String body = this.gson.toJson(RecordIds.builder().records(ids).build());
+
+//        Map<String, String> headers = this.requestInfo.getHeadersMap();
+        DpsHeaders headers = this.requestInfo.getHeaders();
+        headers.put(FRAME_OF_REFERENCE, SLB_FRAME_OF_REFERENCE_VALUE);
+        FetchServiceHttpRequest request = FetchServiceHttpRequest
+                .builder()
+                .httpMethod(HttpMethods.POST)
+                .url(configurationProperties.getStorageQueryRecordForConversionHost())
+                .headers(headers)
+                .body(body).build();
+        HttpResponse response = this.urlFetchService.sendRequest(request);
+        return this.validateStorageResponse(response, ids);
+    }
+
+    private Records validateStorageResponse(HttpResponse response, List<String> ids) {
+        String bulkStorageData = response.getBody();
+
+        // retry entire payload -- storage service returned empty response
+        if (Strings.isNullOrEmpty(bulkStorageData)) {
+            throw new AppException(HttpStatus.SC_NOT_FOUND, "Invalid request", "Storage service returned empty response");
+        }
+
+        Records records = null;
+        try {
+            records = this.objectMapper.readValue(bulkStorageData, Records.class);
+        } catch (JsonProcessingException e) {
+            throw new AppException(RequestStatus.INVALID_RECORD, "Invalid request", "Successful Storage service response with wrong json", e);
+        }
+
+        // no retry possible, update record status as failed -- storage service cannot locate records
+        if (!records.getNotFound().isEmpty()) {
+            this.jobStatus.addOrUpdateRecordStatus(records.getNotFound(), IndexingStatus.FAIL, RequestStatus.INVALID_RECORD, "Storage service records not found", String.format("Storage service records not found: %s", String.join(",", records.getNotFound())));
+        }
+
+        List<Records.Entity> validRecords = records.getRecords();
+        if (validRecords.isEmpty()) {
+            // no need to retry, ack the CloudTask message -- nothing to process from RecordChangeMessage batch
+            if (response.isSuccessCode()) {
+                throw new AppException(RequestStatus.INVALID_RECORD, "Invalid request", "Successful Storage service response with no valid records");
+            }
+
+            // retry entire payload -- storage service returned empty valid records with non-success response-code
+            jaxRsDpsLog.warning(String.format("unable to proceed, valid storage record not found. | upstream response code: %s | record ids: %s", response.getResponseCode(), String.join(" | ", ids)));
+            throw new AppException(HttpStatus.SC_NOT_FOUND, "Invalid request", "Storage service error");
+        }
+
+        Map<String, List<String>> conversionStatus = getConversionErrors(records.getConversionStatuses());
+        for (Records.Entity storageRecord : validRecords) {
+            String recordId = storageRecord.getId();
+            if (conversionStatus.get(recordId) == null) {
+                continue;
+            }
+            for (String status : conversionStatus.get(recordId)) {
+                this.jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, status, String.format("record-id: %s | %s", recordId, status));
+            }
+        }
+
+        // retry missing records -- storage did not return response for all RecordChangeMessage record-ids
+        if (records.getTotalRecordCount() != ids.size()) {
+            List<String> missingRecords = this.getMissingRecords(records, ids);
+            records.setMissingRetryRecords(missingRecords);
+            this.jobStatus.addOrUpdateRecordStatus(missingRecords, IndexingStatus.FAIL, HttpStatus.SC_NOT_FOUND, "Partial response received from Storage service - missing records", String.format("Partial response received from Storage service: %s", String.join(",", missingRecords)));
+        }
+
+        return records;
+    }
+
+    private List<String> getMissingRecords(Records records, List<String> ids) {
+        List<String> validRecordIds = records.getRecords().stream().map(Records.Entity::getId).collect(Collectors.toList());
+        List<String> invalidRecordsIds = records.getNotFound();
+        List<String> requestedIds = new ArrayList<>(ids);
+        requestedIds.removeAll(validRecordIds);
+        requestedIds.removeAll(invalidRecordsIds);
+        return requestedIds;
+    }
+
+    private Map<String, List<String>> getConversionErrors(List<ConversionStatus> conversionStatuses) {
+        Map<String, List<String>> errorsByRecordId = new HashMap<>();
+        for (ConversionStatus conversionStatus : conversionStatuses) {
+            if (Strings.isNullOrEmpty(conversionStatus.getStatus())) continue;
+            if (conversionStatus.getStatus().equalsIgnoreCase("ERROR")) {
+                List<String> statuses = errorsByRecordId.getOrDefault(conversionStatus.getId(), new LinkedList<>());
+                statuses.addAll(conversionStatus.getErrors());
+                errorsByRecordId.put(conversionStatus.getId(), statuses);
+            }
+        }
+        return errorsByRecordId;
+    }
+
+    @Override
+    public RecordQueryResponse getRecordsByKind(RecordReindexRequest reindexRequest) throws URISyntaxException {
+        Map<String, String> queryParams = new HashMap<>();
+        queryParams.put(RecordMetaAttribute.KIND.getValue(), reindexRequest.getKind());
+        queryParams.put("limit", configurationProperties.getStorageRecordsByKindBatchSize().toString());
+        if (!Strings.isNullOrEmpty(reindexRequest.getCursor())) {
+            queryParams.put("cursor", reindexRequest.getCursor());
+        }
+
+        if(requestInfo == null)
+            throw  new AppException(HttpStatus.SC_NO_CONTENT, "Invalid header", "header can't be null");
+
+        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
+                .httpMethod(HttpMethods.GET)
+                .headers(this.requestInfo.getHeadersMap())
+                .url(configurationProperties.getStorageQueryRecordHost())
+                .queryParams(queryParams)
+                .build();
+
+        HttpResponse response = this.urlFetchService.sendRequest(request);
+        return this.gson.fromJson(response.getBody(), RecordQueryResponse.class);
+    }
+
+    @Override
+    public String getStorageSchema(String kind) throws URISyntaxException, UnsupportedEncodingException {
+        String url = String.format("%s/%s", configurationProperties.getStorageSchemaHost(), URLEncoder.encode(kind, StandardCharsets.UTF_8.toString()));
+        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
+                .httpMethod(HttpMethods.GET)
+                .headers(this.requestInfo.getHeadersMap())
+                .url(url)
+                .build();
+        HttpResponse response = this.urlFetchService.sendRequest(request);
+        return response.getResponseCode() != HttpStatus.SC_OK ? null : response.getBody();
+    }
+
+    @Override
+    public List<String> getAllKinds() throws URISyntaxException {
+        String url = configurationProperties.getStorageQueryKindsHost();
+        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
+            .httpMethod(HttpMethods.GET)
+            .headers(this.requestInfo.getHeadersMap())
+            .url(url)
+            .build();
+        HttpResponse response = this.urlFetchService.sendRequest(request);
+        JsonObject asJsonObject = new JsonParser().parse(response.getBody()).getAsJsonObject();
+        JsonElement results = asJsonObject.get("results");
+        return response.getResponseCode() != HttpStatus.SC_OK ? null : this.gson.fromJson(results,List.class);
+    }
 }
\ No newline at end of file
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerQueueTaskBuilder.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerQueueTaskBuilder.java
index 6d0cf380a..1d94b21ae 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerQueueTaskBuilder.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/IndexerQueueTaskBuilder.java
@@ -1,86 +1,86 @@
-// 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.util;
-
-import com.google.api.client.http.HttpMethods;
-import com.google.gson.Gson;
-import lombok.extern.java.Log;
-import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.search.CloudTaskRequest;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.http.IUrlFetchService;
-import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.annotation.RequestScope;
-
-import java.net.URISyntaxException;
-import java.util.Map;
-import javax.inject.Inject;
-
-import static org.opengroup.osdu.core.common.Constants.REINDEX_RELATIVE_URL;
-import static org.opengroup.osdu.core.common.Constants.WORKER_RELATIVE_URL;
-
-    @Log
-    @Component
-    @RequestScope
-    public class IndexerQueueTaskBuilder {
-
-    @Inject
-    private IUrlFetchService urlFetchService;
-    @Inject
-    private JaxRsDpsLog jaxRsDpsLog;
-    @Inject
-    private IndexerConfigurationProperties configurationProperties;
-
-    public void createWorkerTask(String payload, DpsHeaders headers) {
-        createTask(WORKER_RELATIVE_URL, payload, 0l, headers);
-    }
-
-    public void createWorkerTask(String payload, Long countdownMillis, DpsHeaders headers) {
-        createTask(WORKER_RELATIVE_URL, payload, countdownMillis, headers);
-    }
-
-    public void createReIndexTask(String payload, DpsHeaders headers) {
-        createTask(REINDEX_RELATIVE_URL, payload, 0l, headers);
-    }
-
-    public void createReIndexTask(String payload, Long countdownMillis, DpsHeaders headers) {
-        createTask(REINDEX_RELATIVE_URL, payload, countdownMillis, headers);
-    }
-
-    private void createTask(String url, String payload, Long countdownMillis, DpsHeaders headers) {
-        CloudTaskRequest cloudTaskRequest = CloudTaskRequest.builder()
-                .message(payload)
-                .url(url)
-                .initialDelayMillis(countdownMillis)
-                .build();
-
-        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
-                .httpMethod(HttpMethods.POST)
-                .url(configurationProperties.getIndexerQueueHost())
-                .body(new Gson().toJson(cloudTaskRequest))
-                .headers(headers)
-                .build();
-        try {
-            HttpResponse response = this.urlFetchService.sendRequest(request);
-            this.jaxRsDpsLog.info(String.format("task enqueuing response: %s", response.getResponseCode()));
-        } catch (URISyntaxException e) {
-            this.jaxRsDpsLog.warning(String.format("error enqueuing task message: %s | url: %s | task payload: %s", e.getMessage(), url, payload));
-        }
-    }
+// 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.util;
+
+import com.google.api.client.http.HttpMethods;
+import com.google.gson.Gson;
+import lombok.extern.java.Log;
+import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.search.CloudTaskRequest;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.http.IUrlFetchService;
+import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+import java.net.URISyntaxException;
+import java.util.Map;
+import javax.inject.Inject;
+
+import static org.opengroup.osdu.core.common.Constants.REINDEX_RELATIVE_URL;
+import static org.opengroup.osdu.core.common.Constants.WORKER_RELATIVE_URL;
+
+    @Log
+    @Component
+    @RequestScope
+    public class IndexerQueueTaskBuilder {
+
+    @Inject
+    private IUrlFetchService urlFetchService;
+    @Inject
+    private JaxRsDpsLog jaxRsDpsLog;
+    @Inject
+    private IndexerConfigurationProperties configurationProperties;
+
+    public void createWorkerTask(String payload, DpsHeaders headers) {
+        createTask(WORKER_RELATIVE_URL, payload, 0l, headers);
+    }
+
+    public void createWorkerTask(String payload, Long countdownMillis, DpsHeaders headers) {
+        createTask(WORKER_RELATIVE_URL, payload, countdownMillis, headers);
+    }
+
+    public void createReIndexTask(String payload, DpsHeaders headers) {
+        createTask(REINDEX_RELATIVE_URL, payload, 0l, headers);
+    }
+
+    public void createReIndexTask(String payload, Long countdownMillis, DpsHeaders headers) {
+        createTask(REINDEX_RELATIVE_URL, payload, countdownMillis, headers);
+    }
+
+    private void createTask(String url, String payload, Long countdownMillis, DpsHeaders headers) {
+        CloudTaskRequest cloudTaskRequest = CloudTaskRequest.builder()
+                .message(payload)
+                .url(url)
+                .initialDelayMillis(countdownMillis)
+                .build();
+
+        FetchServiceHttpRequest request = FetchServiceHttpRequest.builder()
+                .httpMethod(HttpMethods.POST)
+                .url(configurationProperties.getIndexerQueueHost())
+                .body(new Gson().toJson(cloudTaskRequest))
+                .headers(headers)
+                .build();
+        try {
+            HttpResponse response = this.urlFetchService.sendRequest(request);
+            this.jaxRsDpsLog.info(String.format("task enqueuing response: %s", response.getResponseCode()));
+        } catch (URISyntaxException e) {
+            this.jaxRsDpsLog.warning(String.format("error enqueuing task message: %s | url: %s | task payload: %s", e.getMessage(), url, payload));
+        }
+    }
 }
\ No newline at end of file
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/parser/BooleanParser.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/parser/BooleanParser.java
index 3bb08d3fc..3177f3b65 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/parser/BooleanParser.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/util/parser/BooleanParser.java
@@ -1,15 +1,15 @@
-package org.opengroup.osdu.indexer.util.parser;
-
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.annotation.RequestScope;
-
-@Component
-@RequestScope
-public class BooleanParser {
-
-    public boolean parseBoolean(String attributeName, Object attributeVal) {
-        String val = attributeVal == null ? null : String.valueOf(attributeVal);
-        return Boolean.parseBoolean(val);
-    }
-
-}
+package org.opengroup.osdu.indexer.util.parser;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+@Component
+@RequestScope
+public class BooleanParser {
+
+    public boolean parseBoolean(String attributeName, Object attributeVal) {
+        String val = attributeVal == null ? null : String.valueOf(attributeVal);
+        return Boolean.parseBoolean(val);
+    }
+
+}
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/ReindexApiTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/ReindexApiTest.java
index 089f8417a..23513bc5d 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/ReindexApiTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/api/ReindexApiTest.java
@@ -1,77 +1,77 @@
-// 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.api;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.indexer.logging.AuditLogger;
-import org.opengroup.osdu.indexer.service.IndexSchemaService;
-import org.opengroup.osdu.indexer.service.ReindexService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-@RunWith(SpringRunner.class)
-public class ReindexApiTest {
-
-    private RecordReindexRequest recordReindexRequest;
-
-    @Mock
-    private ReindexService reIndexService;
-    @Mock
-    private IndexSchemaService indexSchemaService;
-    @Mock
-    private AuditLogger auditLogger;
-    @InjectMocks
-    private ReindexApi sut;
-
-    @Before
-    public void setup() {
-        recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor("100").build();
-    }
-
-    @Test
-    public void should_return200_when_valid_kind_provided() throws IOException {
-        when(this.reIndexService.reindexRecords(recordReindexRequest, false)).thenReturn("something");
-
-        ResponseEntity<?> response = sut.reindex(recordReindexRequest, false);
-
-        assertEquals(HttpStatus.OK, response.getStatusCode());
-    }
-
-    @Test(expected = AppException.class)
-    public void should_throwAppException_ifUnknownExceptionCaught_reindexTest() throws IOException {
-        when(this.reIndexService.reindexRecords(recordReindexRequest, false)).thenThrow(new AppException(500, "", ""));
-
-        sut.reindex(recordReindexRequest, false);
-    }
-
-    @Test(expected = NullPointerException.class)
-    public void should_throwAppException_ifNullPointerExceptionCaught_ReindexTest() throws IOException {
-        when(this.reIndexService.reindexRecords(recordReindexRequest, false)).thenThrow(new NullPointerException(""));
-
-        sut.reindex(recordReindexRequest, false);
-    }
-}
+// 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.api;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.indexer.logging.AuditLogger;
+import org.opengroup.osdu.indexer.service.IndexSchemaService;
+import org.opengroup.osdu.indexer.service.ReindexService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringRunner.class)
+public class ReindexApiTest {
+
+    private RecordReindexRequest recordReindexRequest;
+
+    @Mock
+    private ReindexService reIndexService;
+    @Mock
+    private IndexSchemaService indexSchemaService;
+    @Mock
+    private AuditLogger auditLogger;
+    @InjectMocks
+    private ReindexApi sut;
+
+    @Before
+    public void setup() {
+        recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor("100").build();
+    }
+
+    @Test
+    public void should_return200_when_valid_kind_provided() throws IOException {
+        when(this.reIndexService.reindexRecords(recordReindexRequest, false)).thenReturn("something");
+
+        ResponseEntity<?> response = sut.reindex(recordReindexRequest, false);
+
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+    }
+
+    @Test(expected = AppException.class)
+    public void should_throwAppException_ifUnknownExceptionCaught_reindexTest() throws IOException {
+        when(this.reIndexService.reindexRecords(recordReindexRequest, false)).thenThrow(new AppException(500, "", ""));
+
+        sut.reindex(recordReindexRequest, false);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void should_throwAppException_ifNullPointerExceptionCaught_ReindexTest() throws IOException {
+        when(this.reIndexService.reindexRecords(recordReindexRequest, false)).thenThrow(new NullPointerException(""));
+
+        sut.reindex(recordReindexRequest, false);
+    }
+}
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/BooleanParserTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/BooleanParserTest.java
index b12673e19..98ea59355 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/BooleanParserTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/BooleanParserTest.java
@@ -1,27 +1,27 @@
-package org.opengroup.osdu.indexer.util.parser;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-@RunWith(MockitoJUnitRunner.class)
-public class BooleanParserTest {
-
-    @InjectMocks
-    private BooleanParser sut;
-
-    @Test
-    public void should_parseBoolean() {
-        assertTrue(this.sut.parseBoolean("testBooleanAttribute", "true"));
-        assertTrue(this.sut.parseBoolean("testBooleanAttribute", "TRUE"));
-
-        assertFalse(this.sut.parseBoolean("testBooleanAttribute", ""));
-        assertFalse(this.sut.parseBoolean("testBooleanAttribute", null));
-        assertFalse(this.sut.parseBoolean("testBooleanAttribute", "false"));
-        assertFalse(this.sut.parseBoolean("testBooleanAttribute", "truee"));
-    }
+package org.opengroup.osdu.indexer.util.parser;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(MockitoJUnitRunner.class)
+public class BooleanParserTest {
+
+    @InjectMocks
+    private BooleanParser sut;
+
+    @Test
+    public void should_parseBoolean() {
+        assertTrue(this.sut.parseBoolean("testBooleanAttribute", "true"));
+        assertTrue(this.sut.parseBoolean("testBooleanAttribute", "TRUE"));
+
+        assertFalse(this.sut.parseBoolean("testBooleanAttribute", ""));
+        assertFalse(this.sut.parseBoolean("testBooleanAttribute", null));
+        assertFalse(this.sut.parseBoolean("testBooleanAttribute", "false"));
+        assertFalse(this.sut.parseBoolean("testBooleanAttribute", "truee"));
+    }
 }
\ No newline at end of file
diff --git a/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/RetryPolicy.java b/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/RetryPolicy.java
index 85aaa1ee1..c3876e4a3 100644
--- a/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/RetryPolicy.java
+++ b/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/RetryPolicy.java
@@ -1,114 +1,114 @@
-//  Copyright © Microsoft Corporation
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-
-package org.opengroup.osdu.indexer.azure.service;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import io.github.resilience4j.core.IntervalFunction;
-import io.github.resilience4j.retry.RetryConfig;
-import lombok.Data;
-import lombok.extern.java.Log;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-import java.util.function.Predicate;
-
-/**
- * This class handles retry configuration logic for calls made to <prefix>/storage/v2/query/records:batch
- * to resolve intermittent CosmosDb Not found issue
- */
-
-@Log
-@Component
-@Data
-@ConfigurationProperties(prefix = "azure.storage.client.retry")
-public class RetryPolicy {
-
-    @Autowired
-    private JaxRsDpsLog logger;
-
-    private static int MAX_ATTEMPTS = 5;
-    private static int INITIAL_DELAY = 1000;
-    private final String RECORD_NOT_FOUND = "notFound";
-
-    /**
-     * @return RetryConfig with 3 attempts and 1 sec wait time
-     */
-    public RetryConfig retryConfig(Predicate<HttpResponse> predicate) {
-        return RetryConfig.<HttpResponse>custom()
-                .maxAttempts(MAX_ATTEMPTS)
-                .intervalFunction(IntervalFunction.ofExponentialBackoff(INITIAL_DELAY, 2))
-                .retryOnResult(predicate)
-                .build();
-    }
-
-    /**
-     * Unfound records get listed under a JsonArray "notFound" in the http json response
-     *
-     * @param response
-     * @return if there are elements in "notFound" returns true, else false
-     */
-    public boolean batchRetryPolicy(HttpResponse response) {
-        if (retryOnEmptyResponse(response)) return false;
-
-        if (defaultResponseRetry(response)) return true;
-
-        JsonObject jsonObject = new JsonParser().parse(response.getBody()).getAsJsonObject();
-        JsonElement notFoundElement = (JsonArray) jsonObject.get(RECORD_NOT_FOUND);
-        if (notFoundElement == null ||
-                !notFoundElement.isJsonArray() ||
-                notFoundElement.getAsJsonArray().size() == 0 ||
-                notFoundElement.getAsJsonArray().isJsonNull()) {
-            return false;
-        }
-        log.info("Storage batch API retry");
-        return true;
-    }
-
-    public boolean schemaRetryPolicy(HttpResponse response) {
-        if (retryOnEmptyResponse(response)) return false;
-
-        if (defaultResponseRetry(response)) return true;
-
-        if (response.getResponseCode() == 404) {
-            log.info("Schema API retry");
-            return true;
-        }
-
-        return false;
-    }
-
-    public boolean defaultRetryPolicy(HttpResponse response) {
-        if (retryOnEmptyResponse(response)) return false;
-
-        return defaultResponseRetry(response);
-    }
-
-    private boolean retryOnEmptyResponse(HttpResponse response) {
-        return response == null || response.getBody().isEmpty();
-    }
-
-    private boolean defaultResponseRetry(HttpResponse response) {
-        if (response.getResponseCode() <= 501) return false;
-
-        log.info(String.format("Default retry, response code: %s", response.getResponseCode()));
-        return true;
-    }
-}
+//  Copyright © Microsoft Corporation
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+
+package org.opengroup.osdu.indexer.azure.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import io.github.resilience4j.core.IntervalFunction;
+import io.github.resilience4j.retry.RetryConfig;
+import lombok.Data;
+import lombok.extern.java.Log;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.function.Predicate;
+
+/**
+ * This class handles retry configuration logic for calls made to <prefix>/storage/v2/query/records:batch
+ * to resolve intermittent CosmosDb Not found issue
+ */
+
+@Log
+@Component
+@Data
+@ConfigurationProperties(prefix = "azure.storage.client.retry")
+public class RetryPolicy {
+
+    @Autowired
+    private JaxRsDpsLog logger;
+
+    private static int MAX_ATTEMPTS = 5;
+    private static int INITIAL_DELAY = 1000;
+    private final String RECORD_NOT_FOUND = "notFound";
+
+    /**
+     * @return RetryConfig with 3 attempts and 1 sec wait time
+     */
+    public RetryConfig retryConfig(Predicate<HttpResponse> predicate) {
+        return RetryConfig.<HttpResponse>custom()
+                .maxAttempts(MAX_ATTEMPTS)
+                .intervalFunction(IntervalFunction.ofExponentialBackoff(INITIAL_DELAY, 2))
+                .retryOnResult(predicate)
+                .build();
+    }
+
+    /**
+     * Unfound records get listed under a JsonArray "notFound" in the http json response
+     *
+     * @param response
+     * @return if there are elements in "notFound" returns true, else false
+     */
+    public boolean batchRetryPolicy(HttpResponse response) {
+        if (retryOnEmptyResponse(response)) return false;
+
+        if (defaultResponseRetry(response)) return true;
+
+        JsonObject jsonObject = new JsonParser().parse(response.getBody()).getAsJsonObject();
+        JsonElement notFoundElement = (JsonArray) jsonObject.get(RECORD_NOT_FOUND);
+        if (notFoundElement == null ||
+                !notFoundElement.isJsonArray() ||
+                notFoundElement.getAsJsonArray().size() == 0 ||
+                notFoundElement.getAsJsonArray().isJsonNull()) {
+            return false;
+        }
+        log.info("Storage batch API retry");
+        return true;
+    }
+
+    public boolean schemaRetryPolicy(HttpResponse response) {
+        if (retryOnEmptyResponse(response)) return false;
+
+        if (defaultResponseRetry(response)) return true;
+
+        if (response.getResponseCode() == 404) {
+            log.info("Schema API retry");
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean defaultRetryPolicy(HttpResponse response) {
+        if (retryOnEmptyResponse(response)) return false;
+
+        return defaultResponseRetry(response);
+    }
+
+    private boolean retryOnEmptyResponse(HttpResponse response) {
+        return response == null || response.getBody().isEmpty();
+    }
+
+    private boolean defaultResponseRetry(HttpResponse response) {
+        if (response.getResponseCode() <= 501) return false;
+
+        log.info(String.format("Default retry, response code: %s", response.getResponseCode()));
+        return true;
+    }
+}
diff --git a/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImpl.java b/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImpl.java
index c0c56ccd8..91c331f25 100644
--- a/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImpl.java
+++ b/provider/indexer-azure/src/main/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImpl.java
@@ -1,98 +1,98 @@
-//  Copyright © Microsoft Corporation
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-
-package org.opengroup.osdu.indexer.azure.service;
-
-import io.github.resilience4j.retry.Retry;
-import io.github.resilience4j.retry.RetryConfig;
-import io.github.resilience4j.retry.RetryRegistry;
-import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
-import org.opengroup.osdu.core.common.http.IUrlFetchService;
-import org.opengroup.osdu.core.common.http.UrlFetchServiceImpl;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Service;
-import org.springframework.web.context.annotation.RequestScope;
-
-import java.net.URISyntaxException;
-import java.util.function.Supplier;
-
-/**
- * This class has same function as that of UrlFetchService except in the case of
- * <prefix>/storage/v2/query/records:batch call for which it enables retry
- */
-
-@Service
-@RequestScope
-@Primary
-public class UrlFetchServiceAzureImpl implements IUrlFetchService {
-
-    public static final String STORAGE_QUERY_RECORD_FOR_CONVERSION_HOST_URL = "storage/v2/query/records:batch";
-    public static final String SCHEMA_SERVICE_HOST_URL = "api/schema-service/v1/schema";
-
-    @Autowired
-    private RetryPolicy policy;
-
-    @Autowired
-    private UrlFetchServiceImpl urlFetchService;
-
-    @Autowired
-    private JaxRsDpsLog logger;
-
-    /**
-     * this method invokes retryFunction only for <prefix>/storage/v2/query/records:batch
-     * calls otherwise invokes UrlFetchService.sendRequest(FetchServiceHttpRequest request)
-     *
-     * @param httpRequest
-     * @return
-     * @throws URISyntaxException
-     */
-    @Override
-    public HttpResponse sendRequest(FetchServiceHttpRequest httpRequest) throws URISyntaxException {
-        return this.retryFunction(httpRequest);
-    }
-
-    /**
-     * decorates UrlFetchService.sendRequest(FetchServiceHttpRequest request)
-     * with retry configurations in RetryPolicy
-     *
-     * @param request
-     * @return null if URISyntaxException is caught else returns HttpResponse
-     */
-    private HttpResponse retryFunction(FetchServiceHttpRequest request) {
-        RetryConfig config;
-        if (request.getUrl().contains(STORAGE_QUERY_RECORD_FOR_CONVERSION_HOST_URL)) {
-            config = this.policy.retryConfig(response -> this.policy.batchRetryPolicy(response));
-        } else if (request.getUrl().contains(SCHEMA_SERVICE_HOST_URL)) {
-            config = this.policy.retryConfig(response -> this.policy.schemaRetryPolicy(response));
-        } else {
-            config = this.policy.retryConfig(response -> this.policy.defaultRetryPolicy(response));
-        }
-
-        RetryRegistry registry = RetryRegistry.of(config);
-        Retry retry = registry.retry("retryPolicy", config);
-
-        Supplier<HttpResponse> urlFetchServiceSupplier = () -> {
-            try {
-                return this.urlFetchService.sendRequest(request);
-            } catch (URISyntaxException e) {
-                logger.error("HttpResponse is null due to URISyntaxException. " + e.getReason());
-                return null;
-            }
-        };
-        return (urlFetchServiceSupplier == null) ? null : Retry.decorateSupplier(retry, urlFetchServiceSupplier).get();
-    }
-}
+//  Copyright © Microsoft Corporation
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+
+package org.opengroup.osdu.indexer.azure.service;
+
+import io.github.resilience4j.retry.Retry;
+import io.github.resilience4j.retry.RetryConfig;
+import io.github.resilience4j.retry.RetryRegistry;
+import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
+import org.opengroup.osdu.core.common.http.IUrlFetchService;
+import org.opengroup.osdu.core.common.http.UrlFetchServiceImpl;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.annotation.RequestScope;
+
+import java.net.URISyntaxException;
+import java.util.function.Supplier;
+
+/**
+ * This class has same function as that of UrlFetchService except in the case of
+ * <prefix>/storage/v2/query/records:batch call for which it enables retry
+ */
+
+@Service
+@RequestScope
+@Primary
+public class UrlFetchServiceAzureImpl implements IUrlFetchService {
+
+    public static final String STORAGE_QUERY_RECORD_FOR_CONVERSION_HOST_URL = "storage/v2/query/records:batch";
+    public static final String SCHEMA_SERVICE_HOST_URL = "api/schema-service/v1/schema";
+
+    @Autowired
+    private RetryPolicy policy;
+
+    @Autowired
+    private UrlFetchServiceImpl urlFetchService;
+
+    @Autowired
+    private JaxRsDpsLog logger;
+
+    /**
+     * this method invokes retryFunction only for <prefix>/storage/v2/query/records:batch
+     * calls otherwise invokes UrlFetchService.sendRequest(FetchServiceHttpRequest request)
+     *
+     * @param httpRequest
+     * @return
+     * @throws URISyntaxException
+     */
+    @Override
+    public HttpResponse sendRequest(FetchServiceHttpRequest httpRequest) throws URISyntaxException {
+        return this.retryFunction(httpRequest);
+    }
+
+    /**
+     * decorates UrlFetchService.sendRequest(FetchServiceHttpRequest request)
+     * with retry configurations in RetryPolicy
+     *
+     * @param request
+     * @return null if URISyntaxException is caught else returns HttpResponse
+     */
+    private HttpResponse retryFunction(FetchServiceHttpRequest request) {
+        RetryConfig config;
+        if (request.getUrl().contains(STORAGE_QUERY_RECORD_FOR_CONVERSION_HOST_URL)) {
+            config = this.policy.retryConfig(response -> this.policy.batchRetryPolicy(response));
+        } else if (request.getUrl().contains(SCHEMA_SERVICE_HOST_URL)) {
+            config = this.policy.retryConfig(response -> this.policy.schemaRetryPolicy(response));
+        } else {
+            config = this.policy.retryConfig(response -> this.policy.defaultRetryPolicy(response));
+        }
+
+        RetryRegistry registry = RetryRegistry.of(config);
+        Retry retry = registry.retry("retryPolicy", config);
+
+        Supplier<HttpResponse> urlFetchServiceSupplier = () -> {
+            try {
+                return this.urlFetchService.sendRequest(request);
+            } catch (URISyntaxException e) {
+                logger.error("HttpResponse is null due to URISyntaxException. " + e.getReason());
+                return null;
+            }
+        };
+        return (urlFetchServiceSupplier == null) ? null : Retry.decorateSupplier(retry, urlFetchServiceSupplier).get();
+    }
+}
diff --git a/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/RetryPolicyTest.java b/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/RetryPolicyTest.java
index a27c40932..cb891b20b 100644
--- a/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/RetryPolicyTest.java
+++ b/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/RetryPolicyTest.java
@@ -1,163 +1,163 @@
-//  Copyright © Microsoft Corporation
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-
-package org.opengroup.osdu.indexer.azure.service;
-
-import io.github.resilience4j.retry.RetryConfig;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
-import org.opengroup.osdu.core.common.http.UrlFetchServiceImpl;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-
-import java.util.function.Predicate;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RetryPolicyTest {
-
-    private static final String JSON_RESPONSE_WITH_NOT_FOUND = "{\n" +
-            "    \"records\": [\n" +
-            "        {\n" +
-            "            \"data\": {\n" +
-            "                \"Spuddate\": \"atspud\",\n" +
-            "                \"UWI\": \"atuwi\",\n" +
-            "                \"latitude\": \"latitude\",\n" +
-            "                \"longitude\": \"longitude\"\n" +
-            "            },\n" +
-            "            \"meta\": null,\n" +
-            "            \"id\": \"demo\",\n" +
-            "            \"version\": demo,\n" +
-            "            \"kind\": \"demo\",\n" +
-            "            \"acl\": {\n" +
-            "                \"viewers\": [\n" +
-            "                    \"demo\"\n" +
-            "                ],\n" +
-            "                \"owners\": [\n" +
-            "                    \"demo\"\n" +
-            "                ]\n" +
-            "            },\n" +
-            "            \"legal\": {\n" +
-            "                \"legaltags\": [\n" +
-            "                    \"opendes-test-tag\"\n" +
-            "                ],\n" +
-            "                \"otherRelevantDataCountries\": [\n" +
-            "                    \"BR\"\n" +
-            "                ],\n" +
-            "                \"status\": \"compliant\"\n" +
-            "            },\n" +
-            "            \"createUser\": \"demo\",\n" +
-            "            \"createTime\": \"demo\"\n" +
-            "        }\n" +
-            "    ],\n" +
-            "    \"notFound\": [\n" +
-            "        \"demo\"\n" +
-            "    ],\n" +
-            "    \"conversionStatuses\": []\n" +
-            "}";
-
-    private static final String JSON_RESPONSE1_WITHOUT_NOT_FOUND = "{\n" +
-            "    \"records\": [\n" +
-            "        {\n" +
-            "            \"data\": {\n" +
-            "                \"Spuddate\": \"atspud\",\n" +
-            "                \"UWI\": \"atuwi\",\n" +
-            "                \"latitude\": \"latitude\",\n" +
-            "                \"longitude\": \"longitude\"\n" +
-            "            },\n" +
-            "            \"meta\": null,\n" +
-            "            \"id\": \"demo\",\n" +
-            "            \"version\": demo,\n" +
-            "            \"kind\": \"demo\",\n" +
-            "            \"acl\": {\n" +
-            "                \"viewers\": [\n" +
-            "                    \"demo\"\n" +
-            "                ],\n" +
-            "                \"owners\": [\n" +
-            "                    \"demo\"\n" +
-            "                ]\n" +
-            "            },\n" +
-            "            \"legal\": {\n" +
-            "                \"legaltags\": [\n" +
-            "                    \"opendes-test-tag\"\n" +
-            "                ],\n" +
-            "                \"otherRelevantDataCountries\": [\n" +
-            "                    \"BR\"\n" +
-            "                ],\n" +
-            "                \"status\": \"compliant\"\n" +
-            "            },\n" +
-            "            \"createUser\": \"demo\",\n" +
-            "            \"createTime\": \"demo\"\n" +
-            "        }\n" +
-            "    ],\n" +
-            "    \"notFound\": [],\n" +
-            "    \"conversionStatuses\": []\n" +
-            "}";
-
-    private static final String JSON_RESPONSE2_WITHOUT_NOT_FOUND = "{\n" +
-            " \"records\" :[],\n" +
-            " \"conversionStatuses\":[]\n" +
-            "}";
-
-    @Mock
-    private UrlFetchServiceImpl urlFetchService;
-    @Mock
-    private FetchServiceHttpRequest httpRequest;
-    @InjectMocks
-    private HttpResponse response;
-    @InjectMocks
-    private RetryPolicy retryPolicy;
-    @Mock
-    private JaxRsDpsLog logger;
-
-
-    @Test
-    public void retry_should_be_true_for_jsonResponseWithNotFound() {
-        RetryConfig config = this.retryPolicy.retryConfig(response -> this.retryPolicy.batchRetryPolicy(response));
-        Predicate<HttpResponse> retry = config.getResultPredicate();
-        response.setBody(JSON_RESPONSE_WITH_NOT_FOUND);
-        assert retry != null;
-        boolean value = retry.test(response);
-
-        assertTrue(value);
-    }
-
-    @Test
-    public void retry_should_be_false_for_jsonResponse1WithOut_NotFound() {
-        RetryConfig config = this.retryPolicy.retryConfig(response -> this.retryPolicy.batchRetryPolicy(response));
-        Predicate<HttpResponse> retry = config.getResultPredicate();
-        response.setBody(JSON_RESPONSE1_WITHOUT_NOT_FOUND);
-        boolean value = retry.test(response);
-
-        assertFalse(value);
-    }
-
-    @Test
-    public void retry_should_be_false_for_jsonResponse2WithOut_NotFound() {
-        RetryConfig config = this.retryPolicy.retryConfig(response -> this.retryPolicy.batchRetryPolicy(response));
-        Predicate<HttpResponse> retry = config.getResultPredicate();
-        response.setBody(JSON_RESPONSE2_WITHOUT_NOT_FOUND);
-        boolean value = retry.test(response);
-
-        assertFalse(value);
-    }
-
-}
+//  Copyright © Microsoft Corporation
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+
+package org.opengroup.osdu.indexer.azure.service;
+
+import io.github.resilience4j.retry.RetryConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
+import org.opengroup.osdu.core.common.http.UrlFetchServiceImpl;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+
+import java.util.function.Predicate;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RetryPolicyTest {
+
+    private static final String JSON_RESPONSE_WITH_NOT_FOUND = "{\n" +
+            "    \"records\": [\n" +
+            "        {\n" +
+            "            \"data\": {\n" +
+            "                \"Spuddate\": \"atspud\",\n" +
+            "                \"UWI\": \"atuwi\",\n" +
+            "                \"latitude\": \"latitude\",\n" +
+            "                \"longitude\": \"longitude\"\n" +
+            "            },\n" +
+            "            \"meta\": null,\n" +
+            "            \"id\": \"demo\",\n" +
+            "            \"version\": demo,\n" +
+            "            \"kind\": \"demo\",\n" +
+            "            \"acl\": {\n" +
+            "                \"viewers\": [\n" +
+            "                    \"demo\"\n" +
+            "                ],\n" +
+            "                \"owners\": [\n" +
+            "                    \"demo\"\n" +
+            "                ]\n" +
+            "            },\n" +
+            "            \"legal\": {\n" +
+            "                \"legaltags\": [\n" +
+            "                    \"opendes-test-tag\"\n" +
+            "                ],\n" +
+            "                \"otherRelevantDataCountries\": [\n" +
+            "                    \"BR\"\n" +
+            "                ],\n" +
+            "                \"status\": \"compliant\"\n" +
+            "            },\n" +
+            "            \"createUser\": \"demo\",\n" +
+            "            \"createTime\": \"demo\"\n" +
+            "        }\n" +
+            "    ],\n" +
+            "    \"notFound\": [\n" +
+            "        \"demo\"\n" +
+            "    ],\n" +
+            "    \"conversionStatuses\": []\n" +
+            "}";
+
+    private static final String JSON_RESPONSE1_WITHOUT_NOT_FOUND = "{\n" +
+            "    \"records\": [\n" +
+            "        {\n" +
+            "            \"data\": {\n" +
+            "                \"Spuddate\": \"atspud\",\n" +
+            "                \"UWI\": \"atuwi\",\n" +
+            "                \"latitude\": \"latitude\",\n" +
+            "                \"longitude\": \"longitude\"\n" +
+            "            },\n" +
+            "            \"meta\": null,\n" +
+            "            \"id\": \"demo\",\n" +
+            "            \"version\": demo,\n" +
+            "            \"kind\": \"demo\",\n" +
+            "            \"acl\": {\n" +
+            "                \"viewers\": [\n" +
+            "                    \"demo\"\n" +
+            "                ],\n" +
+            "                \"owners\": [\n" +
+            "                    \"demo\"\n" +
+            "                ]\n" +
+            "            },\n" +
+            "            \"legal\": {\n" +
+            "                \"legaltags\": [\n" +
+            "                    \"opendes-test-tag\"\n" +
+            "                ],\n" +
+            "                \"otherRelevantDataCountries\": [\n" +
+            "                    \"BR\"\n" +
+            "                ],\n" +
+            "                \"status\": \"compliant\"\n" +
+            "            },\n" +
+            "            \"createUser\": \"demo\",\n" +
+            "            \"createTime\": \"demo\"\n" +
+            "        }\n" +
+            "    ],\n" +
+            "    \"notFound\": [],\n" +
+            "    \"conversionStatuses\": []\n" +
+            "}";
+
+    private static final String JSON_RESPONSE2_WITHOUT_NOT_FOUND = "{\n" +
+            " \"records\" :[],\n" +
+            " \"conversionStatuses\":[]\n" +
+            "}";
+
+    @Mock
+    private UrlFetchServiceImpl urlFetchService;
+    @Mock
+    private FetchServiceHttpRequest httpRequest;
+    @InjectMocks
+    private HttpResponse response;
+    @InjectMocks
+    private RetryPolicy retryPolicy;
+    @Mock
+    private JaxRsDpsLog logger;
+
+
+    @Test
+    public void retry_should_be_true_for_jsonResponseWithNotFound() {
+        RetryConfig config = this.retryPolicy.retryConfig(response -> this.retryPolicy.batchRetryPolicy(response));
+        Predicate<HttpResponse> retry = config.getResultPredicate();
+        response.setBody(JSON_RESPONSE_WITH_NOT_FOUND);
+        assert retry != null;
+        boolean value = retry.test(response);
+
+        assertTrue(value);
+    }
+
+    @Test
+    public void retry_should_be_false_for_jsonResponse1WithOut_NotFound() {
+        RetryConfig config = this.retryPolicy.retryConfig(response -> this.retryPolicy.batchRetryPolicy(response));
+        Predicate<HttpResponse> retry = config.getResultPredicate();
+        response.setBody(JSON_RESPONSE1_WITHOUT_NOT_FOUND);
+        boolean value = retry.test(response);
+
+        assertFalse(value);
+    }
+
+    @Test
+    public void retry_should_be_false_for_jsonResponse2WithOut_NotFound() {
+        RetryConfig config = this.retryPolicy.retryConfig(response -> this.retryPolicy.batchRetryPolicy(response));
+        Predicate<HttpResponse> retry = config.getResultPredicate();
+        response.setBody(JSON_RESPONSE2_WITHOUT_NOT_FOUND);
+        boolean value = retry.test(response);
+
+        assertFalse(value);
+    }
+
+}
diff --git a/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImplTest.java b/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImplTest.java
index 18adccbfe..255619afc 100644
--- a/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImplTest.java
+++ b/provider/indexer-azure/src/test/java/org/opengroup/osdu/indexer/azure/service/UrlFetchServiceAzureImplTest.java
@@ -1,131 +1,131 @@
-//  Copyright © Microsoft Corporation
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-
-package org.opengroup.osdu.indexer.azure.service;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
-import org.opengroup.osdu.core.common.http.UrlFetchServiceImpl;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
-
-@RunWith(MockitoJUnitRunner.class)
-public class UrlFetchServiceAzureImplTest {
-
-    @Mock
-    private JaxRsDpsLog logger;
-    @Mock
-    private UrlFetchServiceImpl urlFetchService;
-    @InjectMocks
-    private FetchServiceHttpRequest httpRequest;
-    @InjectMocks
-    private HttpResponse response;
-    @Mock
-    private RetryPolicy retryPolicy;
-    @InjectMocks
-    private UrlFetchServiceAzureImpl urlFetchServiceAzure;
-
-    private static final String JSON1 = "{\n" +
-            "    \"records\": [\n" +
-            "        {\n" +
-            "            \"data\": {\n" +
-            "                \"Spuddate\": \"atspud\",\n" +
-            "                \"UWI\": \"atuwi\",\n" +
-            "                \"latitude\": \"latitude\",\n" +
-            "                \"longitude\": \"longitude\"\n" +
-            "            },\n" +
-            "            \"meta\": null,\n" +
-            "            \"id\": \"demo\",\n" +
-            "            \"version\": demo,\n" +
-            "            \"kind\": \"demo\",\n" +
-            "            \"acl\": {\n" +
-            "                \"viewers\": [\n" +
-            "                    \"demo\"\n" +
-            "                ],\n" +
-            "                \"owners\": [\n" +
-            "                    \"demo\"\n" +
-            "                ]\n" +
-            "            },\n" +
-            "            \"legal\": {\n" +
-            "                \"legaltags\": [\n" +
-            "                    \"opendes-test-tag\"\n" +
-            "                ],\n" +
-            "                \"otherRelevantDataCountries\": [\n" +
-            "                    \"BR\"\n" +
-            "                ],\n" +
-            "                \"status\": \"compliant\"\n" +
-            "            },\n" +
-            "            \"createUser\": \"demo\",\n" +
-            "            \"createTime\": \"demo\"\n" +
-            "        }\n" +
-            "    ],\n" +
-            "    \"notFound\": [\n" +
-            "        \"demo\"\n" +
-            "    ],\n" +
-            "    \"conversionStatuses\": []\n" +
-            "}";
-
-    private static final String JSON2 = "{\n" +
-            " \"records\" :[],\n" +
-            " \"conversionStatuses\":[]\n" +
-            "}";
-
-    private static final String BATCH_API_URL = "https://demo/api/storage/v2/query/records:batch";
-    private static final String STORAGE_API_URL = "https://demo/api/storage/v2/schemas";
-    private static final String SCHEMA_API_URL = "https://demo/api/schema-service/v1/schema/osdu:file:gom:1.0.0";
-
-    @Test
-    public void shouldRetry_ForJSON1_when_storageQueryRecordCallIsMade() throws Exception {
-        response.setBody(JSON1);
-        httpRequest.setUrl(BATCH_API_URL);
-        when(this.retryPolicy.retryConfig(any())).thenReturn(new RetryPolicy().retryConfig(response -> this.retryPolicy.batchRetryPolicy(response)));
-        when(urlFetchService.sendRequest(httpRequest)).thenReturn(response);
-
-        urlFetchServiceAzure.sendRequest(httpRequest);
-
-        verify(urlFetchService, atMost(4)).sendRequest(httpRequest);
-    }
-
-    @Test
-    public void shouldRetry_ForJSON1_when_schemaRecordCallIsMade() throws Exception {
-        response.setBody(JSON1);
-        httpRequest.setUrl(SCHEMA_API_URL);
-        when(this.retryPolicy.retryConfig(any())).thenReturn(new RetryPolicy().retryConfig(response -> this.retryPolicy.schemaRetryPolicy(response)));
-        when(urlFetchService.sendRequest(httpRequest)).thenReturn(response);
-
-        urlFetchServiceAzure.sendRequest(httpRequest);
-
-        verify(urlFetchService, atMost(4)).sendRequest(httpRequest);
-    }
-
-    @Test
-    public void shouldRetry_when_anyOtherCallIsMade() throws Exception {
-        response.setBody(JSON2);
-        httpRequest.setUrl(STORAGE_API_URL);
-        when(this.retryPolicy.retryConfig(any())).thenReturn(new RetryPolicy().retryConfig(response -> this.retryPolicy.defaultRetryPolicy(response)));
-        when(urlFetchService.sendRequest(httpRequest)).thenReturn(response);
-
-        urlFetchServiceAzure.sendRequest(httpRequest);
-
-        verify(urlFetchService, atMost(4)).sendRequest(httpRequest);
-    }
-}
+//  Copyright © Microsoft Corporation
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+
+package org.opengroup.osdu.indexer.azure.service;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opengroup.osdu.core.common.http.FetchServiceHttpRequest;
+import org.opengroup.osdu.core.common.http.UrlFetchServiceImpl;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public class UrlFetchServiceAzureImplTest {
+
+    @Mock
+    private JaxRsDpsLog logger;
+    @Mock
+    private UrlFetchServiceImpl urlFetchService;
+    @InjectMocks
+    private FetchServiceHttpRequest httpRequest;
+    @InjectMocks
+    private HttpResponse response;
+    @Mock
+    private RetryPolicy retryPolicy;
+    @InjectMocks
+    private UrlFetchServiceAzureImpl urlFetchServiceAzure;
+
+    private static final String JSON1 = "{\n" +
+            "    \"records\": [\n" +
+            "        {\n" +
+            "            \"data\": {\n" +
+            "                \"Spuddate\": \"atspud\",\n" +
+            "                \"UWI\": \"atuwi\",\n" +
+            "                \"latitude\": \"latitude\",\n" +
+            "                \"longitude\": \"longitude\"\n" +
+            "            },\n" +
+            "            \"meta\": null,\n" +
+            "            \"id\": \"demo\",\n" +
+            "            \"version\": demo,\n" +
+            "            \"kind\": \"demo\",\n" +
+            "            \"acl\": {\n" +
+            "                \"viewers\": [\n" +
+            "                    \"demo\"\n" +
+            "                ],\n" +
+            "                \"owners\": [\n" +
+            "                    \"demo\"\n" +
+            "                ]\n" +
+            "            },\n" +
+            "            \"legal\": {\n" +
+            "                \"legaltags\": [\n" +
+            "                    \"opendes-test-tag\"\n" +
+            "                ],\n" +
+            "                \"otherRelevantDataCountries\": [\n" +
+            "                    \"BR\"\n" +
+            "                ],\n" +
+            "                \"status\": \"compliant\"\n" +
+            "            },\n" +
+            "            \"createUser\": \"demo\",\n" +
+            "            \"createTime\": \"demo\"\n" +
+            "        }\n" +
+            "    ],\n" +
+            "    \"notFound\": [\n" +
+            "        \"demo\"\n" +
+            "    ],\n" +
+            "    \"conversionStatuses\": []\n" +
+            "}";
+
+    private static final String JSON2 = "{\n" +
+            " \"records\" :[],\n" +
+            " \"conversionStatuses\":[]\n" +
+            "}";
+
+    private static final String BATCH_API_URL = "https://demo/api/storage/v2/query/records:batch";
+    private static final String STORAGE_API_URL = "https://demo/api/storage/v2/schemas";
+    private static final String SCHEMA_API_URL = "https://demo/api/schema-service/v1/schema/osdu:file:gom:1.0.0";
+
+    @Test
+    public void shouldRetry_ForJSON1_when_storageQueryRecordCallIsMade() throws Exception {
+        response.setBody(JSON1);
+        httpRequest.setUrl(BATCH_API_URL);
+        when(this.retryPolicy.retryConfig(any())).thenReturn(new RetryPolicy().retryConfig(response -> this.retryPolicy.batchRetryPolicy(response)));
+        when(urlFetchService.sendRequest(httpRequest)).thenReturn(response);
+
+        urlFetchServiceAzure.sendRequest(httpRequest);
+
+        verify(urlFetchService, atMost(4)).sendRequest(httpRequest);
+    }
+
+    @Test
+    public void shouldRetry_ForJSON1_when_schemaRecordCallIsMade() throws Exception {
+        response.setBody(JSON1);
+        httpRequest.setUrl(SCHEMA_API_URL);
+        when(this.retryPolicy.retryConfig(any())).thenReturn(new RetryPolicy().retryConfig(response -> this.retryPolicy.schemaRetryPolicy(response)));
+        when(urlFetchService.sendRequest(httpRequest)).thenReturn(response);
+
+        urlFetchServiceAzure.sendRequest(httpRequest);
+
+        verify(urlFetchService, atMost(4)).sendRequest(httpRequest);
+    }
+
+    @Test
+    public void shouldRetry_when_anyOtherCallIsMade() throws Exception {
+        response.setBody(JSON2);
+        httpRequest.setUrl(STORAGE_API_URL);
+        when(this.retryPolicy.retryConfig(any())).thenReturn(new RetryPolicy().retryConfig(response -> this.retryPolicy.defaultRetryPolicy(response)));
+        when(urlFetchService.sendRequest(httpRequest)).thenReturn(response);
+
+        urlFetchServiceAzure.sendRequest(httpRequest);
+
+        verify(urlFetchService, atMost(4)).sendRequest(httpRequest);
+    }
+}
diff --git a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/middleware/IndexFilterTest.java b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/middleware/IndexFilterTest.java
index 50ff8d892..bd698e00c 100644
--- a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/middleware/IndexFilterTest.java
+++ b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/middleware/IndexFilterTest.java
@@ -1,53 +1,53 @@
-package org.opengroup.osdu.indexer.middleware;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.io.IOException;
-import java.util.Collections;
-
-@RunWith(MockitoJUnitRunner.class)
-public class IndexFilterTest {
-
-    @InjectMocks
-    private IndexFilter indexFilter;
-
-    @Mock
-    private DpsHeaders dpsHeaders;
-
-    @Test
-    public void shouldSetCorrectResponseHeaders() throws IOException, ServletException {
-        HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
-        HttpServletResponse httpServletResponse = Mockito.mock(HttpServletResponse.class);
-        FilterChain filterChain = Mockito.mock(FilterChain.class);
-        Mockito.when(httpServletRequest.getRequestURI()).thenReturn("https://test.com");
-        Mockito.when(httpServletRequest.getMethod()).thenReturn("POST");
-        Mockito.when(dpsHeaders.getCorrelationId()).thenReturn("correlation-id-value");
-
-        indexFilter.doFilter(httpServletRequest, httpServletResponse, filterChain);
-
-        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Origin", Collections.singletonList("*").toString());
-        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Headers", Collections.singletonList("origin, content-type, accept, authorization, data-partition-id, correlation-id, appkey").toString());
-        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Methods", Collections.singletonList("GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH").toString());
-        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Credentials", Collections.singletonList("true").toString());
-        Mockito.verify(httpServletResponse).addHeader("X-Frame-Options", Collections.singletonList("DENY").toString());
-        Mockito.verify(httpServletResponse).addHeader("X-XSS-Protection", Collections.singletonList("1; mode=block").toString());
-        Mockito.verify(httpServletResponse).addHeader("X-Content-Type-Options", Collections.singletonList("nosniff").toString());
-        Mockito.verify(httpServletResponse).addHeader("Cache-Control", Collections.singletonList("no-cache, no-store, must-revalidate").toString());
-        Mockito.verify(httpServletResponse).addHeader("Content-Security-Policy", Collections.singletonList("default-src 'self'").toString());
-        Mockito.verify(httpServletResponse).addHeader("Strict-Transport-Security", Collections.singletonList("max-age=31536000; includeSubDomains").toString());
-        Mockito.verify(httpServletResponse).addHeader("Expires", Collections.singletonList("0").toString());
-        Mockito.verify(httpServletResponse).addHeader("correlation-id", "correlation-id-value");
-        Mockito.verify(filterChain).doFilter(httpServletRequest, httpServletResponse);
-    }
-}
+package org.opengroup.osdu.indexer.middleware;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+import java.util.Collections;
+
+@RunWith(MockitoJUnitRunner.class)
+public class IndexFilterTest {
+
+    @InjectMocks
+    private IndexFilter indexFilter;
+
+    @Mock
+    private DpsHeaders dpsHeaders;
+
+    @Test
+    public void shouldSetCorrectResponseHeaders() throws IOException, ServletException {
+        HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse httpServletResponse = Mockito.mock(HttpServletResponse.class);
+        FilterChain filterChain = Mockito.mock(FilterChain.class);
+        Mockito.when(httpServletRequest.getRequestURI()).thenReturn("https://test.com");
+        Mockito.when(httpServletRequest.getMethod()).thenReturn("POST");
+        Mockito.when(dpsHeaders.getCorrelationId()).thenReturn("correlation-id-value");
+
+        indexFilter.doFilter(httpServletRequest, httpServletResponse, filterChain);
+
+        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Origin", Collections.singletonList("*").toString());
+        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Headers", Collections.singletonList("origin, content-type, accept, authorization, data-partition-id, correlation-id, appkey").toString());
+        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Methods", Collections.singletonList("GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH").toString());
+        Mockito.verify(httpServletResponse).addHeader("Access-Control-Allow-Credentials", Collections.singletonList("true").toString());
+        Mockito.verify(httpServletResponse).addHeader("X-Frame-Options", Collections.singletonList("DENY").toString());
+        Mockito.verify(httpServletResponse).addHeader("X-XSS-Protection", Collections.singletonList("1; mode=block").toString());
+        Mockito.verify(httpServletResponse).addHeader("X-Content-Type-Options", Collections.singletonList("nosniff").toString());
+        Mockito.verify(httpServletResponse).addHeader("Cache-Control", Collections.singletonList("no-cache, no-store, must-revalidate").toString());
+        Mockito.verify(httpServletResponse).addHeader("Content-Security-Policy", Collections.singletonList("default-src 'self'").toString());
+        Mockito.verify(httpServletResponse).addHeader("Strict-Transport-Security", Collections.singletonList("max-age=31536000; includeSubDomains").toString());
+        Mockito.verify(httpServletResponse).addHeader("Expires", Collections.singletonList("0").toString());
+        Mockito.verify(httpServletResponse).addHeader("correlation-id", "correlation-id-value");
+        Mockito.verify(filterChain).doFilter(httpServletRequest, httpServletResponse);
+    }
+}
diff --git a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java
index f8debf207..87dea8ec4 100644
--- a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java
+++ b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/IndexerMappingServiceTest.java
@@ -1,303 +1,303 @@
-package org.opengroup.osdu.indexer.service;
-
-import org.apache.http.StatusLine;
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
-import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
-import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
-import org.elasticsearch.action.bulk.BulkItemResponse.Failure;
-import org.elasticsearch.action.support.master.AcknowledgedResponse;
-import org.elasticsearch.client.*;
-import org.elasticsearch.common.bytes.BytesReference;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.index.reindex.BulkByScrollResponse;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
-import org.opengroup.osdu.indexer.service.IndexerMappingServiceImpl;
-import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.indexer.util.ElasticClientHandler;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.io.IOException;
-import java.util.*;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-@Ignore
-@RunWith(SpringRunner.class)
-@PrepareForTest({ RestHighLevelClient.class, IndicesClient.class })
-public class IndexerMappingServiceTest {
-
-	private final String kind = "tenant:test:test:1.0.0";
-	private final String index = "tenant-test-test-1.0.0";
-	private final String type = "test";
-	private final String mappingValid = "{\"dynamic\":false,\"properties\":{\"data\":{\"properties\":{\"Location\":{\"type\":\"geo_point\"}}},\"id\":{\"type\":\"keyword\"}}}";
-
-	@Mock
-	private RestClient restClient;
-	@Mock
-	private Response response;
-	@Mock
-	private StatusLine statusLine;
-
-	@InjectMocks
-	private IndexerMappingServiceImpl sut;
-
-	@Mock
-	private ElasticClientHandler elasticClientHandler;
-
-	@InjectMocks
-	private RestHighLevelClient restHighLevelClient;
-
-	@InjectMocks
-	private IndexSchema indexSchema;
-	@InjectMocks
-	private IndicesClient indicesClient;
-
-	@InjectMocks
-	private AcknowledgedResponse mappingResponse;
-
-	@Before
-	public void setup() throws IOException {
-		Map<String, Object> dataMapping = new HashMap<>();
-		dataMapping.put("Location", "geo_point");
-		Map<String, Object> metaMapping = new HashMap<>();
-		metaMapping.put(RecordMetaAttribute.ID.getValue(), "keyword");
-		this.indexSchema = IndexSchema.builder().kind(kind).type(type).dataSchema(dataMapping).metaSchema(metaMapping)
-				.build();
-
-		this.indicesClient = PowerMockito.mock(IndicesClient.class);
-		this.restHighLevelClient = PowerMockito.mock(RestHighLevelClient.class);
-
-		when(this.restHighLevelClient.getLowLevelClient()).thenReturn(restClient);
-		when(this.restClient.performRequest(ArgumentMatchers.any())).thenReturn(response);
-		when(this.response.getStatusLine()).thenReturn(statusLine);
-		when(this.statusLine.getStatusCode()).thenReturn(200);
-	}
-
-	@Test
-	public void should_returnValidMapping_givenFalseMerge_createMappingTest() {
-		try {
-			String mapping = this.sut.createMapping(restHighLevelClient, indexSchema, index, false);
-			assertEquals(mappingValid, mapping);
-		} catch (Exception e) {
-			fail("Should not throw this exception" + e.getMessage());
-		}
-	}
-
-	@Test
-	public void should_returnValidMapping_givenTrueMerge_createMappingTest() {
-		try {
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-
-			String mapping = this.sut.createMapping(this.restHighLevelClient, this.indexSchema, this.index, true);
-			assertEquals(this.mappingValid, mapping);
-		} catch (Exception e) {
-			fail("Should not throw this exception" + e.getMessage());
-		}
-	}
-
-	@Test
-	public void should_returnValidMapping_givenExistType_createMappingTest() {
-		try {
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-
-			IndexerMappingServiceImpl indexerMappingServiceLocal = PowerMockito.spy(new IndexerMappingServiceImpl());
-			doReturn(false).when(indexerMappingServiceLocal).isTypeExist(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any());
-			String mapping = this.sut.createMapping(this.restHighLevelClient, this.indexSchema, this.index, true);
-			assertEquals(this.mappingValid, mapping);
-		} catch (Exception e) {
-			fail("Should not throw this exception" + e.getMessage());
-		}
-	}
-
-	@Test
-	public void should_update_indices_field_with_keyword_when_valid_indices() throws Exception {
-		try {
-			Set<String> indices = new HashSet<String>();
-			indices.add("indices 1");
-			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
-			XContentBuilder builder = XContentFactory.jsonBuilder();
-			builder.startObject();
-			builder.field("any field", new HashMap());
-			builder.endObject();
-			BytesReference bytesReference = BytesReference.bytes(builder);
-			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
-			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
-			mapBuilder.put("data.any field", mappingMetaData);
-			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
-			mappingBuilder.put("any index 1", mapBuilder);
-			mappingBuilder.put("any index 2", mapBuilder);
-			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
-			mapping.put("indices 1", mappingBuilder);
-			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
-			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
-			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
-			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
-
-			this.sut.updateIndexMappingForIndicesOfSameType( indices,"any field");
-		} catch (Exception e) {
-			fail("Should not throw this exception" + e.getMessage());
-		}
-	}
-
-	@Test(expected = AppException.class)
-	public void should_throw_exception_if_someIndex_is_invalid_andWeIndexfield_with_keyword() throws Exception {
-		try {
-			Set<String> indices = new HashSet<String>();
-			indices.add("invalid 1");
-			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
-			XContentBuilder builder = XContentFactory.jsonBuilder();
-			builder.startObject();
-			builder.field("any field", new HashMap());
-			builder.endObject();
-			BytesReference bytesReference = BytesReference.bytes(builder);
-			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
-			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
-			mapBuilder.put("data.any field", mappingMetaData);
-			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
-			mappingBuilder.put("any index 1", mapBuilder);
-			mappingBuilder.put("any index 2", mapBuilder);
-			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
-			mapping.put("indices 1", mappingBuilder);
-			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
-			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
-			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
-			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
-
-			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field");
-		} catch (Exception e) {
-			throw e;
-		}
-	}
-
-	@Test(expected = AppException.class)
-	public void should_throw_exception_if_type_of_index_is_invalid_andWeIndexfield_with_keyword() throws Exception {
-		try {
-			Set<String> indices = new HashSet<String>();
-			indices.add("indices 1");
-			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
-			XContentBuilder builder = XContentFactory.jsonBuilder();
-			builder.startObject();
-			builder.field("any field", new HashMap());
-			builder.endObject();
-			BytesReference bytesReference = BytesReference.bytes(builder);
-			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
-			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
-			mapBuilder.put("data.any field", mappingMetaData);
-			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
-			mappingBuilder.put("any index 1", mapBuilder);
-			mappingBuilder.put("any index 2", mapBuilder);
-			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
-			mapping.put("indices 1", mappingBuilder);
-			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
-			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
-			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
-			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
-			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field invalid");
-		} catch (Exception e) {
-			throw e;
-		}
-	}
-
-	@Test(expected = AppException.class)
-	public void should_throw_exception_if_elastic_search_failedToFetch_andWeIndexfield_with_keyword() throws Exception {
-		try {
-
-			Set<String> indices = new HashSet<String>();
-			indices.add("indices 1");
-			indices.add("indices Invalid");
-			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenThrow(new ElasticsearchException(""));
-			XContentBuilder builder = XContentFactory.jsonBuilder();
-			builder.startObject();
-			builder.field("any field", new HashMap());
-			builder.endObject();
-			BytesReference bytesReference = BytesReference.bytes(builder);
-			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
-			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
-			mapBuilder.put("data.any field", mappingMetaData);
-			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
-			mappingBuilder.put("any index 1", mapBuilder);
-			mappingBuilder.put("any index 2", mapBuilder);
-			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
-			mapping.put("indices 1", mappingBuilder);
-			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
-			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
-			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
-			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
-			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field");
-		} catch (AppException e) {
-			throw e;
-		}
-	}
-
-	@Test(expected = AppException.class)
-	public void should_throw_exception_when_elastic_failedToIndex_indices_field_with_keyword() {
-		try {
-			Set<String> indices = new HashSet<String>();
-			indices.add("indices 1");
-			indices.add("indices Invalid");
-			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
-			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
-			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
-			XContentBuilder builder = XContentFactory.jsonBuilder();
-			builder.startObject();
-			builder.field("any field", new HashMap());
-			builder.endObject();
-			BytesReference bytesReference = BytesReference.bytes(builder);
-			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
-			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
-			mapBuilder.put("data.any field", mappingMetaData);
-			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
-			mappingBuilder.put("any index 1", mapBuilder);
-			mappingBuilder.put("any index 2", mapBuilder);
-			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
-			mapping.put("indices 1", mappingBuilder);
-			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
-			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
-			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
-			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
-			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
-			when(this.indicesClient.putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class))).thenThrow(new ElasticsearchException(""));
-			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
-			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field");
-		} catch (AppException e) {
-			throw e;
-		} catch (Exception e) {
-			fail("Should not throw this exception" + e.getMessage());
-		}
-	}
-}
+package org.opengroup.osdu.indexer.service;
+
+import org.apache.http.StatusLine;
+import org.elasticsearch.ElasticsearchException;
+import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
+import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
+import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
+import org.elasticsearch.action.bulk.BulkItemResponse.Failure;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.client.*;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.index.reindex.BulkByScrollResponse;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.opengroup.osdu.core.common.model.indexer.IndexSchema;
+import org.opengroup.osdu.indexer.service.IndexerMappingServiceImpl;
+import org.opengroup.osdu.core.common.model.search.RecordMetaAttribute;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.indexer.util.ElasticClientHandler;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@Ignore
+@RunWith(SpringRunner.class)
+@PrepareForTest({ RestHighLevelClient.class, IndicesClient.class })
+public class IndexerMappingServiceTest {
+
+	private final String kind = "tenant:test:test:1.0.0";
+	private final String index = "tenant-test-test-1.0.0";
+	private final String type = "test";
+	private final String mappingValid = "{\"dynamic\":false,\"properties\":{\"data\":{\"properties\":{\"Location\":{\"type\":\"geo_point\"}}},\"id\":{\"type\":\"keyword\"}}}";
+
+	@Mock
+	private RestClient restClient;
+	@Mock
+	private Response response;
+	@Mock
+	private StatusLine statusLine;
+
+	@InjectMocks
+	private IndexerMappingServiceImpl sut;
+
+	@Mock
+	private ElasticClientHandler elasticClientHandler;
+
+	@InjectMocks
+	private RestHighLevelClient restHighLevelClient;
+
+	@InjectMocks
+	private IndexSchema indexSchema;
+	@InjectMocks
+	private IndicesClient indicesClient;
+
+	@InjectMocks
+	private AcknowledgedResponse mappingResponse;
+
+	@Before
+	public void setup() throws IOException {
+		Map<String, Object> dataMapping = new HashMap<>();
+		dataMapping.put("Location", "geo_point");
+		Map<String, Object> metaMapping = new HashMap<>();
+		metaMapping.put(RecordMetaAttribute.ID.getValue(), "keyword");
+		this.indexSchema = IndexSchema.builder().kind(kind).type(type).dataSchema(dataMapping).metaSchema(metaMapping)
+				.build();
+
+		this.indicesClient = PowerMockito.mock(IndicesClient.class);
+		this.restHighLevelClient = PowerMockito.mock(RestHighLevelClient.class);
+
+		when(this.restHighLevelClient.getLowLevelClient()).thenReturn(restClient);
+		when(this.restClient.performRequest(ArgumentMatchers.any())).thenReturn(response);
+		when(this.response.getStatusLine()).thenReturn(statusLine);
+		when(this.statusLine.getStatusCode()).thenReturn(200);
+	}
+
+	@Test
+	public void should_returnValidMapping_givenFalseMerge_createMappingTest() {
+		try {
+			String mapping = this.sut.createMapping(restHighLevelClient, indexSchema, index, false);
+			assertEquals(mappingValid, mapping);
+		} catch (Exception e) {
+			fail("Should not throw this exception" + e.getMessage());
+		}
+	}
+
+	@Test
+	public void should_returnValidMapping_givenTrueMerge_createMappingTest() {
+		try {
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+
+			String mapping = this.sut.createMapping(this.restHighLevelClient, this.indexSchema, this.index, true);
+			assertEquals(this.mappingValid, mapping);
+		} catch (Exception e) {
+			fail("Should not throw this exception" + e.getMessage());
+		}
+	}
+
+	@Test
+	public void should_returnValidMapping_givenExistType_createMappingTest() {
+		try {
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+
+			IndexerMappingServiceImpl indexerMappingServiceLocal = PowerMockito.spy(new IndexerMappingServiceImpl());
+			doReturn(false).when(indexerMappingServiceLocal).isTypeExist(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any());
+			String mapping = this.sut.createMapping(this.restHighLevelClient, this.indexSchema, this.index, true);
+			assertEquals(this.mappingValid, mapping);
+		} catch (Exception e) {
+			fail("Should not throw this exception" + e.getMessage());
+		}
+	}
+
+	@Test
+	public void should_update_indices_field_with_keyword_when_valid_indices() throws Exception {
+		try {
+			Set<String> indices = new HashSet<String>();
+			indices.add("indices 1");
+			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
+			XContentBuilder builder = XContentFactory.jsonBuilder();
+			builder.startObject();
+			builder.field("any field", new HashMap());
+			builder.endObject();
+			BytesReference bytesReference = BytesReference.bytes(builder);
+			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
+			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
+			mapBuilder.put("data.any field", mappingMetaData);
+			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
+			mappingBuilder.put("any index 1", mapBuilder);
+			mappingBuilder.put("any index 2", mapBuilder);
+			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
+			mapping.put("indices 1", mappingBuilder);
+			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
+			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
+			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
+			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
+
+			this.sut.updateIndexMappingForIndicesOfSameType( indices,"any field");
+		} catch (Exception e) {
+			fail("Should not throw this exception" + e.getMessage());
+		}
+	}
+
+	@Test(expected = AppException.class)
+	public void should_throw_exception_if_someIndex_is_invalid_andWeIndexfield_with_keyword() throws Exception {
+		try {
+			Set<String> indices = new HashSet<String>();
+			indices.add("invalid 1");
+			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
+			XContentBuilder builder = XContentFactory.jsonBuilder();
+			builder.startObject();
+			builder.field("any field", new HashMap());
+			builder.endObject();
+			BytesReference bytesReference = BytesReference.bytes(builder);
+			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
+			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
+			mapBuilder.put("data.any field", mappingMetaData);
+			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
+			mappingBuilder.put("any index 1", mapBuilder);
+			mappingBuilder.put("any index 2", mapBuilder);
+			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
+			mapping.put("indices 1", mappingBuilder);
+			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
+			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
+			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
+			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
+
+			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field");
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	@Test(expected = AppException.class)
+	public void should_throw_exception_if_type_of_index_is_invalid_andWeIndexfield_with_keyword() throws Exception {
+		try {
+			Set<String> indices = new HashSet<String>();
+			indices.add("indices 1");
+			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
+			XContentBuilder builder = XContentFactory.jsonBuilder();
+			builder.startObject();
+			builder.field("any field", new HashMap());
+			builder.endObject();
+			BytesReference bytesReference = BytesReference.bytes(builder);
+			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
+			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
+			mapBuilder.put("data.any field", mappingMetaData);
+			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
+			mappingBuilder.put("any index 1", mapBuilder);
+			mappingBuilder.put("any index 2", mapBuilder);
+			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
+			mapping.put("indices 1", mappingBuilder);
+			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
+			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
+			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
+			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
+			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field invalid");
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	@Test(expected = AppException.class)
+	public void should_throw_exception_if_elastic_search_failedToFetch_andWeIndexfield_with_keyword() throws Exception {
+		try {
+
+			Set<String> indices = new HashSet<String>();
+			indices.add("indices 1");
+			indices.add("indices Invalid");
+			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenThrow(new ElasticsearchException(""));
+			XContentBuilder builder = XContentFactory.jsonBuilder();
+			builder.startObject();
+			builder.field("any field", new HashMap());
+			builder.endObject();
+			BytesReference bytesReference = BytesReference.bytes(builder);
+			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
+			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
+			mapBuilder.put("data.any field", mappingMetaData);
+			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
+			mappingBuilder.put("any index 1", mapBuilder);
+			mappingBuilder.put("any index 2", mapBuilder);
+			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
+			mapping.put("indices 1", mappingBuilder);
+			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
+			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
+			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
+			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
+			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field");
+		} catch (AppException e) {
+			throw e;
+		}
+	}
+
+	@Test(expected = AppException.class)
+	public void should_throw_exception_when_elastic_failedToIndex_indices_field_with_keyword() {
+		try {
+			Set<String> indices = new HashSet<String>();
+			indices.add("indices 1");
+			indices.add("indices Invalid");
+			GetFieldMappingsResponse getFieldMappingsResponse = mock(GetFieldMappingsResponse.class);
+			doReturn(this.indicesClient).when(this.restHighLevelClient).indices();
+			when(this.indicesClient.getFieldMapping(ArgumentMatchers.any(GetFieldMappingsRequest.class), ArgumentMatchers.any())).thenReturn(getFieldMappingsResponse);
+			XContentBuilder builder = XContentFactory.jsonBuilder();
+			builder.startObject();
+			builder.field("any field", new HashMap());
+			builder.endObject();
+			BytesReference bytesReference = BytesReference.bytes(builder);
+			GetFieldMappingsResponse.FieldMappingMetadata mappingMetaData = new GetFieldMappingsResponse.FieldMappingMetadata(index, bytesReference);
+			Map<String, GetFieldMappingsResponse.FieldMappingMetadata> mapBuilder = new HashMap<>();
+			mapBuilder.put("data.any field", mappingMetaData);
+			Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>> mappingBuilder = new HashMap<>();
+			mappingBuilder.put("any index 1", mapBuilder);
+			mappingBuilder.put("any index 2", mapBuilder);
+			Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetadata>>> mapping = new HashMap<>();
+			mapping.put("indices 1", mappingBuilder);
+			when(getFieldMappingsResponse.mappings()).thenReturn(mapping);
+			doReturn(mappingResponse).when(this.indicesClient).putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class));
+			BulkByScrollResponse response = mock(BulkByScrollResponse.class);
+			doReturn(response).when(this.restHighLevelClient).updateByQuery(ArgumentMatchers.any(), ArgumentMatchers.any(RequestOptions.class));
+			when(response.getBulkFailures()).thenReturn(new ArrayList<Failure>());
+			when(this.indicesClient.putMapping(ArgumentMatchers.any(PutMappingRequest.class), ArgumentMatchers.any(RequestOptions.class))).thenThrow(new ElasticsearchException(""));
+			when(elasticClientHandler.createRestClient()).thenReturn(restHighLevelClient);
+			this.sut.updateIndexMappingForIndicesOfSameType(indices,"any field");
+		} catch (AppException e) {
+			throw e;
+		} catch (Exception e) {
+			fail("Should not throw this exception" + e.getMessage());
+		}
+	}
+}
diff --git a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/ReindexServiceTest.java b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/ReindexServiceTest.java
index 4ba73dacf..403199cb3 100644
--- a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/ReindexServiceTest.java
+++ b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/ReindexServiceTest.java
@@ -1,150 +1,150 @@
-// 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.service;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
-import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
-import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.*;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.MockitoAnnotations.initMocks;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(SpringRunner.class)
-public class ReindexServiceTest {
-
-    private final String cursor = "100";
-
-    private final String correlationId = UUID.randomUUID().toString();
-
-    @Mock
-    private IndexerConfigurationProperties configurationProperties;
-    @Mock
-    private StorageService storageService;
-    @Mock
-    private IRequestInfo requestInfo;
-    @Mock
-    private IndexerQueueTaskBuilder indexerQueueTaskBuilder;
-    @Mock
-    private JaxRsDpsLog log;
-    @InjectMocks
-    private ReindexServiceImpl sut;
-
-    private RecordReindexRequest recordReindexRequest;
-    private RecordQueryResponse recordQueryResponse;
-
-    private Map<String, String> httpHeaders;
-
-    @Before
-    public void setup() {
-        initMocks(this);
-
-        mockStatic(UUID.class);
-
-        recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor(cursor).build();
-        recordQueryResponse = new RecordQueryResponse();
-
-        httpHeaders = new HashMap<>();
-        httpHeaders.put(DpsHeaders.AUTHORIZATION, "testAuth");
-        httpHeaders.put(DpsHeaders.CORRELATION_ID, correlationId);
-        DpsHeaders standardHeaders = DpsHeaders.createFromMap(httpHeaders);
-        when(requestInfo.getHeaders()).thenReturn(standardHeaders);
-        when(requestInfo.getHeadersMapWithDwdAuthZ()).thenReturn(httpHeaders);
-        when(requestInfo.getHeadersWithDwdAuthZ()).thenReturn(standardHeaders);
-    }
-
-    @Test
-    public void should_returnNull_givenNullResponseResult_reIndexRecordsTest() {
-        try {
-            recordQueryResponse.setResults(null);
-            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
-
-            String response = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertNull(response);
-        } catch (Exception e) {
-            fail("Should not throw this exception" + e.getMessage());
-        }
-    }
-
-    @Test
-    public void should_returnNull_givenEmptyResponseResult_reIndexRecordsTest() {
-        try {
-            recordQueryResponse.setResults(new ArrayList<>());
-            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
-
-            String response = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertNull(response);
-        } catch (Exception e) {
-            fail("Should not throw this exception" + e.getMessage());
-        }
-    }
-    @Ignore
-    @Test
-    public void should_returnRecordQueryRequestPayload_givenValidResponseResult_reIndexRecordsTest() {
-        try {
-            recordQueryResponse.setCursor(cursor);
-            List<String> results = new ArrayList<>();
-            results.add("test1");
-            recordQueryResponse.setResults(results);
-
-            when(configurationProperties.getStorageRecordsBatchSize()).thenReturn(1);
-
-            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
-
-            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertEquals("{\"kind\":\"tenant:test:test:1.0.0\",\"cursor\":\"100\"}", taskQueuePayload);
-        } catch (Exception e) {
-            fail("Should not throw exception" + e.getMessage());
-        }
-    }
-
-    @Test
-    public void should_returnRecordChangedMessage_givenValidResponseResult_reIndexRecordsTest() {
-        try {
-            List<String> results = new ArrayList<>();
-            results.add("test1");
-            recordQueryResponse.setResults(results);
-            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
-
-            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertEquals(String.format("{\"data\":\"[{\\\"id\\\":\\\"test1\\\",\\\"kind\\\":\\\"tenant:test:test:1.0.0\\\",\\\"op\\\":\\\"create\\\"}]\",\"attributes\":{\"correlation-id\":\"%s\"}}", correlationId), taskQueuePayload);
-        } catch (Exception e) {
-            fail("Should not throw exception" + e.getMessage());
-        }
-    }
-}
+// 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.service;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
+import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
+import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.*;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(SpringRunner.class)
+public class ReindexServiceTest {
+
+    private final String cursor = "100";
+
+    private final String correlationId = UUID.randomUUID().toString();
+
+    @Mock
+    private IndexerConfigurationProperties configurationProperties;
+    @Mock
+    private StorageService storageService;
+    @Mock
+    private IRequestInfo requestInfo;
+    @Mock
+    private IndexerQueueTaskBuilder indexerQueueTaskBuilder;
+    @Mock
+    private JaxRsDpsLog log;
+    @InjectMocks
+    private ReindexServiceImpl sut;
+
+    private RecordReindexRequest recordReindexRequest;
+    private RecordQueryResponse recordQueryResponse;
+
+    private Map<String, String> httpHeaders;
+
+    @Before
+    public void setup() {
+        initMocks(this);
+
+        mockStatic(UUID.class);
+
+        recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor(cursor).build();
+        recordQueryResponse = new RecordQueryResponse();
+
+        httpHeaders = new HashMap<>();
+        httpHeaders.put(DpsHeaders.AUTHORIZATION, "testAuth");
+        httpHeaders.put(DpsHeaders.CORRELATION_ID, correlationId);
+        DpsHeaders standardHeaders = DpsHeaders.createFromMap(httpHeaders);
+        when(requestInfo.getHeaders()).thenReturn(standardHeaders);
+        when(requestInfo.getHeadersMapWithDwdAuthZ()).thenReturn(httpHeaders);
+        when(requestInfo.getHeadersWithDwdAuthZ()).thenReturn(standardHeaders);
+    }
+
+    @Test
+    public void should_returnNull_givenNullResponseResult_reIndexRecordsTest() {
+        try {
+            recordQueryResponse.setResults(null);
+            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
+
+            String response = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertNull(response);
+        } catch (Exception e) {
+            fail("Should not throw this exception" + e.getMessage());
+        }
+    }
+
+    @Test
+    public void should_returnNull_givenEmptyResponseResult_reIndexRecordsTest() {
+        try {
+            recordQueryResponse.setResults(new ArrayList<>());
+            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
+
+            String response = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertNull(response);
+        } catch (Exception e) {
+            fail("Should not throw this exception" + e.getMessage());
+        }
+    }
+    @Ignore
+    @Test
+    public void should_returnRecordQueryRequestPayload_givenValidResponseResult_reIndexRecordsTest() {
+        try {
+            recordQueryResponse.setCursor(cursor);
+            List<String> results = new ArrayList<>();
+            results.add("test1");
+            recordQueryResponse.setResults(results);
+
+            when(configurationProperties.getStorageRecordsBatchSize()).thenReturn(1);
+
+            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
+
+            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertEquals("{\"kind\":\"tenant:test:test:1.0.0\",\"cursor\":\"100\"}", taskQueuePayload);
+        } catch (Exception e) {
+            fail("Should not throw exception" + e.getMessage());
+        }
+    }
+
+    @Test
+    public void should_returnRecordChangedMessage_givenValidResponseResult_reIndexRecordsTest() {
+        try {
+            List<String> results = new ArrayList<>();
+            results.add("test1");
+            recordQueryResponse.setResults(results);
+            when(storageService.getRecordsByKind(any())).thenReturn(recordQueryResponse);
+
+            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertEquals(String.format("{\"data\":\"[{\\\"id\\\":\\\"test1\\\",\\\"kind\\\":\\\"tenant:test:test:1.0.0\\\",\\\"op\\\":\\\"create\\\"}]\",\"attributes\":{\"correlation-id\":\"%s\"}}", correlationId), taskQueuePayload);
+        } catch (Exception e) {
+            fail("Should not throw exception" + e.getMessage());
+        }
+    }
+}
diff --git a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/StorageServiceTest.java b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/StorageServiceTest.java
index 99bf8b099..3ff767ebe 100644
--- a/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/StorageServiceTest.java
+++ b/provider/indexer-gcp/src/test/java/org/opengroup/osdu/indexer/service/StorageServiceTest.java
@@ -1,254 +1,254 @@
-// 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.service;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.Spy;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
-import org.opengroup.osdu.core.common.model.indexer.JobStatus;
-import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
-import org.opengroup.osdu.core.common.http.IUrlFetchService;
-import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.core.common.model.indexer.Records;
-import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
-import org.springframework.http.HttpStatus;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
-import static java.util.Collections.singletonList;
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-@RunWith(SpringRunner.class)
-public class StorageServiceTest {
-
-    @Mock
-    private IUrlFetchService urlFetchService;
-    @Mock
-    private JobStatus jobStatus;
-    @Mock
-    private JaxRsDpsLog log;
-    @Mock
-    private IRequestInfo requestInfo;
-    @Mock
-    private IndexerConfigurationProperties configurationProperties;
-    @Spy
-    private ObjectMapper objectMapper = new ObjectMapper();
-    @InjectMocks
-    private StorageServiceImpl sut;
-
-    private List<String> ids;
-    private static final String RECORD_ID1 = "tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465";
-    private static final String RECORDS_ID2 = "tenant1:doc:15e790a69beb4d789b1f979e2af2e813";
-
-    @Before
-    public void setup() {
-
-        String recordChangedMessages = "[{\"id\":\"tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"purge\"}," +
-                "{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"create\"}]";
-
-        when(this.requestInfo.getHeadersMap()).thenReturn(new HashMap<>());
-        when(this.requestInfo.getHeaders()).thenReturn(new DpsHeaders());
-
-        Type listType = new TypeToken<List<RecordInfo>>() {}.getType();
-
-        List<RecordInfo> msgs = (new Gson()).fromJson(recordChangedMessages, listType);
-        jobStatus.initialize(msgs);
-        ids = Arrays.asList(RECORD_ID1, RECORDS_ID2);
-
-        when(configurationProperties.getStorageRecordsBatchSize()).thenReturn(20);
-    }
-
-    @Test
-    public void should_return404_givenNullData_getValidStorageRecordsTest() throws URISyntaxException {
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(null);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        should_return404_getValidStorageRecordsTest();
-    }
-
-    @Test
-    public void should_return404_givenEmptyData_getValidStorageRecordsTest() throws URISyntaxException {
-
-        String emptyDataFromStorage = "{\"records\":[],\"notFound\":[]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(emptyDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        should_return404_getValidStorageRecordsTest();
-    }
-
-    @Test
-    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsTest() throws URISyntaxException {
-
-        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"], \"conversionStatuses\": []}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(ids);
-
-        assertEquals(1, storageRecords.getRecords().size());
-    }
-
-    @Test
-    public void should_logMissingRecord_given_storageMissedRecords() throws URISyntaxException {
-
-        String validDataFromStorage = "{\"records\":[{\"id\":\"tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(ids);
-
-        assertEquals(1, storageRecords.getRecords().size());
-        verify(this.jobStatus).addOrUpdateRecordStatus(singletonList(RECORDS_ID2), IndexingStatus.FAIL, HttpStatus.NOT_FOUND.value(), "Partial response received from Storage service - missing records", "Partial response received from Storage service: tenant1:doc:15e790a69beb4d789b1f979e2af2e813");
-    }
-
-    @Test
-    public void should_returnValidJobStatus_givenFailedUnitsConversion_processRecordChangedMessageTest() throws URISyntaxException {
-        String validDataFromStorage = "{\"records\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[],\"conversionStatuses\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"status\":\"ERROR\",\"errors\":[\"crs conversion failed\"]}]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(singletonList(RECORDS_ID2));
-
-        assertEquals(1, storageRecords.getRecords().size());
-        verify(this.jobStatus).addOrUpdateRecordStatus(RECORDS_ID2, IndexingStatus.WARN, HttpStatus.BAD_REQUEST.value(), "crs conversion failed", String.format("record-id: %s | %s", "tenant1:doc:15e790a69beb4d789b1f979e2af2e813", "crs conversion failed"));
-    }
-
-    @Test
-    public void should_returnValidResponse_givenValidRecordQueryRequest_getRecordListByKind() throws Exception {
-
-        RecordReindexRequest recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor("100").build();
-
-        HttpResponse httpResponse = new HttpResponse();
-        httpResponse.setBody(new Gson().toJson(recordReindexRequest, RecordReindexRequest.class));
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        RecordQueryResponse recordQueryResponse = this.sut.getRecordsByKind(recordReindexRequest);
-
-        assertEquals("100", recordQueryResponse.getCursor());
-        assertNull(recordQueryResponse.getResults());
-    }
-
-    @Test
-    public void should_returnValidResponse_givenValidKind_getSchemaByKind() throws Exception {
-
-        String validSchemaFromStorage = "{" +
-                "  \"kind\": \"tenant:test:test:1.0.0\"," +
-                "  \"schema\": [" +
-                "    {" +
-                "      \"path\": \"msg\"," +
-                "      \"kind\": \"string\"" +
-                "    }," +
-                "    {" +
-                "      \"path\": \"references.entity\"," +
-                "      \"kind\": \"string\"" +
-                "    }" +
-                "  ]," +
-                "  \"ext\": null" +
-                "}";
-        String kind = "tenant:test:test:1.0.0";
-
-        HttpResponse httpResponse = new HttpResponse();
-        httpResponse.setResponseCode(HttpStatus.OK.value());
-        httpResponse.setBody(validSchemaFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        String recordSchemaResponse = this.sut.getStorageSchema(kind);
-
-        assertNotNull(recordSchemaResponse);
-    }
-
-    @Test
-    public void should_returnNullResponse_givenAbsentKind_getSchemaByKind() throws Exception {
-
-        String kind = "tenant:test:test:1.0.0";
-
-        HttpResponse httpResponse = new HttpResponse();
-        httpResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        String recordSchemaResponse = this.sut.getStorageSchema(kind);
-
-        assertNull(recordSchemaResponse);
-    }
-
-    @Test
-    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsWithInvalidConversionTest() throws URISyntaxException {
-
-        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"],\"conversionStatuses\": [{\"id\":\"testid\",\"status\":\"ERROR\",\"errors\":[\"conversion error occurred\"] } ]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(ids);
-
-        assertEquals(1, storageRecords.getRecords().size());
-
-        assertEquals(1, storageRecords.getConversionStatuses().get(0).getErrors().size());
-
-        assertEquals("conversion error occurred", storageRecords.getConversionStatuses().get(0).getErrors().get(0));
-    }
-
-    private void should_return404_getValidStorageRecordsTest() {
-        try {
-            this.sut.getStorageRecords(ids);
-            fail("Should throw exception");
-        } catch (AppException e) {
-            assertEquals(HttpStatus.NOT_FOUND.value(), e.getError().getCode());
-        } catch (Exception e) {
-            fail("Should not throw this exception" + e.getMessage());
-        }
-    }
-}
+// 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.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
+import org.opengroup.osdu.core.common.model.indexer.JobStatus;
+import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
+import org.opengroup.osdu.core.common.http.IUrlFetchService;
+import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.core.common.model.indexer.Records;
+import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.lang.reflect.Type;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(SpringRunner.class)
+public class StorageServiceTest {
+
+    @Mock
+    private IUrlFetchService urlFetchService;
+    @Mock
+    private JobStatus jobStatus;
+    @Mock
+    private JaxRsDpsLog log;
+    @Mock
+    private IRequestInfo requestInfo;
+    @Mock
+    private IndexerConfigurationProperties configurationProperties;
+    @Spy
+    private ObjectMapper objectMapper = new ObjectMapper();
+    @InjectMocks
+    private StorageServiceImpl sut;
+
+    private List<String> ids;
+    private static final String RECORD_ID1 = "tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465";
+    private static final String RECORDS_ID2 = "tenant1:doc:15e790a69beb4d789b1f979e2af2e813";
+
+    @Before
+    public void setup() {
+
+        String recordChangedMessages = "[{\"id\":\"tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"purge\"}," +
+                "{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"create\"}]";
+
+        when(this.requestInfo.getHeadersMap()).thenReturn(new HashMap<>());
+        when(this.requestInfo.getHeaders()).thenReturn(new DpsHeaders());
+
+        Type listType = new TypeToken<List<RecordInfo>>() {}.getType();
+
+        List<RecordInfo> msgs = (new Gson()).fromJson(recordChangedMessages, listType);
+        jobStatus.initialize(msgs);
+        ids = Arrays.asList(RECORD_ID1, RECORDS_ID2);
+
+        when(configurationProperties.getStorageRecordsBatchSize()).thenReturn(20);
+    }
+
+    @Test
+    public void should_return404_givenNullData_getValidStorageRecordsTest() throws URISyntaxException {
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(null);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        should_return404_getValidStorageRecordsTest();
+    }
+
+    @Test
+    public void should_return404_givenEmptyData_getValidStorageRecordsTest() throws URISyntaxException {
+
+        String emptyDataFromStorage = "{\"records\":[],\"notFound\":[]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(emptyDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        should_return404_getValidStorageRecordsTest();
+    }
+
+    @Test
+    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsTest() throws URISyntaxException {
+
+        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"], \"conversionStatuses\": []}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(ids);
+
+        assertEquals(1, storageRecords.getRecords().size());
+    }
+
+    @Test
+    public void should_logMissingRecord_given_storageMissedRecords() throws URISyntaxException {
+
+        String validDataFromStorage = "{\"records\":[{\"id\":\"tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(ids);
+
+        assertEquals(1, storageRecords.getRecords().size());
+        verify(this.jobStatus).addOrUpdateRecordStatus(singletonList(RECORDS_ID2), IndexingStatus.FAIL, HttpStatus.NOT_FOUND.value(), "Partial response received from Storage service - missing records", "Partial response received from Storage service: tenant1:doc:15e790a69beb4d789b1f979e2af2e813");
+    }
+
+    @Test
+    public void should_returnValidJobStatus_givenFailedUnitsConversion_processRecordChangedMessageTest() throws URISyntaxException {
+        String validDataFromStorage = "{\"records\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[],\"conversionStatuses\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"status\":\"ERROR\",\"errors\":[\"crs conversion failed\"]}]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(singletonList(RECORDS_ID2));
+
+        assertEquals(1, storageRecords.getRecords().size());
+        verify(this.jobStatus).addOrUpdateRecordStatus(RECORDS_ID2, IndexingStatus.WARN, HttpStatus.BAD_REQUEST.value(), "crs conversion failed", String.format("record-id: %s | %s", "tenant1:doc:15e790a69beb4d789b1f979e2af2e813", "crs conversion failed"));
+    }
+
+    @Test
+    public void should_returnValidResponse_givenValidRecordQueryRequest_getRecordListByKind() throws Exception {
+
+        RecordReindexRequest recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor("100").build();
+
+        HttpResponse httpResponse = new HttpResponse();
+        httpResponse.setBody(new Gson().toJson(recordReindexRequest, RecordReindexRequest.class));
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        RecordQueryResponse recordQueryResponse = this.sut.getRecordsByKind(recordReindexRequest);
+
+        assertEquals("100", recordQueryResponse.getCursor());
+        assertNull(recordQueryResponse.getResults());
+    }
+
+    @Test
+    public void should_returnValidResponse_givenValidKind_getSchemaByKind() throws Exception {
+
+        String validSchemaFromStorage = "{" +
+                "  \"kind\": \"tenant:test:test:1.0.0\"," +
+                "  \"schema\": [" +
+                "    {" +
+                "      \"path\": \"msg\"," +
+                "      \"kind\": \"string\"" +
+                "    }," +
+                "    {" +
+                "      \"path\": \"references.entity\"," +
+                "      \"kind\": \"string\"" +
+                "    }" +
+                "  ]," +
+                "  \"ext\": null" +
+                "}";
+        String kind = "tenant:test:test:1.0.0";
+
+        HttpResponse httpResponse = new HttpResponse();
+        httpResponse.setResponseCode(HttpStatus.OK.value());
+        httpResponse.setBody(validSchemaFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        String recordSchemaResponse = this.sut.getStorageSchema(kind);
+
+        assertNotNull(recordSchemaResponse);
+    }
+
+    @Test
+    public void should_returnNullResponse_givenAbsentKind_getSchemaByKind() throws Exception {
+
+        String kind = "tenant:test:test:1.0.0";
+
+        HttpResponse httpResponse = new HttpResponse();
+        httpResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        String recordSchemaResponse = this.sut.getStorageSchema(kind);
+
+        assertNull(recordSchemaResponse);
+    }
+
+    @Test
+    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsWithInvalidConversionTest() throws URISyntaxException {
+
+        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"],\"conversionStatuses\": [{\"id\":\"testid\",\"status\":\"ERROR\",\"errors\":[\"conversion error occurred\"] } ]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(ids);
+
+        assertEquals(1, storageRecords.getRecords().size());
+
+        assertEquals(1, storageRecords.getConversionStatuses().get(0).getErrors().size());
+
+        assertEquals("conversion error occurred", storageRecords.getConversionStatuses().get(0).getErrors().get(0));
+    }
+
+    private void should_return404_getValidStorageRecordsTest() {
+        try {
+            this.sut.getStorageRecords(ids);
+            fail("Should throw exception");
+        } catch (AppException e) {
+            assertEquals(HttpStatus.NOT_FOUND.value(), e.getError().getCode());
+        } catch (Exception e) {
+            fail("Should not throw this exception" + e.getMessage());
+        }
+    }
+}
diff --git a/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/GlobalExceptionMapper.java b/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/GlobalExceptionMapper.java
index 092b76bb7..8ceacd2d7 100644
--- a/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/GlobalExceptionMapper.java
+++ b/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/GlobalExceptionMapper.java
@@ -1,72 +1,72 @@
-/* Licensed Materials - Property of IBM              */		
-/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
-
-package org.opengroup.osdu.indexer.ibm.util;
-
-import javax.validation.ValidationException;
-
-import javassist.NotFoundException;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
-import org.opengroup.osdu.core.common.model.http.AppException;
-
-@Order(Ordered.HIGHEST_PRECEDENCE)
-@ControllerAdvice
-public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
-
-    @Autowired
-    private JaxRsDpsLog logger;
-
-    @ExceptionHandler(AppException.class)
-    protected ResponseEntity<Object> handleAppException(AppException e) {
-        return this.getErrorResponse(e);
-    }
-
-    @ExceptionHandler(ValidationException.class)
-    protected ResponseEntity<Object> handleValidationException(ValidationException e) {
-        return this.getErrorResponse(
-                new AppException(HttpStatus.BAD_REQUEST.value(), "Validation error.", e.getMessage(), e));
-    }
-
-    @ExceptionHandler(NotFoundException.class)
-    protected ResponseEntity<Object> handleNotFoundException(NotFoundException e) {
-        return this.getErrorResponse(
-                new AppException(HttpStatus.NOT_FOUND.value(), "Resource not found.", e.getMessage(), e));
-    }
-
-    @ExceptionHandler(AccessDeniedException.class)
-    protected ResponseEntity<Object> handleAccessDeniedException(AccessDeniedException e) {
-        return this.getErrorResponse(
-                new AppException(HttpStatus.FORBIDDEN.value(), "Access denied", e.getMessage(), e));
-    }
-
-    @ExceptionHandler(Exception.class)
-    protected ResponseEntity<Object> handleGeneralException(Exception e) {
-        return this.getErrorResponse(
-                new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Server error.",
-                        "An unknown error has occurred.", e));
-    }
-
-    private ResponseEntity<Object> getErrorResponse(AppException e) {
-
-        String exceptionMsg = e.getOriginalException() != null
-                ? e.getOriginalException().getMessage()
-                : e.getError().getMessage();
-
-        if (e.getError().getCode() > 499) {
-            this.logger.error(exceptionMsg, e);
-        } else {
-            this.logger.warning(exceptionMsg, e);
-        }
-
-        return new ResponseEntity<Object>(e.getError(), HttpStatus.resolve(e.getError().getCode()));
-    }
+/* Licensed Materials - Property of IBM              */		
+/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
+
+package org.opengroup.osdu.indexer.ibm.util;
+
+import javax.validation.ValidationException;
+
+import javassist.NotFoundException;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+import org.opengroup.osdu.core.common.model.http.AppException;
+
+@Order(Ordered.HIGHEST_PRECEDENCE)
+@ControllerAdvice
+public class GlobalExceptionMapper extends ResponseEntityExceptionHandler {
+
+    @Autowired
+    private JaxRsDpsLog logger;
+
+    @ExceptionHandler(AppException.class)
+    protected ResponseEntity<Object> handleAppException(AppException e) {
+        return this.getErrorResponse(e);
+    }
+
+    @ExceptionHandler(ValidationException.class)
+    protected ResponseEntity<Object> handleValidationException(ValidationException e) {
+        return this.getErrorResponse(
+                new AppException(HttpStatus.BAD_REQUEST.value(), "Validation error.", e.getMessage(), e));
+    }
+
+    @ExceptionHandler(NotFoundException.class)
+    protected ResponseEntity<Object> handleNotFoundException(NotFoundException e) {
+        return this.getErrorResponse(
+                new AppException(HttpStatus.NOT_FOUND.value(), "Resource not found.", e.getMessage(), e));
+    }
+
+    @ExceptionHandler(AccessDeniedException.class)
+    protected ResponseEntity<Object> handleAccessDeniedException(AccessDeniedException e) {
+        return this.getErrorResponse(
+                new AppException(HttpStatus.FORBIDDEN.value(), "Access denied", e.getMessage(), e));
+    }
+
+    @ExceptionHandler(Exception.class)
+    protected ResponseEntity<Object> handleGeneralException(Exception e) {
+        return this.getErrorResponse(
+                new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Server error.",
+                        "An unknown error has occurred.", e));
+    }
+
+    private ResponseEntity<Object> getErrorResponse(AppException e) {
+
+        String exceptionMsg = e.getOriginalException() != null
+                ? e.getOriginalException().getMessage()
+                : e.getError().getMessage();
+
+        if (e.getError().getCode() > 499) {
+            this.logger.error(exceptionMsg, e);
+        } else {
+            this.logger.warning(exceptionMsg, e);
+        }
+
+        return new ResponseEntity<Object>(e.getError(), HttpStatus.resolve(e.getError().getCode()));
+    }
 }
\ No newline at end of file
diff --git a/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/IndexerQueueTaskBuilderIbm.java b/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/IndexerQueueTaskBuilderIbm.java
index a3d7805e6..b44ce5753 100644
--- a/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/IndexerQueueTaskBuilderIbm.java
+++ b/provider/indexer-ibm/src/main/java/org/opengroup/osdu/indexer/ibm/util/IndexerQueueTaskBuilderIbm.java
@@ -1,159 +1,159 @@
-/* Licensed Materials - Property of IBM              */		
-/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
- 
-package org.opengroup.osdu.indexer.ibm.util;
-
-import static org.opengroup.osdu.core.common.Constants.WORKER_RELATIVE_URL;
-import static org.opengroup.osdu.core.common.model.http.DpsHeaders.AUTHORIZATION;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-
-import org.apache.http.HttpStatus;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.indexer.OperationType;
-import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
-import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
-import org.opengroup.osdu.core.ibm.messagebus.IMessageFactory;
-import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
-import org.opengroup.osdu.indexer.service.StorageService;
-import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
-
-import com.google.common.base.Strings;
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-
-@Primary
-@Component
-public class IndexerQueueTaskBuilderIbm extends IndexerQueueTaskBuilder {
-	private static final Logger logger = LoggerFactory.getLogger(IndexerQueueTaskBuilderIbm.class);
-	
-	@Inject
-	IMessageFactory mq;
-	
-    @Inject
-    private StorageService storageService;
-
-    @Inject
-    private RequestInfoImpl requestInfo;
-    
-    @Inject
-    private IndexerConfigurationProperties configurationProperties;
-	
-	private Gson gson;
-	private final static String RETRY_STRING = "retry";
-	private final static String ERROR_CODE = "errorCode";
-	private final static String ERROR_MESSAGE = "errorMessage";
-
-	@Inject
-	public void init() {
-		gson = new Gson();
-	}
-
-	@Override
-	public void createWorkerTask(String payload, DpsHeaders headers) {
-		createTask(payload, headers);
-	}
-
-	@Override
-	public void createReIndexTask(String payload, DpsHeaders headers) {
-		createTask(payload, headers);
-	}
-	
-    public void createReIndexTask(String payload, Long countdownMillis, DpsHeaders headers) {
-    	publishAllRecordsToSubscriber(payload, headers);
-    }
-	
-	//used by reindexer api
-	@Override
-	public void createWorkerTask(String payload, Long countdownMillis, DpsHeaders headers) {
-		createTask(payload, headers);
-    }
-
-	private void createTask(String payload, DpsHeaders headers) {
-
-		try {
-			RecordChangedMessages receivedPayload = gson.fromJson(payload, RecordChangedMessages.class);
-
-			Map<String, String> attributes = receivedPayload.getAttributes();
-			int retryCount = 0;
-			if (attributes.containsKey(RETRY_STRING)) {
-				retryCount = Integer.parseInt(attributes.get(RETRY_STRING));
-				retryCount++;
-			} else {
-				retryCount = 1;
-			}
-			attributes.put(RETRY_STRING, String.valueOf(retryCount));
-			attributes.put(ERROR_CODE, "999"); //error code TBD 
-			attributes.put(ERROR_MESSAGE, "Indexer could not process record");
-			receivedPayload.setAttributes(attributes);
-
-			// incase if we need to shift logic from indexer-queue-ibm/subscriber.java
-			/*
-			 * if(Integer.parseInt(receivedPayload.getAttributes().get(RETRY_STRING))>3) {
-			 * //add DLQ in IMessageFactory
-			 * 
-			 * mq.sendMessage("DLQ", gson.toJson(receivedPayload)); }
-			 */
-			logger.info("Message send back to queue : " + receivedPayload);
-			mq.sendMessage(IMessageFactory.DEFAULT_QUEUE_NAME, gson.toJson(receivedPayload));
-		} catch (JsonSyntaxException e) {
-			logger.error("JsonSyntaxException in IndexerQueueTaskBuilderIbm " + e.toString());
-			e.printStackTrace();
-		} catch (NumberFormatException e) {
-			logger.error("NumberFormatException in IndexerQueueTaskBuilderIbm " + e.toString());
-			e.printStackTrace();
-		} catch (Exception e) {
-			logger.error("Exception in IndexerQueueTaskBuilderIbm " + e.toString());
-			e.printStackTrace();
-		}
-
-	}
-	 private void publishAllRecordsToSubscriber(String payload, DpsHeaders headers) {
-	        Gson gson = new Gson();
-	        RecordReindexRequest recordReindexRequest = gson.fromJson(payload, RecordReindexRequest.class);
-	        final String recordKind = recordReindexRequest.getKind();
-	        RecordQueryResponse recordQueryResponse = null;
-
-	        try {
-	            do {
-	                headers.put(AUTHORIZATION, this.requestInfo.checkOrGetAuthorizationHeader());
-
-	                if (recordQueryResponse != null) {
-	                    recordReindexRequest = RecordReindexRequest.builder().cursor(recordQueryResponse.getCursor()).kind(recordKind).build();
-	                }
-	                recordQueryResponse = this.storageService.getRecordsByKind(recordReindexRequest);
-	                if (recordQueryResponse.getResults() != null && recordQueryResponse.getResults().size() != 0) {
-
-	                    List<RecordInfo> records = recordQueryResponse.getResults().stream()
-	                            .map(record -> RecordInfo.builder().id(record).kind(recordKind).op(OperationType.create.name()).build()).collect(Collectors.toList());
-
-	                    Map<String, String> attributes = new HashMap<>();
-	                    attributes.put(DpsHeaders.ACCOUNT_ID,  headers.getPartitionIdWithFallbackToAccountId());
-	                    attributes.put(DpsHeaders.DATA_PARTITION_ID,  headers.getPartitionIdWithFallbackToAccountId());
-	                    attributes.put(DpsHeaders.CORRELATION_ID, headers.getCorrelationId());
-
-	                    RecordChangedMessages recordChangedMessages = RecordChangedMessages.builder().data(gson.toJson(records)).attributes(attributes).build();
-	                    String recordChangedMessagePayload = gson.toJson(recordChangedMessages);
-	                    createTask(recordChangedMessagePayload, headers);
-	                }
-	            } while (!Strings.isNullOrEmpty(recordQueryResponse.getCursor()) && recordQueryResponse.getResults().size() == configurationProperties.getStorageRecordsBatchSize());
-
-	        } catch (AppException e) {
-	            throw e;
-	        } catch (Exception e) {
-	            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error", "An unknown error has occurred.", e);
-	        }
-	    }
+/* Licensed Materials - Property of IBM              */		
+/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
+ 
+package org.opengroup.osdu.indexer.ibm.util;
+
+import static org.opengroup.osdu.core.common.Constants.WORKER_RELATIVE_URL;
+import static org.opengroup.osdu.core.common.model.http.DpsHeaders.AUTHORIZATION;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.indexer.OperationType;
+import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
+import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.core.common.model.search.RecordChangedMessages;
+import org.opengroup.osdu.core.ibm.messagebus.IMessageFactory;
+import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
+import org.opengroup.osdu.indexer.service.StorageService;
+import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+
+@Primary
+@Component
+public class IndexerQueueTaskBuilderIbm extends IndexerQueueTaskBuilder {
+	private static final Logger logger = LoggerFactory.getLogger(IndexerQueueTaskBuilderIbm.class);
+	
+	@Inject
+	IMessageFactory mq;
+	
+    @Inject
+    private StorageService storageService;
+
+    @Inject
+    private RequestInfoImpl requestInfo;
+    
+    @Inject
+    private IndexerConfigurationProperties configurationProperties;
+	
+	private Gson gson;
+	private final static String RETRY_STRING = "retry";
+	private final static String ERROR_CODE = "errorCode";
+	private final static String ERROR_MESSAGE = "errorMessage";
+
+	@Inject
+	public void init() {
+		gson = new Gson();
+	}
+
+	@Override
+	public void createWorkerTask(String payload, DpsHeaders headers) {
+		createTask(payload, headers);
+	}
+
+	@Override
+	public void createReIndexTask(String payload, DpsHeaders headers) {
+		createTask(payload, headers);
+	}
+	
+    public void createReIndexTask(String payload, Long countdownMillis, DpsHeaders headers) {
+    	publishAllRecordsToSubscriber(payload, headers);
+    }
+	
+	//used by reindexer api
+	@Override
+	public void createWorkerTask(String payload, Long countdownMillis, DpsHeaders headers) {
+		createTask(payload, headers);
+    }
+
+	private void createTask(String payload, DpsHeaders headers) {
+
+		try {
+			RecordChangedMessages receivedPayload = gson.fromJson(payload, RecordChangedMessages.class);
+
+			Map<String, String> attributes = receivedPayload.getAttributes();
+			int retryCount = 0;
+			if (attributes.containsKey(RETRY_STRING)) {
+				retryCount = Integer.parseInt(attributes.get(RETRY_STRING));
+				retryCount++;
+			} else {
+				retryCount = 1;
+			}
+			attributes.put(RETRY_STRING, String.valueOf(retryCount));
+			attributes.put(ERROR_CODE, "999"); //error code TBD 
+			attributes.put(ERROR_MESSAGE, "Indexer could not process record");
+			receivedPayload.setAttributes(attributes);
+
+			// incase if we need to shift logic from indexer-queue-ibm/subscriber.java
+			/*
+			 * if(Integer.parseInt(receivedPayload.getAttributes().get(RETRY_STRING))>3) {
+			 * //add DLQ in IMessageFactory
+			 * 
+			 * mq.sendMessage("DLQ", gson.toJson(receivedPayload)); }
+			 */
+			logger.info("Message send back to queue : " + receivedPayload);
+			mq.sendMessage(IMessageFactory.DEFAULT_QUEUE_NAME, gson.toJson(receivedPayload));
+		} catch (JsonSyntaxException e) {
+			logger.error("JsonSyntaxException in IndexerQueueTaskBuilderIbm " + e.toString());
+			e.printStackTrace();
+		} catch (NumberFormatException e) {
+			logger.error("NumberFormatException in IndexerQueueTaskBuilderIbm " + e.toString());
+			e.printStackTrace();
+		} catch (Exception e) {
+			logger.error("Exception in IndexerQueueTaskBuilderIbm " + e.toString());
+			e.printStackTrace();
+		}
+
+	}
+	 private void publishAllRecordsToSubscriber(String payload, DpsHeaders headers) {
+	        Gson gson = new Gson();
+	        RecordReindexRequest recordReindexRequest = gson.fromJson(payload, RecordReindexRequest.class);
+	        final String recordKind = recordReindexRequest.getKind();
+	        RecordQueryResponse recordQueryResponse = null;
+
+	        try {
+	            do {
+	                headers.put(AUTHORIZATION, this.requestInfo.checkOrGetAuthorizationHeader());
+
+	                if (recordQueryResponse != null) {
+	                    recordReindexRequest = RecordReindexRequest.builder().cursor(recordQueryResponse.getCursor()).kind(recordKind).build();
+	                }
+	                recordQueryResponse = this.storageService.getRecordsByKind(recordReindexRequest);
+	                if (recordQueryResponse.getResults() != null && recordQueryResponse.getResults().size() != 0) {
+
+	                    List<RecordInfo> records = recordQueryResponse.getResults().stream()
+	                            .map(record -> RecordInfo.builder().id(record).kind(recordKind).op(OperationType.create.name()).build()).collect(Collectors.toList());
+
+	                    Map<String, String> attributes = new HashMap<>();
+	                    attributes.put(DpsHeaders.ACCOUNT_ID,  headers.getPartitionIdWithFallbackToAccountId());
+	                    attributes.put(DpsHeaders.DATA_PARTITION_ID,  headers.getPartitionIdWithFallbackToAccountId());
+	                    attributes.put(DpsHeaders.CORRELATION_ID, headers.getCorrelationId());
+
+	                    RecordChangedMessages recordChangedMessages = RecordChangedMessages.builder().data(gson.toJson(records)).attributes(attributes).build();
+	                    String recordChangedMessagePayload = gson.toJson(recordChangedMessages);
+	                    createTask(recordChangedMessagePayload, headers);
+	                }
+	            } while (!Strings.isNullOrEmpty(recordQueryResponse.getCursor()) && recordQueryResponse.getResults().size() == configurationProperties.getStorageRecordsBatchSize());
+
+	        } catch (AppException e) {
+	            throw e;
+	        } catch (Exception e) {
+	            throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error", "An unknown error has occurred.", e);
+	        }
+	    }
 }
\ No newline at end of file
diff --git a/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/ReindexServiceTest.java b/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/ReindexServiceTest.java
index 87dfea951..acb116a76 100644
--- a/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/ReindexServiceTest.java
+++ b/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/ReindexServiceTest.java
@@ -1,144 +1,144 @@
-/* Licensed Materials - Property of IBM              */		
-/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
-package org.opengroup.osdu.indexer.ibm.service;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.opengroup.osdu.core.common.model.http.DpsHeaders;
-import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
-import org.opengroup.osdu.indexer.service.ReindexServiceImpl;
-import org.opengroup.osdu.indexer.service.StorageService;
-import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
-import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.*;
-
-import static org.junit.Assert.fail;
-import static org.mockito.MockitoAnnotations.initMocks;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-@Ignore
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(SpringRunner.class)
-@PrepareForTest({IndexerConfigurationProperties.class})
-public class ReindexServiceTest {
-
-    private final String cursor = "100";
-
-    private final String correlationId = UUID.randomUUID().toString();
-
-    @Mock
-    private IndexerConfigurationProperties indexerConfigurationProperties;
-
-    @Mock
-    private StorageService storageService;
-
-    @Mock
-    private Map<String, String> httpHeaders;
-    @Mock
-    private IRequestInfo requestInfo;
-    @Mock
-    private IndexerQueueTaskBuilder indexerQueueTaskBuilder;
-    @Mock
-    private JaxRsDpsLog log;
-    @InjectMocks
-    private ReindexServiceImpl sut;
-
-    private RecordReindexRequest recordReindexRequest;
-    private RecordQueryResponse recordQueryResponse;
-
-    @Before
-    public void setup() {
-        initMocks(this);
-
-        mockStatic(UUID.class);
-
-        recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor(cursor).build();
-        recordQueryResponse = new RecordQueryResponse();
-
-        httpHeaders = new HashMap<>();
-        httpHeaders.put(DpsHeaders.AUTHORIZATION, "testAuth");
-        httpHeaders.put(DpsHeaders.CORRELATION_ID, correlationId);
-        DpsHeaders standardHeaders = DpsHeaders.createFromMap(httpHeaders);
-        when(requestInfo.getHeaders()).thenReturn(standardHeaders);
-        when(requestInfo.getHeadersMapWithDwdAuthZ()).thenReturn(httpHeaders);
-    }
-
-    @Test
-    public void should_returnNull_givenNullResponseResult_reIndexRecordsTest() {
-        try {
-            recordQueryResponse.setResults(null);
-            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
-
-            String response = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertNull(response);
-        } catch (Exception e) {
-            fail("Should not throw this exception" + e.getMessage());
-        }
-    }
-
-    @Test
-    public void should_returnNull_givenEmptyResponseResult_reIndexRecordsTest() {
-        try {
-            recordQueryResponse.setResults(new ArrayList<>());
-            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
-
-            String response = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertNull(response);
-        } catch (Exception e) {
-            fail("Should not throw this exception" + e.getMessage());
-        }
-    }
-
-    @Test
-    public void should_returnRecordQueryRequestPayload_givenValidResponseResult_reIndexRecordsTest() {
-        try {
-            recordQueryResponse.setCursor(cursor);
-            List<String> results = new ArrayList<>();
-            results.add("test1");
-            recordQueryResponse.setResults(results);
-
-            when(indexerConfigurationProperties.getStorageRecordsBatchSize()).thenReturn(1);
-
-            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
-
-            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertEquals("{\"kind\":\"tenant:test:test:1.0.0\",\"cursor\":\"100\"}", taskQueuePayload);
-        } catch (Exception e) {
-            fail("Should not throw exception" + e.getMessage());
-        }
-    }
-
-    @Test
-    public void should_returnRecordChangedMessage_givenValidResponseResult_reIndexRecordsTest() {
-        try {
-            List<String> results = new ArrayList<>();
-            results.add("test1");
-            recordQueryResponse.setResults(results);
-            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
-
-            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
-
-            Assert.assertEquals(String.format("{\"data\":\"[{\\\"id\\\":\\\"test1\\\",\\\"kind\\\":\\\"tenant:test:test:1.0.0\\\",\\\"op\\\":\\\"create\\\"}]\",\"attributes\":{\"slb-correlation-id\":\"%s\"}}", correlationId), taskQueuePayload);
-        } catch (Exception e) {
-            fail("Should not throw exception" + e.getMessage());
-        }
-    }
-}
+/* Licensed Materials - Property of IBM              */		
+/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
+package org.opengroup.osdu.indexer.ibm.service;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.indexer.config.IndexerConfigurationProperties;
+import org.opengroup.osdu.indexer.service.ReindexServiceImpl;
+import org.opengroup.osdu.indexer.service.StorageService;
+import org.opengroup.osdu.indexer.util.IndexerQueueTaskBuilder;
+import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.*;
+
+import static org.junit.Assert.fail;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@Ignore
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(SpringRunner.class)
+@PrepareForTest({IndexerConfigurationProperties.class})
+public class ReindexServiceTest {
+
+    private final String cursor = "100";
+
+    private final String correlationId = UUID.randomUUID().toString();
+
+    @Mock
+    private IndexerConfigurationProperties indexerConfigurationProperties;
+
+    @Mock
+    private StorageService storageService;
+
+    @Mock
+    private Map<String, String> httpHeaders;
+    @Mock
+    private IRequestInfo requestInfo;
+    @Mock
+    private IndexerQueueTaskBuilder indexerQueueTaskBuilder;
+    @Mock
+    private JaxRsDpsLog log;
+    @InjectMocks
+    private ReindexServiceImpl sut;
+
+    private RecordReindexRequest recordReindexRequest;
+    private RecordQueryResponse recordQueryResponse;
+
+    @Before
+    public void setup() {
+        initMocks(this);
+
+        mockStatic(UUID.class);
+
+        recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor(cursor).build();
+        recordQueryResponse = new RecordQueryResponse();
+
+        httpHeaders = new HashMap<>();
+        httpHeaders.put(DpsHeaders.AUTHORIZATION, "testAuth");
+        httpHeaders.put(DpsHeaders.CORRELATION_ID, correlationId);
+        DpsHeaders standardHeaders = DpsHeaders.createFromMap(httpHeaders);
+        when(requestInfo.getHeaders()).thenReturn(standardHeaders);
+        when(requestInfo.getHeadersMapWithDwdAuthZ()).thenReturn(httpHeaders);
+    }
+
+    @Test
+    public void should_returnNull_givenNullResponseResult_reIndexRecordsTest() {
+        try {
+            recordQueryResponse.setResults(null);
+            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
+
+            String response = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertNull(response);
+        } catch (Exception e) {
+            fail("Should not throw this exception" + e.getMessage());
+        }
+    }
+
+    @Test
+    public void should_returnNull_givenEmptyResponseResult_reIndexRecordsTest() {
+        try {
+            recordQueryResponse.setResults(new ArrayList<>());
+            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
+
+            String response = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertNull(response);
+        } catch (Exception e) {
+            fail("Should not throw this exception" + e.getMessage());
+        }
+    }
+
+    @Test
+    public void should_returnRecordQueryRequestPayload_givenValidResponseResult_reIndexRecordsTest() {
+        try {
+            recordQueryResponse.setCursor(cursor);
+            List<String> results = new ArrayList<>();
+            results.add("test1");
+            recordQueryResponse.setResults(results);
+
+            when(indexerConfigurationProperties.getStorageRecordsBatchSize()).thenReturn(1);
+
+            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
+
+            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertEquals("{\"kind\":\"tenant:test:test:1.0.0\",\"cursor\":\"100\"}", taskQueuePayload);
+        } catch (Exception e) {
+            fail("Should not throw exception" + e.getMessage());
+        }
+    }
+
+    @Test
+    public void should_returnRecordChangedMessage_givenValidResponseResult_reIndexRecordsTest() {
+        try {
+            List<String> results = new ArrayList<>();
+            results.add("test1");
+            recordQueryResponse.setResults(results);
+            when(storageService.getRecordsByKind(ArgumentMatchers.any())).thenReturn(recordQueryResponse);
+
+            String taskQueuePayload = sut.reindexRecords(recordReindexRequest, false);
+
+            Assert.assertEquals(String.format("{\"data\":\"[{\\\"id\\\":\\\"test1\\\",\\\"kind\\\":\\\"tenant:test:test:1.0.0\\\",\\\"op\\\":\\\"create\\\"}]\",\"attributes\":{\"slb-correlation-id\":\"%s\"}}", correlationId), taskQueuePayload);
+        } catch (Exception e) {
+            fail("Should not throw exception" + e.getMessage());
+        }
+    }
+}
diff --git a/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/StorageServiceTest.java b/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/StorageServiceTest.java
index d546e9b65..dfbdb4396 100644
--- a/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/StorageServiceTest.java
+++ b/provider/indexer-ibm/src/test/java/org/opengroup/osdu/indexer/ibm/service/StorageServiceTest.java
@@ -1,219 +1,219 @@
-/* Licensed Materials - Property of IBM              */		
-/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
-
-package org.opengroup.osdu.indexer.ibm.service;
-
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
-import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
-import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
-import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
-import org.opengroup.osdu.core.common.model.indexer.Records;
-import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
-import org.opengroup.osdu.indexer.service.StorageServiceImpl;
-import org.opengroup.osdu.core.common.model.indexer.JobStatus;
-import org.opengroup.osdu.core.common.model.http.HttpResponse;
-import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
-import org.opengroup.osdu.core.common.http.IUrlFetchService;
-import org.opengroup.osdu.core.common.model.http.AppException;
-import org.springframework.http.HttpStatus;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.lang.reflect.Type;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
-import static java.util.Collections.singletonList;
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-@Ignore
-@RunWith(SpringRunner.class)
-public class StorageServiceTest {
-
-    @Mock
-    private IUrlFetchService urlFetchService;
-    @Mock
-    private JobStatus jobStatus;
-    @Mock
-    private JaxRsDpsLog log;
-    @Mock
-    private IRequestInfo requestInfo;
-    @InjectMocks
-    private StorageServiceImpl sut;
-
-    private List<String> ids;
-    private static final String RECORD_ID1 = "tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465";
-    private static final String RECORDS_ID2 = "tenant1:doc:15e790a69beb4d789b1f979e2af2e813";
-
-    @Before
-    public void setup() {
-
-        String recordChangedMessages = "[{\"id\":\"tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"purge\"}," +
-                "{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"create\"}]";
-
-        when(this.requestInfo.getHeadersMap()).thenReturn(new HashMap<>());
-
-        Type listType = new TypeToken<List<RecordInfo>>() {}.getType();
-
-        List<RecordInfo> msgs = (new Gson()).fromJson(recordChangedMessages, listType);
-        jobStatus.initialize(msgs);
-        ids = Arrays.asList(RECORD_ID1, RECORDS_ID2);
-    }
-
-    @Test
-    public void should_return404_givenNullData_getValidStorageRecordsTest() throws URISyntaxException {
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(null);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        should_return404_getValidStorageRecordsTest();
-    }
-
-    @Test
-    public void should_return404_givenEmptyData_getValidStorageRecordsTest() throws URISyntaxException {
-
-        String emptyDataFromStorage = "{\"records\":[],\"notFound\":[]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(emptyDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        should_return404_getValidStorageRecordsTest();
-    }
-
-    @Test
-    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsTest() throws URISyntaxException {
-
-        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(ids);
-
-        assertEquals(1, storageRecords.getRecords().size());
-    }
-
-    @Test
-    public void should_returnValidResponse_givenValidRecordQueryRequest_getRecordListByKind() throws Exception {
-
-        RecordReindexRequest recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor("100").build();
-
-        HttpResponse httpResponse = new HttpResponse();
-        httpResponse.setBody(new Gson().toJson(recordReindexRequest, RecordReindexRequest.class));
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        RecordQueryResponse recordQueryResponse = this.sut.getRecordsByKind(recordReindexRequest);
-
-        assertEquals("100", recordQueryResponse.getCursor());
-        assertNull(recordQueryResponse.getResults());
-    }
-
-    @Test
-    public void should_returnValidJobStatus_givenFailedUnitsConversion_processRecordChangedMessageTest() throws URISyntaxException {
-        String validDataFromStorage = "{\"records\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[],\"conversionStatuses\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"status\":\"ERROR\",\"errors\":[\"crs conversion failed\"]}]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(singletonList("tenant1:doc:15e790a69beb4d789b1f979e2af2e813"));
-
-        assertEquals(1, storageRecords.getRecords().size());
-        verify(this.jobStatus).addOrUpdateRecordStatus(RECORDS_ID2, IndexingStatus.WARN, HttpStatus.BAD_REQUEST.value(), "crs conversion failed", String.format("record-id: %s | %s", "tenant1:doc:15e790a69beb4d789b1f979e2af2e813", "crs conversion failed"));
-    }
-
-    @Test
-    public void should_returnValidResponse_givenValidKind_getSchemaByKind() throws Exception {
-
-        String validSchemaFromStorage = "{" +
-                "  \"kind\": \"tenant:test:test:1.0.0\"," +
-                "  \"schema\": [" +
-                "    {" +
-                "      \"path\": \"msg\"," +
-                "      \"kind\": \"string\"" +
-                "    }," +
-                "    {" +
-                "      \"path\": \"references.entity\"," +
-                "      \"kind\": \"string\"" +
-                "    }" +
-                "  ]," +
-                "  \"ext\": null" +
-                "}";
-        String kind = "tenant:test:test:1.0.0";
-
-        HttpResponse httpResponse = new HttpResponse();
-        httpResponse.setResponseCode(HttpStatus.OK.value());
-        httpResponse.setBody(validSchemaFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        String recordSchemaResponse = this.sut.getStorageSchema(kind);
-
-        assertNotNull(recordSchemaResponse);
-    }
-
-    @Test
-    public void should_returnNullResponse_givenAbsentKind_getSchemaByKind() throws Exception {
-
-        String kind = "tenant:test:test:1.0.0";
-
-        HttpResponse httpResponse = new HttpResponse();
-        httpResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-
-        String recordSchemaResponse = this.sut.getStorageSchema(kind);
-
-        assertNull(recordSchemaResponse);
-    }
-
-    @Test
-    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsWithInvalidConversionTest() throws URISyntaxException {
-
-        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"],\"conversionStatuses\": [{\"id\":\"testid\",\"status\":\"ERROR\",\"errors\":[\"conversion error occurred\"] } ]}";
-
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
-
-        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
-        Records storageRecords = this.sut.getStorageRecords(ids);
-
-        assertEquals(1, storageRecords.getRecords().size());
-
-        assertEquals(1, storageRecords.getConversionStatuses().get(0).getErrors().size());
-
-        assertEquals("conversion error occurred", storageRecords.getConversionStatuses().get(0).getErrors().get(0));
-    }
-
-    private void should_return404_getValidStorageRecordsTest() {
-        try {
-            this.sut.getStorageRecords(ids);
-            fail("Should throw exception");
-        } catch (AppException e) {
-            assertEquals(HttpStatus.NOT_FOUND, e.getError().getCode());
-        } catch (Exception e) {
-            fail("Should not throw this exception" + e.getMessage());
-        }
-    }
-}
+/* Licensed Materials - Property of IBM              */		
+/* (c) Copyright IBM Corp. 2020. All Rights Reserved.*/
+
+package org.opengroup.osdu.indexer.ibm.service;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opengroup.osdu.core.common.model.indexer.IndexingStatus;
+import org.opengroup.osdu.core.common.model.indexer.RecordInfo;
+import org.opengroup.osdu.core.common.model.indexer.RecordQueryResponse;
+import org.opengroup.osdu.core.common.model.indexer.RecordReindexRequest;
+import org.opengroup.osdu.core.common.model.indexer.Records;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.indexer.service.StorageServiceImpl;
+import org.opengroup.osdu.core.common.model.indexer.JobStatus;
+import org.opengroup.osdu.core.common.model.http.HttpResponse;
+import org.opengroup.osdu.core.common.provider.interfaces.IRequestInfo;
+import org.opengroup.osdu.core.common.http.IUrlFetchService;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.lang.reflect.Type;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@Ignore
+@RunWith(SpringRunner.class)
+public class StorageServiceTest {
+
+    @Mock
+    private IUrlFetchService urlFetchService;
+    @Mock
+    private JobStatus jobStatus;
+    @Mock
+    private JaxRsDpsLog log;
+    @Mock
+    private IRequestInfo requestInfo;
+    @InjectMocks
+    private StorageServiceImpl sut;
+
+    private List<String> ids;
+    private static final String RECORD_ID1 = "tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465";
+    private static final String RECORDS_ID2 = "tenant1:doc:15e790a69beb4d789b1f979e2af2e813";
+
+    @Before
+    public void setup() {
+
+        String recordChangedMessages = "[{\"id\":\"tenant1:doc:1dbf528e0e0549cab7a08f29fbfc8465\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"purge\"}," +
+                "{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"kind\":\"tenant1:testindexer1528919679710:well:1.0.0\",\"op\":\"create\"}]";
+
+        when(this.requestInfo.getHeadersMap()).thenReturn(new HashMap<>());
+
+        Type listType = new TypeToken<List<RecordInfo>>() {}.getType();
+
+        List<RecordInfo> msgs = (new Gson()).fromJson(recordChangedMessages, listType);
+        jobStatus.initialize(msgs);
+        ids = Arrays.asList(RECORD_ID1, RECORDS_ID2);
+    }
+
+    @Test
+    public void should_return404_givenNullData_getValidStorageRecordsTest() throws URISyntaxException {
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(null);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        should_return404_getValidStorageRecordsTest();
+    }
+
+    @Test
+    public void should_return404_givenEmptyData_getValidStorageRecordsTest() throws URISyntaxException {
+
+        String emptyDataFromStorage = "{\"records\":[],\"notFound\":[]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(emptyDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        should_return404_getValidStorageRecordsTest();
+    }
+
+    @Test
+    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsTest() throws URISyntaxException {
+
+        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(ids);
+
+        assertEquals(1, storageRecords.getRecords().size());
+    }
+
+    @Test
+    public void should_returnValidResponse_givenValidRecordQueryRequest_getRecordListByKind() throws Exception {
+
+        RecordReindexRequest recordReindexRequest = RecordReindexRequest.builder().kind("tenant:test:test:1.0.0").cursor("100").build();
+
+        HttpResponse httpResponse = new HttpResponse();
+        httpResponse.setBody(new Gson().toJson(recordReindexRequest, RecordReindexRequest.class));
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        RecordQueryResponse recordQueryResponse = this.sut.getRecordsByKind(recordReindexRequest);
+
+        assertEquals("100", recordQueryResponse.getCursor());
+        assertNull(recordQueryResponse.getResults());
+    }
+
+    @Test
+    public void should_returnValidJobStatus_givenFailedUnitsConversion_processRecordChangedMessageTest() throws URISyntaxException {
+        String validDataFromStorage = "{\"records\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[],\"conversionStatuses\":[{\"id\":\"tenant1:doc:15e790a69beb4d789b1f979e2af2e813\",\"status\":\"ERROR\",\"errors\":[\"crs conversion failed\"]}]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(singletonList("tenant1:doc:15e790a69beb4d789b1f979e2af2e813"));
+
+        assertEquals(1, storageRecords.getRecords().size());
+        verify(this.jobStatus).addOrUpdateRecordStatus(RECORDS_ID2, IndexingStatus.WARN, HttpStatus.BAD_REQUEST.value(), "crs conversion failed", String.format("record-id: %s | %s", "tenant1:doc:15e790a69beb4d789b1f979e2af2e813", "crs conversion failed"));
+    }
+
+    @Test
+    public void should_returnValidResponse_givenValidKind_getSchemaByKind() throws Exception {
+
+        String validSchemaFromStorage = "{" +
+                "  \"kind\": \"tenant:test:test:1.0.0\"," +
+                "  \"schema\": [" +
+                "    {" +
+                "      \"path\": \"msg\"," +
+                "      \"kind\": \"string\"" +
+                "    }," +
+                "    {" +
+                "      \"path\": \"references.entity\"," +
+                "      \"kind\": \"string\"" +
+                "    }" +
+                "  ]," +
+                "  \"ext\": null" +
+                "}";
+        String kind = "tenant:test:test:1.0.0";
+
+        HttpResponse httpResponse = new HttpResponse();
+        httpResponse.setResponseCode(HttpStatus.OK.value());
+        httpResponse.setBody(validSchemaFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        String recordSchemaResponse = this.sut.getStorageSchema(kind);
+
+        assertNotNull(recordSchemaResponse);
+    }
+
+    @Test
+    public void should_returnNullResponse_givenAbsentKind_getSchemaByKind() throws Exception {
+
+        String kind = "tenant:test:test:1.0.0";
+
+        HttpResponse httpResponse = new HttpResponse();
+        httpResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+
+        String recordSchemaResponse = this.sut.getStorageSchema(kind);
+
+        assertNull(recordSchemaResponse);
+    }
+
+    @Test
+    public void should_returnOneValidRecords_givenValidData_getValidStorageRecordsWithInvalidConversionTest() throws URISyntaxException {
+
+        String validDataFromStorage = "{\"records\":[{\"id\":\"testid\", \"version\":1, \"kind\":\"tenant:test:test:1.0.0\"}],\"notFound\":[\"invalid1\"],\"conversionStatuses\": [{\"id\":\"testid\",\"status\":\"ERROR\",\"errors\":[\"conversion error occurred\"] } ]}";
+
+        HttpResponse httpResponse = mock(HttpResponse.class);
+        Mockito.when(httpResponse.getBody()).thenReturn(validDataFromStorage);
+
+        when(this.urlFetchService.sendRequest(ArgumentMatchers.any())).thenReturn(httpResponse);
+        Records storageRecords = this.sut.getStorageRecords(ids);
+
+        assertEquals(1, storageRecords.getRecords().size());
+
+        assertEquals(1, storageRecords.getConversionStatuses().get(0).getErrors().size());
+
+        assertEquals("conversion error occurred", storageRecords.getConversionStatuses().get(0).getErrors().get(0));
+    }
+
+    private void should_return404_getValidStorageRecordsTest() {
+        try {
+            this.sut.getStorageRecords(ids);
+            fail("Should throw exception");
+        } catch (AppException e) {
+            assertEquals(HttpStatus.NOT_FOUND, e.getError().getCode());
+        } catch (Exception e) {
+            fail("Should not throw this exception" + e.getMessage());
+        }
+    }
+}
-- 
GitLab