From 4ab961eebbd7d27d0516aaf1a77a4346791d0660 Mon Sep 17 00:00:00 2001
From: Stanislaw Bieniecki <stanislaw.bieniecki@hitachivantara.com>
Date: Mon, 12 Aug 2024 12:52:33 +0200
Subject: [PATCH 01/18] Fix mapping boolean values to string

(cherry picked from commit 16b487d025cb7abe1ec775f9f07b8c59d96cd4f1)
---
 .../SchemaConverterPropertiesConfig.java      |  6 ++-
 .../osdu/indexer/schema/converter/readme.md   |  2 +-
 .../converter/PropertiesProcessorTest.java    | 37 +++++++++++++++++++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
index e969f8e31..c09339260 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
@@ -46,7 +46,11 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
     private Map<String, String> getDefaultPrimitiveTypesMap() {
         Map<String, String> defaultPrimitiveTypesMap = new HashMap<>();
 
-        defaultPrimitiveTypesMap.put("boolean", "bool");
+        // in the earlier versions boolean was translated to bool and 
+        // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
+        // in some places boolean is still presented as bool so here both are normalized to boolean
+        defaultPrimitiveTypesMap.put("boolean", "boolean");
+        defaultPrimitiveTypesMap.put("bool", "boolean");
         defaultPrimitiveTypesMap.put("number", "double");
         defaultPrimitiveTypesMap.put("date-time", "datetime");
         defaultPrimitiveTypesMap.put("date", "datetime");
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/readme.md b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/readme.md
index 17a4ca99a..f4f8b2e11 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/readme.md
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/readme.md
@@ -278,7 +278,7 @@ Following primitive types are converted to the Storage Service Schema types (all
 "date"->"datetime"
 "int64"->"long"
 "number"->"double"
-"boolean"->"bool"
+"bool"->"boolean"
 "integer"->"int"
 ```
 
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
index fdcfeba5d..478448df0 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
@@ -105,6 +105,43 @@ public class PropertiesProcessorTest {
         assertEquals("{path=" + PATH + ", kind=int}", res);
     }
 
+    @Test
+    public void should_return_boolean_from_boolean_item() {
+        // in the earlier versions boolean was translated to bool and 
+        // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
+        AllOfItem allOfItem = new AllOfItem();
+        JaxRsDpsLog log = Mockito.mock(JaxRsDpsLog.class);
+
+        TypeProperty property = new TypeProperty();
+        property.setType("boolean");
+
+        Map<String, TypeProperty> properties = new LinkedHashMap<>();
+        properties.put(PATH, property);
+        allOfItem.setProperties(properties);
+
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+                .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
+        assertEquals("{path=" + PATH + ", kind=boolean}", res);
+    }
+
+    @Test
+    public void should_return_boolean_from_bool_item() { 
+        // StorageType entry in map is boolean not bool
+        AllOfItem allOfItem = new AllOfItem();
+        JaxRsDpsLog log = Mockito.mock(JaxRsDpsLog.class);
+
+        TypeProperty property = new TypeProperty();
+        property.setType("bool");
+
+        Map<String, TypeProperty> properties = new LinkedHashMap<>();
+        properties.put(PATH, property);
+        allOfItem.setProperties(properties);
+
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+                .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
+        assertEquals("{path=" + PATH + ", kind=boolean}", res);
+    }
+
     @Test
     public void should_return_processed_nested_array_items(){
         JaxRsDpsLog log = Mockito.mock(JaxRsDpsLog.class);
-- 
GitLab


From bb256e4a2513aac702f437aeef31c05f9fd2921f Mon Sep 17 00:00:00 2001
From: Stanislaw Bieniecki <stanislaw.bieniecki@hitachivantara.com>
Date: Tue, 20 Aug 2024 14:40:03 +0200
Subject: [PATCH 02/18] Fix SchemaToStorageFormatImplTest tests

(cherry picked from commit c436ff8c88df23497797722b9d134bc6162b1cc3)
---
 .../R3-json-schema/Generated/file/File.1.0.0.json.res         | 2 +-
 .../R3-json-schema/Generated/type/Type.1.0.0.json.res         | 2 +-
 .../Generated/work-product/WorkProduct.1.0.0.json.res         | 4 ++--
 .../test/resources/converter/wks/slb_wke_wellbore.json.res    | 4 ++--
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res
index 44a5a89ec..c354504c3 100644
--- a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res
@@ -26,7 +26,7 @@
       "path": "Endian"
     },
     {
-      "kind": "bool",
+      "kind": "boolean",
       "path": "LossyCompressionIndicator"
     },
     {
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res
index a7ba6fd16..ad5d44bec 100644
--- a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res
@@ -26,7 +26,7 @@
       "path": "SchemaKind"
     },
     {
-      "kind": "bool",
+      "kind": "boolean",
       "path": "IsReferenceValueType"
     },
     {
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res
index 5852817c8..ea7b4ff22 100644
--- a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res
@@ -6,11 +6,11 @@
       "path": "Components"
     },
     {
-      "kind": "bool",
+      "kind": "boolean",
       "path": "IsExtendedLoad"
     },
     {
-      "kind": "bool",
+      "kind": "boolean",
       "path": "IsDiscoverable"
     },
     {
diff --git a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
index 4b4b9b61d..37d499f5d 100644
--- a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
+++ b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
@@ -66,11 +66,11 @@
       "path": "formationProjected"
     },
     {
-      "kind": "bool",
+      "kind": "boolean",
       "path": "hasAchievedTotalDepth"
     },
     {
-      "kind": "bool",
+      "kind": "boolean",
       "path": "isActive"
     },
     {
-- 
GitLab


From e7244a0d72d0131b68b26274f4087f5f111d2857 Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Tue, 20 Aug 2024 13:10:37 +0000
Subject: [PATCH 03/18] Update NOTICE

(cherry picked from commit 6d078e3b0f33b34c10f05fef7fb57c1e8e6c52f8)
---
 NOTICE | 1 +
 1 file changed, 1 insertion(+)

diff --git a/NOTICE b/NOTICE
index 322ddeb2d..ac0f0c29b 100644
--- a/NOTICE
+++ b/NOTICE
@@ -58,6 +58,7 @@ The following software have components provided under the terms of this license:
 - Byte Buddy (without dependencies) (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy)
 - Byte Buddy Java agent (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent)
 - ClassMate (from http://github.com/cowtowncoder/java-classmate)
+- Cloud Key Management Service (KMS) API v1-rev20240801-2.0.0 (from https://repo1.maven.org/maven2/com/google/apis/google-api-services-cloudkms)
 - Collections (from https://repo1.maven.org/maven2/commons-collections/commons-collections)
 - Converter: Jackson (from https://github.com/square/retrofit, https://repo1.maven.org/maven2/com/squareup/retrofit2/converter-jackson)
 - Core functionality for the Reactor Netty library (from https://github.com/reactor/reactor-netty)
-- 
GitLab


From 6eac033c370e7f1ffaa506ae6650ce5b42e0bdbc Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Thu, 26 Sep 2024 14:18:07 -0400
Subject: [PATCH 04/18] set feature flag to control mapping WIP

(cherry picked from commit 991e2e67f0163a0b107cb13ab4f3845b53632fc7)
---
 .../src/main/resources/application.properties |  1 +
 .../IndexerConfigurationProperties.java       |  1 +
 .../SchemaConverterPropertiesConfig.java      | 21 ++++++++++++++-----
 .../converter/PropertiesProcessorTest.java    | 13 ++++++++++--
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/indexer-core-plus/src/main/resources/application.properties b/indexer-core-plus/src/main/resources/application.properties
index 2f1c6c98b..5d827e4f1 100644
--- a/indexer-core-plus/src/main/resources/application.properties
+++ b/indexer-core-plus/src/main/resources/application.properties
@@ -63,6 +63,7 @@ rabbitmq-retry-limit=5
 
 # Feature flag settings
 featureFlag.strategy=dataPartition
+featureFlag.mapBooleanToString.enabled=true
 featureFlag.asIngestedCoordinates.enabled=false
 featureFlag.keywordLower.enabled=false
 featureFlag.bagOfWords.enabled=false
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/config/IndexerConfigurationProperties.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/config/IndexerConfigurationProperties.java
index 0b7efbc6e..a8afb4a13 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/config/IndexerConfigurationProperties.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/config/IndexerConfigurationProperties.java
@@ -13,6 +13,7 @@ import org.springframework.context.annotation.Configuration;
 @Getter
 @Setter
 public class IndexerConfigurationProperties {
+	public static final String MAP_BOOL2STRING_FEATURE_NAME = "featureFlag.mapBooleanToString.enabled";
 	public static final String KEYWORD_LOWER_FEATURE_NAME = "featureFlag.keywordLower.enabled";
 	public static final String BAG_OF_WORDS_FEATURE_NAME = "featureFlag.bagOfWords.enabled";
 	public static final String COLLABORATIONS_FEATURE_NAME = "collaborations-enabled";
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
index c09339260..5058a08fd 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
@@ -7,9 +7,13 @@ import java.util.Map;
 import java.util.Set;
 import lombok.Getter;
 import lombok.Setter;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
 
+import org.opengroup.osdu.core.common.feature.IFeatureFlag;
+import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
+
 @Configuration
 @ConfigurationProperties(prefix = "schema.converter")
 @Getter
@@ -23,6 +27,8 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
     private Set<String> processedArraysTypes = getDefaultArraysTypesForProcessing();
     private String defaultObjectArraysType = getObjectArraysDefaultType();
 
+    @Autowired
+    private IFeatureFlag featureFlagChecker;
 
     private Set<String> getDefaultSkippedDefinitions() {
         return new HashSet<>(Arrays.asList("AbstractAnyCrsFeatureCollection",
@@ -46,11 +52,16 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
     private Map<String, String> getDefaultPrimitiveTypesMap() {
         Map<String, String> defaultPrimitiveTypesMap = new HashMap<>();
 
-        // in the earlier versions boolean was translated to bool and 
-        // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
-        // in some places boolean is still presented as bool so here both are normalized to boolean
-        defaultPrimitiveTypesMap.put("boolean", "boolean");
-        defaultPrimitiveTypesMap.put("bool", "boolean");
+        if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)) {
+            // in the earlier versions boolean was translated to bool and
+            // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
+            // in some places boolean is still presented as bool so here both are normalized to boolean
+            defaultPrimitiveTypesMap.put("boolean", "boolean");
+            defaultPrimitiveTypesMap.put("bool", "boolean");
+        } else {
+            defaultPrimitiveTypesMap.put("boolean", "bool");
+        }
+
         defaultPrimitiveTypesMap.put("number", "double");
         defaultPrimitiveTypesMap.put("date-time", "datetime");
         defaultPrimitiveTypesMap.put("date", "datetime");
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
index 478448df0..88ae2eb82 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
@@ -30,12 +30,20 @@ import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
+import org.opengroup.osdu.core.common.feature.IFeatureFlag;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 
 public class PropertiesProcessorTest {
 
     private static final String PATH = "given_path";
     private static final String DEFINITIONS_PREFIX = "#/definitions/";
 
+    @Autowired
+    private IFeatureFlag featureFlagChecker;
+
     @Test
     public void should_fail_on_bad_reference_definition() {
         PropertiesProcessor propertiesProcessor = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig());
@@ -121,7 +129,8 @@ public class PropertiesProcessorTest {
 
         String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
                 .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
-        assertEquals("{path=" + PATH + ", kind=boolean}", res);
+        String preferredType = (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME))?"string":"boolean";
+        assertEquals("{{path=${PATH}, kind=${preferredType}}}", res);
     }
 
     @Test
@@ -246,4 +255,4 @@ public class PropertiesProcessorTest {
             .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
         assertEquals("{path="+ PATH + ", kind=[]int}",res);
     }
-}
\ No newline at end of file
+}
-- 
GitLab


From 36e71a65c734d8459820aa6e202980b9e366a53d Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Tue, 1 Oct 2024 16:11:39 -0400
Subject: [PATCH 05/18] use existing Schema config object

(cherry picked from commit 8dd87b274662f44c451490bf71278158fac07ffc)
---
 .../schema/converter/PropertiesProcessor.java |  20 +-
 .../Generated/file/File.1.0.0.json.FF.res     |  49 +++
 .../wks/slb_wke_wellbore.json.FF.res          | 357 ++++++++++++++++++
 .../src/main/resources/application.properties |   1 +
 .../src/main/resources/application.properties |   1 +
 .../src/main/resources/application.properties |   1 +
 .../src/main/resources/application.properties |   1 +
 7 files changed, 419 insertions(+), 11 deletions(-)
 create mode 100644 indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.FF.res
 create mode 100644 indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.FF.res

diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessor.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessor.java
index 45a13b37f..0a84da41d 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessor.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessor.java
@@ -14,6 +14,7 @@
 
 package org.opengroup.osdu.indexer.schema.converter;
 
+import lombok.Getter;
 import org.apache.http.HttpStatus;
 import org.opengroup.osdu.core.common.Constants;
 import org.opengroup.osdu.core.common.model.http.AppException;
@@ -36,7 +37,7 @@ import java.util.stream.Stream;
 
 public class PropertiesProcessor {
 
-    private SchemaConverterConfig schemaConverterConfig;
+    private final SchemaConverterConfig schemaConverterConfig;
 
     private static final String TYPE_KEY = "type";
     private static final String DEF_PREFIX = "#/definitions/";
@@ -47,6 +48,7 @@ public class PropertiesProcessor {
     private final String pathPrefix;
     private final String pathPrefixWithDot;
 
+    @Getter
     private final List<String> errors = new LinkedList<>();
 
     public PropertiesProcessor(Definitions definitions, SchemaConverterConfig schemaConverterConfig) {
@@ -124,10 +126,6 @@ public class PropertiesProcessor {
         return properties.entrySet().stream().flatMap(this::processPropertyEntry);
     }
 
-    public List<String> getErrors() {
-        return errors;
-    }
-
     private String getDefinitionIdentity(String definitionSubRef) {
         String[] components = definitionSubRef.split(":");
         switch (components.length) {
@@ -208,7 +206,7 @@ public class PropertiesProcessor {
 
             if (Objects.nonNull(entry.getValue().getProperties())) {
                 PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey()
-                        , new SchemaConverterPropertiesConfig());
+                        , schemaConverterConfig);
                 Stream<Map<String, Object>> result = entry.getValue().getProperties().entrySet().stream().flatMap(propertiesProcessor::processPropertyEntry);
                 errors.addAll(propertiesProcessor.getErrors());
                 return result;
@@ -216,7 +214,7 @@ public class PropertiesProcessor {
 
             if (Objects.nonNull(entry.getValue().getRef())) {
                 PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions
-                        , pathPrefixWithDot + entry.getKey(), new SchemaConverterPropertiesConfig());
+                        , pathPrefixWithDot + entry.getKey(), schemaConverterConfig);
                 Stream<Map<String, Object>> refResult = propertiesProcessor.processRef(entry.getValue().getRef());
                 errors.addAll(propertiesProcessor.getErrors());
                 return refResult;
@@ -238,7 +236,7 @@ public class PropertiesProcessor {
                 indexHint.getOrDefault(TYPE_KEY, schemaConverterConfig.getDefaultObjectArraysType());
 
         if (schemaConverterConfig.getProcessedArraysTypes().contains(indexingType)) {
-            PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, new SchemaConverterPropertiesConfig());
+            PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, schemaConverterConfig);
 
             Stream<Map<String, Object>> propertiesStream = Stream.empty();
 
@@ -265,7 +263,7 @@ public class PropertiesProcessor {
 
         if (Objects.nonNull(entry.getValue().getAllOf())) {
             PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey()
-                    , new SchemaConverterPropertiesConfig());
+                    , schemaConverterConfig);
 
             ofItems = entry.getValue().getAllOf().stream().flatMap(propertiesProcessor::processItem);
             errors.addAll(propertiesProcessor.getErrors());
@@ -273,7 +271,7 @@ public class PropertiesProcessor {
 
         if (Objects.nonNull(entry.getValue().getAnyOf())) {
             PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey()
-                    , new SchemaConverterPropertiesConfig());
+                    , schemaConverterConfig);
 
             ofItems = Stream.concat(Optional.ofNullable(ofItems).orElseGet(Stream::empty),
                     entry.getValue().getAnyOf().stream().flatMap(propertiesProcessor::processItem));
@@ -282,7 +280,7 @@ public class PropertiesProcessor {
 
         if (Objects.nonNull(entry.getValue().getOneOf())) {
             PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey()
-                    , new SchemaConverterPropertiesConfig());
+                    , schemaConverterConfig);
 
             ofItems = Stream.concat(Optional.ofNullable(ofItems).orElseGet(Stream::empty),
                     entry.getValue().getOneOf().stream().flatMap(propertiesProcessor::processItem));
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.FF.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.FF.res
new file mode 100644
index 000000000..c354504c3
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.FF.res
@@ -0,0 +1,49 @@
+{
+  "kind": "osdu:osdu:Wellbore:1.0.0",
+  "schema": [
+    {
+      "kind": "link",
+      "path": "SchemaFormatTypeID"
+    },
+    {
+      "kind": "string",
+      "path": "PreloadFilePath"
+    },
+    {
+      "kind": "string",
+      "path": "FileSource"
+    },
+    {
+      "kind": "int",
+      "path": "FileSize"
+    },
+    {
+      "kind": "link",
+      "path": "EncodingFormatTypeID"
+    },
+    {
+      "kind": "string",
+      "path": "Endian"
+    },
+    {
+      "kind": "boolean",
+      "path": "LossyCompressionIndicator"
+    },
+    {
+      "kind": "link",
+      "path": "CompressionMethodTypeID"
+    },
+    {
+      "kind": "double",
+      "path": "CompressionLevel"
+    },
+    {
+      "kind": "string",
+      "path": "Checksum"
+    },
+    {
+      "kind": "[]object",
+      "path": "VectorHeaderMapping"
+    }
+  ]
+}
diff --git a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.FF.res b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.FF.res
new file mode 100644
index 000000000..37d499f5d
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.FF.res
@@ -0,0 +1,357 @@
+{
+  "kind": "slb:wks:wellbore:1.0.6",
+  "schema": [
+    {
+      "kind": "string",
+      "path": "airGap.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "airGap.value"
+    },
+    {
+      "kind": "string",
+      "path": "block"
+    },
+    {
+      "kind": "string",
+      "path": "country"
+    },
+    {
+      "kind": "string",
+      "path": "county"
+    },
+    {
+      "kind": "datetime",
+      "path": "dateCreated"
+    },
+    {
+      "kind": "datetime",
+      "path": "dateModified"
+    },
+    {
+      "kind": "string",
+      "path": "drillingDaysTarget.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "drillingDaysTarget.value"
+    },
+    {
+      "kind": "string",
+      "path": "elevationReference.elevationFromMsl.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "elevationReference.elevationFromMsl.value"
+    },
+    {
+      "kind": "string",
+      "path": "elevationReference.name"
+    },
+    {
+      "kind": "[]link",
+      "path": "externalIds"
+    },
+    {
+      "kind": "string",
+      "path": "field"
+    },
+    {
+      "kind": "string",
+      "path": "formationAtTd"
+    },
+    {
+      "kind": "string",
+      "path": "formationProjected"
+    },
+    {
+      "kind": "boolean",
+      "path": "hasAchievedTotalDepth"
+    },
+    {
+      "kind": "boolean",
+      "path": "isActive"
+    },
+    {
+      "kind": "string",
+      "path": "kickOffMd.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "kickOffMd.value"
+    },
+    {
+      "kind": "string",
+      "path": "kickOffTvd.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "kickOffTvd.value"
+    },
+    {
+      "kind": "core:dl:geoshape:1.0.0",
+      "path": "locationWGS84"
+    },
+    {
+      "kind": "string",
+      "path": "name"
+    },
+    {
+      "kind": "string",
+      "path": "operator"
+    },
+    {
+      "kind": "datetime",
+      "path": "permitDate"
+    },
+    {
+      "kind": "string",
+      "path": "permitNumber"
+    },
+    {
+      "kind": "string",
+      "path": "plssLocation.aliquotPart"
+    },
+    {
+      "kind": "string",
+      "path": "plssLocation.range"
+    },
+    {
+      "kind": "int",
+      "path": "plssLocation.section"
+    },
+    {
+      "kind": "string",
+      "path": "plssLocation.township"
+    },
+    {
+      "kind": "string",
+      "path": "propertyDictionary"
+    },
+    {
+      "kind": "double",
+      "path": "relationships.definitiveTimeDepthRelation.confidence"
+    },
+    {
+      "kind": "link",
+      "path": "relationships.definitiveTimeDepthRelation.id"
+    },
+    {
+      "kind": "string",
+      "path": "relationships.definitiveTimeDepthRelation.name"
+    },
+    {
+      "kind": "long",
+      "path": "relationships.definitiveTimeDepthRelation.version"
+    },
+    {
+      "kind": "double",
+      "path": "relationships.definitiveTrajectory.confidence"
+    },
+    {
+      "kind": "link",
+      "path": "relationships.definitiveTrajectory.id"
+    },
+    {
+      "kind": "string",
+      "path": "relationships.definitiveTrajectory.name"
+    },
+    {
+      "kind": "long",
+      "path": "relationships.definitiveTrajectory.version"
+    },
+    {
+      "kind": "double",
+      "path": "relationships.tieInWellbore.confidence"
+    },
+    {
+      "kind": "link",
+      "path": "relationships.tieInWellbore.id"
+    },
+    {
+      "kind": "string",
+      "path": "relationships.tieInWellbore.name"
+    },
+    {
+      "kind": "long",
+      "path": "relationships.tieInWellbore.version"
+    },
+    {
+      "kind": "double",
+      "path": "relationships.well.confidence"
+    },
+    {
+      "kind": "link",
+      "path": "relationships.well.id"
+    },
+    {
+      "kind": "string",
+      "path": "relationships.well.name"
+    },
+    {
+      "kind": "long",
+      "path": "relationships.well.version"
+    },
+    {
+      "kind": "string",
+      "path": "shape"
+    },
+    {
+      "kind": "datetime",
+      "path": "spudDate"
+    },
+    {
+      "kind": "string",
+      "path": "state"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthMd.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthMd.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthMdDriller.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthMdDriller.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthMdPlanned.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthMdPlanned.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthMdSubSeaPlanned.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthMdSubSeaPlanned.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthProjectedMd.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthProjectedMd.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthTvd.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthTvd.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthTvdDriller.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthTvdDriller.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthTvdPlanned.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthTvdPlanned.value"
+    },
+    {
+      "kind": "string",
+      "path": "totalDepthTvdSubSeaPlanned.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "totalDepthTvdSubSeaPlanned.value"
+    },
+    {
+      "kind": "string",
+      "path": "uwi"
+    },
+    {
+      "kind": "string",
+      "path": "wellHeadElevation.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadElevation.value"
+    },
+    {
+      "kind": "string",
+      "path": "wellHeadGeographic.crsKey"
+    },
+    {
+      "kind": "string",
+      "path": "wellHeadGeographic.elevationFromMsl.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadGeographic.elevationFromMsl.value"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadGeographic.latitude"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadGeographic.longitude"
+    },
+    {
+      "kind": "string",
+      "path": "wellHeadProjected.crsKey"
+    },
+    {
+      "kind": "string",
+      "path": "wellHeadProjected.elevationFromMsl.unitKey"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadProjected.elevationFromMsl.value"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadProjected.x"
+    },
+    {
+      "kind": "double",
+      "path": "wellHeadProjected.y"
+    },
+    {
+      "kind": "core:dl:geopoint:1.0.0",
+      "path": "wellHeadWgs84"
+    },
+    {
+      "kind": "string",
+      "path": "wellboreNumberGovernment"
+    },
+    {
+      "kind": "string",
+      "path": "wellboreNumberOperator"
+    },
+    {
+      "kind": "string",
+      "path": "wellborePurpose"
+    },
+    {
+      "kind": "string",
+      "path": "wellboreStatus"
+    },
+    {
+      "kind": "string",
+      "path": "wellboreType"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/provider/indexer-aws/src/main/resources/application.properties b/provider/indexer-aws/src/main/resources/application.properties
index d6180a3d8..10ea1892a 100644
--- a/provider/indexer-aws/src/main/resources/application.properties
+++ b/provider/indexer-aws/src/main/resources/application.properties
@@ -85,6 +85,7 @@ spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.Sec
 
 # Feature flag settings
 featureFlag.strategy=appProperty
+featureFlag.mapBooleanToString.enabled=false
 featureFlag.asIngestedCoordinates.enabled=true
 featureFlag.keywordLower.enabled=true
 featureFlag.bagOfWords.enabled=true
diff --git a/provider/indexer-azure/src/main/resources/application.properties b/provider/indexer-azure/src/main/resources/application.properties
index 08b7c659d..5a84c72c3 100644
--- a/provider/indexer-azure/src/main/resources/application.properties
+++ b/provider/indexer-azure/src/main/resources/application.properties
@@ -105,6 +105,7 @@ redis.database=${REDIS_DATABASE}
 
 # Feature flag settings
 featureFlag.strategy=${featureFlag_appProperty:appProperty}
+featureFlag.mapBooleanToString.enabled=${featureFlag_mapBooleanToString_enabled:false}
 featureFlag.asIngestedCoordinates.enabled=${featureFlag_asIngestedCoordinates_enabled:true}
 featureFlag.keywordLower.enabled=${featureFlag_keywordLower_enabled:true}
 featureFlag.bagOfWords.enabled=${featureFlag_bagOfWords_enabled:true}
diff --git a/provider/indexer-gc/src/main/resources/application.properties b/provider/indexer-gc/src/main/resources/application.properties
index f25237671..b4ad62851 100644
--- a/provider/indexer-gc/src/main/resources/application.properties
+++ b/provider/indexer-gc/src/main/resources/application.properties
@@ -66,6 +66,7 @@ reindex-topic-name=reindex
 # Feature flag settings
 featureFlag.strategy=dataPartition
 featureFlag.xCollaboration.enabled=false
+featureFlag.mapBooleanToString.enabled=false
 featureFlag.asIngestedCoordinates.enabled=true
 featureFlag.keywordLower.enabled=true
 featureFlag.bagOfWords.enabled=true
diff --git a/provider/indexer-ibm/src/main/resources/application.properties b/provider/indexer-ibm/src/main/resources/application.properties
index d0e2d06b3..6c205933b 100644
--- a/provider/indexer-ibm/src/main/resources/application.properties
+++ b/provider/indexer-ibm/src/main/resources/application.properties
@@ -71,6 +71,7 @@ ELASTIC_USER_PASSWORD=REPLACE_ME:REPLACE_ME
 
 # Feature flag settings
 featureFlag.strategy=appProperty
+featureFlag.mapBooleanToString.enabled=false
 featureFlag.asIngestedCoordinates.enabled=false
 featureFlag.keywordLower.enabled=false
 featureFlag.bagOfWords.enabled=false
-- 
GitLab


From bf0fb1a3d975b906f7356d475e9fcd7abed50796 Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Tue, 1 Oct 2024 16:13:52 -0400
Subject: [PATCH 06/18] facilitate testing

(cherry picked from commit 5762f5bc975efbb36b73427f1767f3fb2b6c9704)
---
 .../indexer/schema/converter/SchemaToStorageFormatImpl.java | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java
index 7631df84b..2b4f48d50 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java
@@ -49,10 +49,16 @@ public class SchemaToStorageFormatImpl implements SchemaToStorageFormat {
 
     @Inject
     public SchemaToStorageFormatImpl(ObjectMapper objectMapper, JaxRsDpsLog log, SchemaConverterConfig schemaConverterConfig) {
+        this(objectMapper, log, schemaConverterConfig, null);
+    }
+
+    public SchemaToStorageFormatImpl(ObjectMapper objectMapper, JaxRsDpsLog log, SchemaConverterConfig schemaConverterConfig,
+                                     VirtualPropertiesSchemaCache virtualPropertiesSchemaCache) {
         Preconditions.checkNotNull(objectMapper, "objectMapper cannot be null");
 
         this.objectMapper = objectMapper;
         this.schemaConverterConfig = schemaConverterConfig;
+        if (virtualPropertiesSchemaCache != null) this.virtualPropertiesSchemaCache = virtualPropertiesSchemaCache;
     }
 
     @Override
-- 
GitLab


From 322a9256973e3ae070111c1d4de84dd51683af7d Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Tue, 1 Oct 2024 16:20:20 -0400
Subject: [PATCH 07/18] facilitate testing

(cherry picked from commit 9c6e902b5634e863db7b9bfc635c9bb239d2500c)
---
 .../SchemaConverterPropertiesConfig.java      | 36 ++++++++++++++-----
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
index 5058a08fd..077ae9925 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
@@ -9,27 +9,47 @@ import lombok.Getter;
 import lombok.Setter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
 
 import org.opengroup.osdu.core.common.feature.IFeatureFlag;
+import org.springframework.stereotype.Component;
+
 import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 
-@Configuration
+@Component
 @ConfigurationProperties(prefix = "schema.converter")
 @Getter
 @Setter
 public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
 
-    private Set<String> skippedDefinitions = getDefaultSkippedDefinitions();
-    private Set<String> supportedArrayTypes = getDefaultSupportedArrayTypes();
-    private Map<String, String> specialDefinitionsMap = getDefaultSpecialDefinitionsMap();
-    private Map<String, String> primitiveTypesMap = getDefaultPrimitiveTypesMap();
-    private Set<String> processedArraysTypes = getDefaultArraysTypesForProcessing();
-    private String defaultObjectArraysType = getObjectArraysDefaultType();
+    private Set<String> skippedDefinitions;
+    private Set<String> supportedArrayTypes;
+    private Map<String, String> specialDefinitionsMap;
+    private Map<String, String> primitiveTypesMap;
+    private Set<String> processedArraysTypes;
+    private String defaultObjectArraysType;
 
     @Autowired
     private IFeatureFlag featureFlagChecker;
 
+    public SchemaConverterPropertiesConfig(IFeatureFlag flag) {
+        if (flag != null) featureFlagChecker=flag;
+        skippedDefinitions = getDefaultSkippedDefinitions();
+        supportedArrayTypes = getDefaultSupportedArrayTypes();
+        specialDefinitionsMap = getDefaultSpecialDefinitionsMap();
+        primitiveTypesMap = getDefaultPrimitiveTypesMap();
+        processedArraysTypes = getDefaultArraysTypesForProcessing();
+        defaultObjectArraysType = getObjectArraysDefaultType();
+    }
+
+    public void resetToDefault() {
+        skippedDefinitions = getDefaultSkippedDefinitions();
+        supportedArrayTypes = getDefaultSupportedArrayTypes();
+        specialDefinitionsMap = getDefaultSpecialDefinitionsMap();
+        primitiveTypesMap = getDefaultPrimitiveTypesMap();
+        processedArraysTypes = getDefaultArraysTypesForProcessing();
+        defaultObjectArraysType = getObjectArraysDefaultType();
+    }
+
     private Set<String> getDefaultSkippedDefinitions() {
         return new HashSet<>(Arrays.asList("AbstractAnyCrsFeatureCollection",
             "anyCrsGeoJsonFeatureCollection"));
-- 
GitLab


From 78579b4489ff88e2cf123df1e12a7faaf9bf9f0a Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Tue, 1 Oct 2024 16:33:55 -0400
Subject: [PATCH 08/18] set feature flag testing

(cherry picked from commit 47e6c6ff25c746485fc9fa33491d969a09c6e071)
---
 .../converter/PropertiesProcessorTest.java    | 79 +++++++++++++------
 .../SchemaToStorageFormatImplTest.java        | 34 ++++++--
 .../StorageIndexerPayloadMapperTest.java      |  7 +-
 .../Generated/file/File.1.0.0.json.res        |  2 +-
 .../converter/wks/slb_wke_wellbore.json.res   |  4 +-
 5 files changed, 92 insertions(+), 34 deletions(-)

diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
index 88ae2eb82..90a141eb6 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
@@ -15,7 +15,9 @@
 package org.opengroup.osdu.indexer.schema.converter;
 
 import com.google.common.collect.ImmutableMap;
+import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
 import org.opengroup.osdu.indexer.schema.converter.config.SchemaConverterPropertiesConfig;
@@ -25,48 +27,66 @@ import org.opengroup.osdu.indexer.schema.converter.tags.Definitions;
 import org.opengroup.osdu.indexer.schema.converter.tags.Items;
 import org.opengroup.osdu.indexer.schema.converter.tags.TypeProperty;
 
+import java.io.IOException;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
 import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 import org.opengroup.osdu.core.common.feature.IFeatureFlag;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
-
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@Import({IFeatureFlag.class})
+@ContextConfiguration(classes = {PropertiesProcessorTest.class, IFeatureFlag.class})
+@SpringBootTest(classes = {IFeatureFlag.class})
 public class PropertiesProcessorTest {
 
     private static final String PATH = "given_path";
     private static final String DEFINITIONS_PREFIX = "#/definitions/";
 
-    @Autowired
+    @MockBean
     private IFeatureFlag featureFlagChecker;
 
+    private SchemaConverterPropertiesConfig schemaConverterConfig;
+
+    @Before
+    public void setup() throws IOException {
+        initMocks(this);
+        schemaConverterConfig = new SchemaConverterPropertiesConfig(featureFlagChecker);
+    }
+
     @Test
     public void should_fail_on_bad_reference_definition() {
-        PropertiesProcessor propertiesProcessor = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig());
+        PropertiesProcessor propertiesProcessor = new PropertiesProcessor(Mockito.mock(Definitions.class),
+                schemaConverterConfig);
         propertiesProcessor.processRef(DEFINITIONS_PREFIX + "unknownDefinition");
         assertEquals(1, propertiesProcessor.getErrors().size());
     }
 
     @Test
     public void should_fail_on_wrong_definition_format() {
-        PropertiesProcessor propertiesProcessor = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig());
+        PropertiesProcessor propertiesProcessor = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig);
         propertiesProcessor.processRef("unknownDefinition");
         assertEquals(1, propertiesProcessor.getErrors().size());
     }
 
     @Test
     public void should_not_process_special_reference() {
-        assertFalse(new PropertiesProcessor(null, new SchemaConverterPropertiesConfig())
+        assertFalse(new PropertiesProcessor(null, schemaConverterConfig)
                 .processRef(DEFINITIONS_PREFIX + "a:b:anyCrsGeoJsonFeatureCollection:1.0.0").findAny().isPresent());
     }
 
     @Test
     public void should_return_special_type() {
-        String res = new PropertiesProcessor(null, PATH, new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(null, PATH, schemaConverterConfig)
                 .processRef(DEFINITIONS_PREFIX + "a:b:core_dl_geopoint:1.0.0").map(Object::toString).reduce("", String::concat);
         assertEquals("{path=" + PATH + ", kind=core:dl:geopoint:1.0.0}", res);
     }
@@ -90,7 +110,7 @@ public class PropertiesProcessorTest {
         String defName = "a:b:defName:1.0.0";
         definitions.add(defName, definition);
 
-        String res = new PropertiesProcessor(definitions, PATH, new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(definitions, PATH, schemaConverterConfig)
                 .processRef(DEFINITIONS_PREFIX + defName).map(Object::toString).reduce("", String::concat);
         assertEquals(res, "{path="+ PATH + "." + propertyName + ", kind=string}");
     }
@@ -108,15 +128,29 @@ public class PropertiesProcessorTest {
         properties.put(PATH, property);
         allOfItem.setProperties(properties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
                 .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
         assertEquals("{path=" + PATH + ", kind=int}", res);
     }
 
     @Test
-    public void should_return_boolean_from_boolean_item() {
+    public void should_return_boolean_from_boolean_item_FF_OFF() {
         // in the earlier versions boolean was translated to bool and 
         // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
+        internal_should_return_boolean_from_boolean_item(false);
+    }
+
+    @Test
+    public void should_return_boolean_from_boolean_item_FF_ON() {
+        // in the earlier versions boolean was translated to bool and
+        // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
+        internal_should_return_boolean_from_boolean_item(true);
+    }
+
+    private void internal_should_return_boolean_from_boolean_item(boolean ffFlag) {
+        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(ffFlag);
+        when(schemaConverterConfig.getFeatureFlagChecker().isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(ffFlag);
+        schemaConverterConfig.resetToDefault();
         AllOfItem allOfItem = new AllOfItem();
         JaxRsDpsLog log = Mockito.mock(JaxRsDpsLog.class);
 
@@ -127,10 +161,11 @@ public class PropertiesProcessorTest {
         properties.put(PATH, property);
         allOfItem.setProperties(properties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
-                .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
-        String preferredType = (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME))?"string":"boolean";
-        assertEquals("{{path=${PATH}, kind=${preferredType}}}", res);
+        assertEquals(
+                "{path="+PATH+", kind="+ (ffFlag?"boolean":"bool")+"}",
+                new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
+                        .processItem(allOfItem).map(Object::toString).reduce("", String::concat)
+        );
     }
 
     @Test
@@ -146,9 +181,9 @@ public class PropertiesProcessorTest {
         properties.put(PATH, property);
         allOfItem.setProperties(properties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
                 .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
-        assertEquals("{path=" + PATH + ", kind=boolean}", res);
+        assertEquals("{path=" + PATH + ", kind=bool}", res);
     }
 
     @Test
@@ -174,7 +209,7 @@ public class PropertiesProcessorTest {
         AllOfItem allOfItem = new AllOfItem();
         allOfItem.setProperties(allOfItemProperties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
             .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
         assertEquals("{path="+ PATH + ", kind=nested, properties=[{path="+ PATH + ", kind=int}]}",res);
     }
@@ -202,7 +237,7 @@ public class PropertiesProcessorTest {
         AllOfItem allOfItem = new AllOfItem();
         allOfItem.setProperties(allOfItemProperties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
             .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
         assertEquals("{path="+ PATH + ", kind=flattened}",res);
     }
@@ -229,7 +264,7 @@ public class PropertiesProcessorTest {
         AllOfItem allOfItem = new AllOfItem();
         allOfItem.setProperties(allOfItemProperties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
             .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
         assertEquals("{path="+ PATH + ", kind=[]object}",res);
     }
@@ -251,7 +286,7 @@ public class PropertiesProcessorTest {
         AllOfItem allOfItem = new AllOfItem();
         allOfItem.setProperties(allOfItemProperties);
 
-        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), new SchemaConverterPropertiesConfig())
+        String res = new PropertiesProcessor(Mockito.mock(Definitions.class), schemaConverterConfig)
             .processItem(allOfItem).map(Object::toString).reduce("", String::concat);
         assertEquals("{path="+ PATH + ", kind=[]int}",res);
     }
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
index ea24acdc4..d4141cd80 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
@@ -16,6 +16,7 @@ package org.opengroup.osdu.indexer.schema.converter;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.inject.Inject;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -23,10 +24,14 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.opengroup.osdu.core.common.feature.IFeatureFlag;
 import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
 import org.opengroup.osdu.indexer.cache.partitionsafe.VirtualPropertiesSchemaCache;
 import org.opengroup.osdu.indexer.schema.converter.config.SchemaConverterPropertiesConfig;
 import org.opengroup.osdu.indexer.schema.converter.exeption.SchemaProcessingException;
+import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
+
+import org.springframework.context.annotation.Configuration;
 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 import org.springframework.test.context.junit4.SpringRunner;
 
@@ -42,10 +47,10 @@ import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.*;
 
 @RunWith(SpringRunner.class)
+@Configuration
 public class SchemaToStorageFormatImplTest {
 
     private static final String KIND = "KIND_VAL";
@@ -54,17 +59,22 @@ public class SchemaToStorageFormatImplTest {
 
     private JaxRsDpsLog jaxRsDpsLog = Mockito.mock(JaxRsDpsLog.class);
 
-    @InjectMocks
-    private SchemaToStorageFormatImpl schemaToStorageFormatImpl
-            = new SchemaToStorageFormatImpl(objectMapper, jaxRsDpsLog
-            , new SchemaConverterPropertiesConfig());
+    private SchemaToStorageFormatImpl schemaToStorageFormatImpl;
 
-    @Mock
     private VirtualPropertiesSchemaCache virtualPropertiesSchemaCache;
 
+    private IFeatureFlag featureFlag;
+
     @Before
     public void init() {
         MockitoAnnotations.initMocks(this);
+        featureFlag = Mockito.mock(IFeatureFlag.class);
+        when(featureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
+        virtualPropertiesSchemaCache = Mockito.mock(VirtualPropertiesSchemaCache.class);
+//        when(virtualPropertiesSchemaCache.put(Mockito.anyString(), Mockito.any())).doNothing();
+        schemaToStorageFormatImpl
+                = new SchemaToStorageFormatImpl(objectMapper, jaxRsDpsLog,
+                    new SchemaConverterPropertiesConfig(featureFlag), virtualPropertiesSchemaCache);
     }
 
     @Test
@@ -175,11 +185,19 @@ public class SchemaToStorageFormatImplTest {
         String json = getSchemaFromSchemaService(filename);
 
         Map<String, Object> converted = schemaToStorageFormatImpl.convertToMap(json, kind);
-        Map<String, Object> expected = getStorageSchema(filename + ".res");
+        String resource = filename +
+                ((featureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME))?".FF":"")+
+                ".res";
+        if (!existsStorageSchema(resource)) resource = filename + ".res";
+        Map<String, Object> expected = getStorageSchema(resource);
 
         compareSchemas(expected, converted, filename);
     }
 
+    private boolean existsStorageSchema(String s) {
+        return null != this.getClass().getResource(s);
+    }
+
     private Map<String, Object> getStorageSchema(String s) {
 
         TypeReference<Map<String, Object>> typeRef
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
index ba5696d33..79a7c9602 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
@@ -40,6 +40,7 @@ import java.util.*;
 
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.when;
+import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 import static org.opengroup.osdu.indexer.model.Constants.AS_INGESTED_COORDINATES_FEATURE_NAME;
 
 @RunWith(SpringRunner.class)
@@ -48,7 +49,8 @@ import static org.opengroup.osdu.indexer.model.Constants.AS_INGESTED_COORDINATES
         GeometryDecimator.class, PointExtractor.class, GeometryConversionService.class, FeatureFlagCache.class,
         DpsHeaders.class, JobStatus.class, SchemaConverterPropertiesConfig.class, JaxRsDpsLog.class,
         ServiceAccountJwtClientMock.class, VirtualPropertiesSchemaCacheMock.class, VirtualPropertiesSchemaCache.class, RequestInfoMock.class,
-        IFeatureFlag.class, StringParser.class})
+        IFeatureFlag.class, StringParser.class}
+)
 public class StorageIndexerPayloadMapperTest {
 
     public static final String FIRST_OBJECT_INNER_PROPERTY = "FirstObjectInnerProperty";
@@ -282,6 +284,7 @@ public class StorageIndexerPayloadMapperTest {
     @Test
     public void mapDataPayloadTestAsIngestedCoordinates() {
         when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
+        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -318,6 +321,7 @@ public class StorageIndexerPayloadMapperTest {
     @Test
     public void mapDataPayloadTestAsIngestedCoordinatesGeographicBottomHoleLocationAndSpatialLocation() {
         when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
+        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("GeographicBottomHoleLocation.AsIngestedCoordinates", "SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -381,6 +385,7 @@ public class StorageIndexerPayloadMapperTest {
     @Test
     public void mapDataPayloadTestAsIngestedCoordinatesWithEmptyZCoordinate() {
         when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
+        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res
index c354504c3..44a5a89ec 100644
--- a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/file/File.1.0.0.json.res
@@ -26,7 +26,7 @@
       "path": "Endian"
     },
     {
-      "kind": "boolean",
+      "kind": "bool",
       "path": "LossyCompressionIndicator"
     },
     {
diff --git a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
index 37d499f5d..e8d480d2f 100644
--- a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
+++ b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
@@ -70,7 +70,7 @@
       "path": "hasAchievedTotalDepth"
     },
     {
-      "kind": "boolean",
+      "kind": "bool",
       "path": "isActive"
     },
     {
@@ -354,4 +354,4 @@
       "path": "wellboreType"
     }
   ]
-}
\ No newline at end of file
+}
-- 
GitLab


From c54becf370bba5c9d7539aae49871022b3a577a5 Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Thu, 3 Oct 2024 11:17:47 -0400
Subject: [PATCH 09/18] test feature flag on and off

(cherry picked from commit 1528d77dabd9d43629d1364bcb58e38f628b2f2c)
---
 .../SchemaToStorageFormatImplTest.java        | 37 ++++++++-----
 .../Generated/type/Type.1.0.0.json.FF.res     | 41 ++++++++++++++
 .../Generated/type/Type.1.0.0.json.res        |  4 +-
 .../WorkProduct.1.0.0.json.FF.res             | 53 +++++++++++++++++++
 .../work-product/WorkProduct.1.0.0.json.res   |  6 +--
 5 files changed, 124 insertions(+), 17 deletions(-)
 create mode 100644 indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.FF.res
 create mode 100644 indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.FF.res

diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
index d4141cd80..d1849ad57 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
@@ -16,12 +16,9 @@ package org.opengroup.osdu.indexer.schema.converter;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import jakarta.inject.Inject;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.opengroup.osdu.core.common.feature.IFeatureFlag;
@@ -65,16 +62,16 @@ public class SchemaToStorageFormatImplTest {
 
     private IFeatureFlag featureFlag;
 
+    private SchemaConverterPropertiesConfig schemaConverterPropertiesConfig;
     @Before
     public void init() {
         MockitoAnnotations.initMocks(this);
         featureFlag = Mockito.mock(IFeatureFlag.class);
-        when(featureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
         virtualPropertiesSchemaCache = Mockito.mock(VirtualPropertiesSchemaCache.class);
-//        when(virtualPropertiesSchemaCache.put(Mockito.anyString(), Mockito.any())).doNothing();
+        schemaConverterPropertiesConfig = new SchemaConverterPropertiesConfig(featureFlag);
         schemaToStorageFormatImpl
-                = new SchemaToStorageFormatImpl(objectMapper, jaxRsDpsLog,
-                    new SchemaConverterPropertiesConfig(featureFlag), virtualPropertiesSchemaCache);
+            = new SchemaToStorageFormatImpl(objectMapper, jaxRsDpsLog,
+                schemaConverterPropertiesConfig, virtualPropertiesSchemaCache);
     }
 
     @Test
@@ -171,23 +168,39 @@ public class SchemaToStorageFormatImplTest {
     }
 
     @Test
-    public void folderPassed() throws URISyntaxException, IOException {
+    public void folderPassedWithFF() throws URISyntaxException, IOException {
+        folderPassed(true);
+    }
+
+    @Test
+    public void folderPassedFFOff() throws URISyntaxException, IOException {
+        folderPassed(false);
+    }
 
+    public void folderPassed(boolean map2StringFF) throws URISyntaxException, IOException {
         String folder = "/converter/R3-json-schema";
         Path path = Paths.get(this.getClass().getResource(folder).toURI());
         Files.walk(path)
                 .filter(Files::isRegularFile)
                 .filter(f -> f.toString().endsWith(".json"))
-                .forEach(f -> testSingleFile(f.toString().replaceAll("\\\\", "/").substring(f.toString().replaceAll("\\\\", "/").indexOf(folder)), "osdu:osdu:Wellbore:1.0.0"));
+                .forEach(f -> testSingleFile(
+                        f.toString().replaceAll("\\\\", "/").substring(f.toString().replaceAll("\\\\", "/").indexOf(folder)),
+                        "osdu:osdu:Wellbore:1.0.0",
+                        map2StringFF
+                ));
     }
 
     private void testSingleFile(String filename, String kind) {
+        testSingleFile(filename, kind, false);
+    }
+
+    private void testSingleFile(String filename, String kind, boolean map2StringFF) {
+        when(featureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(map2StringFF);
+        schemaConverterPropertiesConfig.resetToDefault();
         String json = getSchemaFromSchemaService(filename);
 
         Map<String, Object> converted = schemaToStorageFormatImpl.convertToMap(json, kind);
-        String resource = filename +
-                ((featureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME))?".FF":"")+
-                ".res";
+        String resource = filename + (map2StringFF?".FF":"")+ ".res";
         if (!existsStorageSchema(resource)) resource = filename + ".res";
         Map<String, Object> expected = getStorageSchema(resource);
 
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.FF.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.FF.res
new file mode 100644
index 000000000..c2e7cffc4
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.FF.res
@@ -0,0 +1,41 @@
+{
+  "kind": "osdu:osdu:Wellbore:1.0.0",
+  "schema": [
+    {
+      "kind": "string",
+      "path": "Description"
+    },
+    {
+      "kind": "string",
+      "path": "Schema"
+    },
+    {
+      "kind": "[]string",
+      "path": "NaturalKeys"
+    },
+    {
+      "kind": "string",
+      "path": "SchemaID"
+    },
+    {
+      "kind": "string",
+      "path": "Name"
+    },
+    {
+      "kind": "string",
+      "path": "SchemaKind"
+    },
+    {
+      "kind": "boolean",
+      "path": "IsReferenceValueType"
+    },
+    {
+      "kind": "[]link",
+      "path": "GovernanceAuthorities"
+    },
+    {
+      "kind": "string",
+      "path": "GovernanceModel"
+    }
+  ]
+}
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res
index ad5d44bec..c2817db53 100644
--- a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/type/Type.1.0.0.json.res
@@ -26,7 +26,7 @@
       "path": "SchemaKind"
     },
     {
-      "kind": "boolean",
+      "kind": "bool",
       "path": "IsReferenceValueType"
     },
     {
@@ -38,4 +38,4 @@
       "path": "GovernanceModel"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.FF.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.FF.res
new file mode 100644
index 000000000..ea7b4ff22
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.FF.res
@@ -0,0 +1,53 @@
+{
+  "kind": "osdu:osdu:Wellbore:1.0.0",
+  "schema": [
+    {
+      "kind": "[]link",
+      "path": "Components"
+    },
+    {
+      "kind": "boolean",
+      "path": "IsExtendedLoad"
+    },
+    {
+      "kind": "boolean",
+      "path": "IsDiscoverable"
+    },
+    {
+      "kind": "string",
+      "path": "Name"
+    },
+    {
+      "kind": "string",
+      "path": "Description"
+    },
+    {
+      "kind": "datetime",
+      "path": "CreationDateTime"
+    },
+    {
+      "kind": "[]string",
+      "path": "Tags"
+    },
+    {
+      "kind": "string",
+      "path": "SubmitterName"
+    },
+    {
+      "kind": "[]string",
+      "path": "BusinessActivities"
+    },
+    {
+      "kind": "[]string",
+      "path": "AuthorIDs"
+    },
+    {
+      "kind": "[]string",
+      "path": "Annotations"
+    },
+    {
+       "kind": "[]object",
+       "path": "LineageAssertions"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res
index ea7b4ff22..d341d7f8d 100644
--- a/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res
+++ b/indexer-core/src/test/resources/converter/R3-json-schema/Generated/work-product/WorkProduct.1.0.0.json.res
@@ -6,11 +6,11 @@
       "path": "Components"
     },
     {
-      "kind": "boolean",
+      "kind": "bool",
       "path": "IsExtendedLoad"
     },
     {
-      "kind": "boolean",
+      "kind": "bool",
       "path": "IsDiscoverable"
     },
     {
@@ -50,4 +50,4 @@
        "path": "LineageAssertions"
     }
   ]
-}
\ No newline at end of file
+}
-- 
GitLab


From d799daccb4102a64ef6afdc73fa006dc1afd9075 Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Thu, 3 Oct 2024 14:03:04 -0400
Subject: [PATCH 10/18] test feature flag on and off in virtual properties

(cherry picked from commit 0038d03f041c5d1679ccff4912c8aa6f336ecef7)
---
 .../SchemaToStorageFormatImplTest.java        |  24 +-
 ...ched-virtual-properties-schema.json.FF.res | 340 +++++++++++++++++
 ...matched-virtual-properties-schema.json.res |   2 +-
 .../virtual-properties-schema.json.FF.res     | 343 ++++++++++++++++++
 .../virtual-properties-schema.json.res        |   2 +-
 .../converter/wks/slb_wke_wellbore.json.res   |   2 +-
 6 files changed, 706 insertions(+), 7 deletions(-)
 create mode 100644 indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.FF.res
 create mode 100644 indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.FF.res

diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
index d1849ad57..c4ec5697e 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
@@ -17,6 +17,7 @@ package org.opengroup.osdu.indexer.schema.converter;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
@@ -155,15 +156,30 @@ public class SchemaToStorageFormatImplTest {
     }
 
     @Test
-    public void virtualProperties() {
-        testSingleFile("/converter/index-virtual-properties/virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0");
+    @Ignore
+    public void virtualProperties_FFoff() {
+        testSingleFile("/converter/index-virtual-properties/virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0", false);
         verify(this.virtualPropertiesSchemaCache, times(1)).put(Mockito.anyString(), Mockito.any());
     }
 
     @Test
-    public void unmatchedVirtualProperties() {
+    public void virtualProperties_FFon() {
+        testSingleFile("/converter/index-virtual-properties/virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0", true);
+        verify(this.virtualPropertiesSchemaCache, times(1)).put(Mockito.anyString(), Mockito.any());
+    }
+
+    @Test
+    public void unmatchedVirtualProperties_FFon() {
+        // The actual property "data.Facility" does not exist for "data.VirtualProperties.DefaultName"
+        testSingleFile("/converter/index-virtual-properties/unmatched-virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0", true);
+        verify(this.virtualPropertiesSchemaCache, times(1)).put(Mockito.anyString(), Mockito.any());
+    }
+
+    @Test
+    @Ignore
+    public void unmatchedVirtualProperties_FFoff() {
         // The actual property "data.Facility" does not exist for "data.VirtualProperties.DefaultName"
-        testSingleFile("/converter/index-virtual-properties/unmatched-virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0");
+        testSingleFile("/converter/index-virtual-properties/unmatched-virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0", false);
         verify(this.virtualPropertiesSchemaCache, times(1)).put(Mockito.anyString(), Mockito.any());
     }
 
diff --git a/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.FF.res b/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.FF.res
new file mode 100644
index 000000000..91a70ee6e
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.FF.res
@@ -0,0 +1,340 @@
+{
+  "kind" : "osdu:wks:master-data--Wellbore:1.0.0",
+  "schema" : [ {
+    "path" : "ResourceHomeRegionID",
+    "kind" : "string"
+  }, {
+    "path" : "ResourceHostRegionIDs",
+    "kind" : "[]string"
+  }, {
+    "path" : "ResourceLifecycleStatus",
+    "kind" : "string"
+  }, {
+    "path" : "ResourceSecurityClassification",
+    "kind" : "string"
+  }, {
+    "path" : "ResourceCurationStatus",
+    "kind" : "string"
+  }, {
+    "path" : "ExistenceKind",
+    "kind" : "string"
+  }, {
+    "path" : "TechnicalAssuranceID",
+    "kind" : "string"
+  }, {
+    "path" : "Source",
+    "kind" : "string"
+  }, {
+    "path" : "NameAliases",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "AliasNameTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "AliasName",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "DefinitionOrganisationID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "SpatialLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "SpatialLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "SpatialLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "SpatialLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "SpatialLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "SpatialLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VersionCreationReason",
+    "kind" : "string"
+  }, {
+    "path" : "GeoContexts",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "GeoPoliticalEntityID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "BasinID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "FieldID",
+      "kind" : "string"
+    }, {
+      "path" : "PlayID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "ProspectID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "FacilityStates",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "FacilityStateTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    } ]
+  }, {
+    "path" : "FacilityID",
+    "kind" : "string"
+  }, {
+    "path" : "OperatingEnvironmentID",
+    "kind" : "string"
+  }, {
+    "path" : "FacilityNameAliases",
+    "kind" : "[]object"
+  }, {
+    "path" : "FacilityEvents",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "FacilityEventTypeID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "FacilitySpecifications",
+    "kind" : "flattened"
+  }, {
+    "path" : "DataSourceOrganisationID",
+    "kind" : "string"
+  }, {
+    "path" : "InitialOperatorID",
+    "kind" : "string"
+  }, {
+    "path" : "CurrentOperatorID",
+    "kind" : "string"
+  }, {
+    "path" : "FacilityOperators",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "FacilityOperatorID",
+      "kind" : "string"
+    }, {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "FacilityOperatorOrganisationID",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    } ]
+  }, {
+    "path" : "FacilityName",
+    "kind" : "string"
+  }, {
+    "path" : "FacilityTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "GeographicBottomHoleLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "GeographicBottomHoleLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "GeographicBottomHoleLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "DrillingReasons",
+    "kind" : "[]object"
+  }, {
+    "path" : "VerticalMeasurements",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "VerticalMeasurementID",
+      "kind" : "string"
+    }, {
+      "path" : "WellboreTVDTrajectoryID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalCRSID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalMeasurementSourceID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalReferenceID",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "VerticalMeasurementPathID",
+      "kind" : "string"
+    }, {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "VerticalMeasurement",
+      "kind" : "double"
+    }, {
+      "path" : "VerticalMeasurementTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalMeasurementDescription",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalMeasurementUnitOfMeasureID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "PrimaryMaterialID",
+    "kind" : "string"
+  }, {
+    "path" : "SequenceNumber",
+    "kind" : "int"
+  }, {
+    "path" : "TargetFormation",
+    "kind" : "string"
+  }, {
+    "path" : "KickOffWellbore",
+    "kind" : "string"
+  }, {
+    "path" : "DefaultVerticalMeasurementID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "WellID",
+    "kind" : "string"
+  }, {
+    "path" : "TrajectoryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "DefinitiveTrajectoryID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+         "path" : "VirtualProperties.DefaultLocation.IsDecimated",
+         "kind" : "boolean"
+  }]
+}
diff --git a/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res b/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res
index 91a70ee6e..c27e6beef 100644
--- a/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res
+++ b/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res
@@ -335,6 +335,6 @@
     "kind" : "string"
   }, {
          "path" : "VirtualProperties.DefaultLocation.IsDecimated",
-         "kind" : "boolean"
+         "kind" : "bool"
   }]
 }
diff --git a/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.FF.res b/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.FF.res
new file mode 100644
index 000000000..59998ea9e
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.FF.res
@@ -0,0 +1,343 @@
+{
+  "kind" : "osdu:wks:master-data--Wellbore:1.0.0",
+  "schema" : [ {
+    "path" : "ResourceHomeRegionID",
+    "kind" : "string"
+  }, {
+    "path" : "ResourceHostRegionIDs",
+    "kind" : "[]string"
+  }, {
+    "path" : "ResourceLifecycleStatus",
+    "kind" : "string"
+  }, {
+    "path" : "ResourceSecurityClassification",
+    "kind" : "string"
+  }, {
+    "path" : "ResourceCurationStatus",
+    "kind" : "string"
+  }, {
+    "path" : "ExistenceKind",
+    "kind" : "string"
+  }, {
+    "path" : "TechnicalAssuranceID",
+    "kind" : "string"
+  }, {
+    "path" : "Source",
+    "kind" : "string"
+  }, {
+    "path" : "NameAliases",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "AliasNameTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "AliasName",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "DefinitionOrganisationID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "SpatialLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "SpatialLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "SpatialLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "SpatialLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "SpatialLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "SpatialLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "SpatialLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VersionCreationReason",
+    "kind" : "string"
+  }, {
+    "path" : "GeoContexts",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "GeoPoliticalEntityID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "BasinID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "FieldID",
+      "kind" : "string"
+    }, {
+      "path" : "PlayID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "ProspectID",
+      "kind" : "string"
+    }, {
+      "path" : "GeoTypeID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "FacilityStates",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "FacilityStateTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    } ]
+  }, {
+    "path" : "FacilityID",
+    "kind" : "string"
+  }, {
+    "path" : "OperatingEnvironmentID",
+    "kind" : "string"
+  }, {
+    "path" : "FacilityNameAliases",
+    "kind" : "[]object"
+  }, {
+    "path" : "FacilityEvents",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "FacilityEventTypeID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "FacilitySpecifications",
+    "kind" : "flattened"
+  }, {
+    "path" : "DataSourceOrganisationID",
+    "kind" : "string"
+  }, {
+    "path" : "InitialOperatorID",
+    "kind" : "string"
+  }, {
+    "path" : "CurrentOperatorID",
+    "kind" : "string"
+  }, {
+    "path" : "FacilityOperators",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "FacilityOperatorID",
+      "kind" : "string"
+    }, {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "FacilityOperatorOrganisationID",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    } ]
+  }, {
+    "path" : "FacilityName",
+    "kind" : "string"
+  }, {
+    "path" : "FacilityTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "GeographicBottomHoleLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "GeographicBottomHoleLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "GeographicBottomHoleLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "GeographicBottomHoleLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "DrillingReasons",
+    "kind" : "[]object"
+  }, {
+    "path" : "VerticalMeasurements",
+    "kind" : "nested",
+    "properties" : [ {
+      "path" : "VerticalMeasurementID",
+      "kind" : "string"
+    }, {
+      "path" : "WellboreTVDTrajectoryID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalCRSID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalMeasurementSourceID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalReferenceID",
+      "kind" : "string"
+    }, {
+      "path" : "TerminationDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "VerticalMeasurementPathID",
+      "kind" : "string"
+    }, {
+      "path" : "EffectiveDateTime",
+      "kind" : "datetime"
+    }, {
+      "path" : "VerticalMeasurement",
+      "kind" : "double"
+    }, {
+      "path" : "VerticalMeasurementTypeID",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalMeasurementDescription",
+      "kind" : "string"
+    }, {
+      "path" : "VerticalMeasurementUnitOfMeasureID",
+      "kind" : "string"
+    } ]
+  }, {
+    "path" : "PrimaryMaterialID",
+    "kind" : "string"
+  }, {
+    "path" : "SequenceNumber",
+    "kind" : "int"
+  }, {
+    "path" : "TargetFormation",
+    "kind" : "string"
+  }, {
+    "path" : "KickOffWellbore",
+    "kind" : "string"
+  }, {
+    "path" : "DefaultVerticalMeasurementID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "ProjectedBottomHoleLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "WellID",
+    "kind" : "string"
+  }, {
+    "path" : "TrajectoryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "DefinitiveTrajectoryID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.SpatialParameterTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.QuantitativeAccuracyBandID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.CoordinateQualityCheckRemarks",
+    "kind" : "[]string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.AppliedOperations",
+    "kind" : "[]string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.QualitativeSpatialAccuracyTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.CoordinateQualityCheckPerformedBy",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.SpatialLocationCoordinatesDate",
+    "kind" : "datetime"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.CoordinateQualityCheckDateTime",
+    "kind" : "datetime"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.Wgs84Coordinates",
+    "kind" : "core:dl:geoshape:1.0.0"
+  }, {
+    "path" : "VirtualProperties.DefaultLocation.SpatialGeometryTypeID",
+    "kind" : "string"
+  }, {
+    "path" : "VirtualProperties.DefaultName",
+    "kind" : "string"
+  }, {
+      "path" : "VirtualProperties.DefaultLocation.IsDecimated",
+      "kind" : "boolean"
+    }]
+}
diff --git a/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res b/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res
index 59998ea9e..d9d443e79 100644
--- a/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res
+++ b/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res
@@ -338,6 +338,6 @@
     "kind" : "string"
   }, {
       "path" : "VirtualProperties.DefaultLocation.IsDecimated",
-      "kind" : "boolean"
+      "kind" : "bool"
     }]
 }
diff --git a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
index e8d480d2f..8c4788013 100644
--- a/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
+++ b/indexer-core/src/test/resources/converter/wks/slb_wke_wellbore.json.res
@@ -66,7 +66,7 @@
       "path": "formationProjected"
     },
     {
-      "kind": "boolean",
+      "kind": "bool",
       "path": "hasAchievedTotalDepth"
     },
     {
-- 
GitLab


From e7a6d368cbe73e60846fd683ca1c584fd01db5ea Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Thu, 3 Oct 2024 14:11:45 -0400
Subject: [PATCH 11/18] change expectations for feature flag off in virtual
 properties

(cherry picked from commit 4b22835a6f0d0db8433682bb594c83fd32e8d0f2)
---
 .../indexer/schema/converter/SchemaToStorageFormatImplTest.java | 2 --
 .../unmatched-virtual-properties-schema.json.res                | 2 +-
 .../index-virtual-properties/virtual-properties-schema.json.res | 2 +-
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
index c4ec5697e..07960a3db 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
@@ -156,7 +156,6 @@ public class SchemaToStorageFormatImplTest {
     }
 
     @Test
-    @Ignore
     public void virtualProperties_FFoff() {
         testSingleFile("/converter/index-virtual-properties/virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0", false);
         verify(this.virtualPropertiesSchemaCache, times(1)).put(Mockito.anyString(), Mockito.any());
@@ -176,7 +175,6 @@ public class SchemaToStorageFormatImplTest {
     }
 
     @Test
-    @Ignore
     public void unmatchedVirtualProperties_FFoff() {
         // The actual property "data.Facility" does not exist for "data.VirtualProperties.DefaultName"
         testSingleFile("/converter/index-virtual-properties/unmatched-virtual-properties-schema.json", "osdu:wks:master-data--Wellbore:1.0.0", false);
diff --git a/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res b/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res
index c27e6beef..91a70ee6e 100644
--- a/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res
+++ b/indexer-core/src/test/resources/converter/index-virtual-properties/unmatched-virtual-properties-schema.json.res
@@ -335,6 +335,6 @@
     "kind" : "string"
   }, {
          "path" : "VirtualProperties.DefaultLocation.IsDecimated",
-         "kind" : "bool"
+         "kind" : "boolean"
   }]
 }
diff --git a/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res b/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res
index d9d443e79..59998ea9e 100644
--- a/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res
+++ b/indexer-core/src/test/resources/converter/index-virtual-properties/virtual-properties-schema.json.res
@@ -338,6 +338,6 @@
     "kind" : "string"
   }, {
       "path" : "VirtualProperties.DefaultLocation.IsDecimated",
-      "kind" : "bool"
+      "kind" : "boolean"
     }]
 }
-- 
GitLab


From 1f59ea0c555fb9f29159b90f00bcfe36d1009bf5 Mon Sep 17 00:00:00 2001
From: Stanislaw Bieniecki <stanislaw.bieniecki@hitachivantara.com>
Date: Wed, 23 Oct 2024 12:29:32 +0200
Subject: [PATCH 12/18] Add autoconversions to string also behind the feature
 flag

(cherry picked from commit b296c4042fb90cdf4b6c5879919ea0ba20e13e81)
---
 .../service/StorageIndexerPayloadMapper.java  |  21 +++-
 .../StorageIndexerPayloadMapperTest.java      | 100 ++++++++++++++++--
 .../wellStorageRecordData.json                |  19 ++++
 .../wellStorageSchema.json                    |  32 ++++++
 4 files changed, 161 insertions(+), 11 deletions(-)
 create mode 100644 indexer-core/src/test/resources/converter/index-autoconversions/wellStorageRecordData.json
 create mode 100644 indexer-core/src/test/resources/converter/index-autoconversions/wellStorageSchema.json

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 adf0d41d9..4b20fd821 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
@@ -44,6 +44,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 import static org.opengroup.osdu.indexer.model.Constants.AS_INGESTED_COORDINATES_FEATURE_NAME;
+import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 
 @Component
 public class StorageIndexerPayloadMapper {
@@ -67,7 +68,7 @@ public class StorageIndexerPayloadMapper {
     private PointExtractor pointExtractor;
 
     @Autowired
-    private IFeatureFlag asIngestedCoordinatesFeatureFlag;
+    private IFeatureFlag featureFlagChecker;
 
     public Map<String, Object> mapDataPayload(ArrayList<String> asIngestedCoordinatesPaths, IndexSchema storageSchema, Map<String, Object> storageRecordData,
                                               String recordId) {
@@ -81,7 +82,7 @@ public class StorageIndexerPayloadMapper {
 
         mapDataPayload(storageSchema.getDataSchema(), storageRecordData, recordId, dataCollectorMap);
         mapVirtualPropertiesPayload(storageSchema, recordId, dataCollectorMap);
-        if (this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)) {
+        if (this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)) {
             mapAsIngestedCoordinatesPayload(recordId, asIngestedCoordinatesPaths, storageRecordData, dataCollectorMap);
         }
 
@@ -115,11 +116,23 @@ public class StorageIndexerPayloadMapper {
             switch (elasticType) {
                 case KEYWORD:
                 case TEXT:
-                    this.attributeParsingService.tryParseString(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+                    // Feature flag enforces conversion of values to string when index type is string, this is required for features using
+                    // copy_to mechanic like bag of words, however originally index type for boolean values was string so this would convert
+                    // those values to string without changing the index type, changing index type would require migration so it is also
+                    // under this feature flag as not all users will be interested with it
+                    if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)) {
+                        this.attributeParsingService.tryParseString(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+                    } else {
+                        dataCollectorMap.put(schemaPropertyName, storageRecordValue);    
+                    }
                     break;
                 case KEYWORD_ARRAY:
                 case TEXT_ARRAY:
-                    this.attributeParsingService.tryParseValueArray(String.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+                    if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)) {
+                        this.attributeParsingService.tryParseValueArray(String.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
+                    } else {
+                        dataCollectorMap.put(schemaPropertyName, storageRecordValue);
+                    }
                     break;
                 case INTEGER_ARRAY:
                     this.attributeParsingService.tryParseValueArray(Integer.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
index 79a7c9602..80fe386da 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
@@ -84,7 +84,7 @@ public class StorageIndexerPayloadMapperTest {
     private VirtualPropertiesSchemaCache virtualPropertiesSchemaCache;
 
     @MockBean
-    protected IFeatureFlag asIngestedCoordinatesFeatureFlag;
+    protected IFeatureFlag featureFlagChecker;
 
     @BeforeClass
     public static void setUp() {
@@ -283,8 +283,8 @@ public class StorageIndexerPayloadMapperTest {
 
     @Test
     public void mapDataPayloadTestAsIngestedCoordinates() {
-        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
-        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
+        when(this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
+        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -320,8 +320,8 @@ public class StorageIndexerPayloadMapperTest {
 
     @Test
     public void mapDataPayloadTestAsIngestedCoordinatesGeographicBottomHoleLocationAndSpatialLocation() {
-        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
-        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
+        when(this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
+        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("GeographicBottomHoleLocation.AsIngestedCoordinates", "SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -384,8 +384,8 @@ public class StorageIndexerPayloadMapperTest {
 
     @Test
     public void mapDataPayloadTestAsIngestedCoordinatesWithEmptyZCoordinate() {
-        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
-        when(this.asIngestedCoordinatesFeatureFlag.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
+        when(this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
+        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -409,6 +409,92 @@ public class StorageIndexerPayloadMapperTest {
         assertNull(dataCollectorMap.get("SpatialLocation.AsIngestedCoordinates.FirstPoint.Z"));
     }
 
+    @Test
+    public void mapDataPayloadTestAutoconversionsBooleanConversionOn() {
+        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
+        Map<String, Object> storageRecordLocalData = loadObject("/converter/index-autoconversions/wellStorageRecordData.json", storageRecordData.getClass());
+        IndexSchema indexLocalSchema = loadObject("/converter/index-autoconversions/wellStorageSchema.json", IndexSchema.class);
+        Map<String, Object> dataCollectorMap = payloadMapper.mapDataPayload(emptyAsIngestedCoordinatesPaths, indexLocalSchema, storageRecordLocalData, RECORD_TEST_ID);
+
+        assertTrue(dataCollectorMap.containsKey("SomeKeywordField"));
+        assertEquals(dataCollectorMap.get("SomeKeywordField"), "42.0");
+        assertTrue(dataCollectorMap.containsKey("SomeTextField"));
+        assertEquals(dataCollectorMap.get("SomeTextField"), "43.0");
+        assertTrue(dataCollectorMap.containsKey("SomeOtherTextField"));
+        assertEquals(dataCollectorMap.get("SomeOtherTextField"), "true");
+        assertTrue(dataCollectorMap.containsKey("SomeKeywordArrayField"));
+        assertEquals(((String[]) dataCollectorMap.get("SomeKeywordArrayField"))[0], "44.0");
+        assertTrue(dataCollectorMap.containsKey("SomeTextArrayField"));
+        assertEquals(((String[]) dataCollectorMap.get("SomeTextArrayField"))[0], "46.1");
+        assertTrue(dataCollectorMap.containsKey("SomeIntegerArrayField"));
+        assertEquals(((Integer[]) dataCollectorMap.get("SomeIntegerArrayField"))[0].intValue(), 48);
+        assertTrue(dataCollectorMap.containsKey("SomeIntegerField"));
+        assertEquals(dataCollectorMap.get("SomeIntegerField"), 50);
+        assertTrue(dataCollectorMap.containsKey("SomeLongArrayField"));
+        assertEquals(((Long[]) dataCollectorMap.get("SomeLongArrayField"))[0].longValue(), 510000000000001L);
+        assertTrue(dataCollectorMap.containsKey("SomeLongField"));
+        assertEquals(dataCollectorMap.get("SomeLongField"), 530000000000001L);
+        assertTrue(dataCollectorMap.containsKey("SomeFloatArrayField"));
+        assertEquals(((Float[]) dataCollectorMap.get("SomeFloatArrayField"))[0].floatValue(), 54.11111, 0.0001);
+        assertTrue(dataCollectorMap.containsKey("SomeFloatField"));
+        assertEquals((Float) dataCollectorMap.get("SomeFloatField"), 56.11111, 0.0001);
+        assertTrue(dataCollectorMap.containsKey("SomeDoubleArrayField"));
+        assertEquals(((Double[]) dataCollectorMap.get("SomeDoubleArrayField"))[0].doubleValue(), 56.11111111111111D, 0.00000000001D);
+        assertTrue(dataCollectorMap.containsKey("SomeDoubleField"));
+        assertEquals((Double) dataCollectorMap.get("SomeDoubleField"), 58.11111111111111D, 0.00000000001D);
+        assertTrue(dataCollectorMap.containsKey("SomeBooleanArrayField"));
+        assertEquals(((Boolean[]) dataCollectorMap.get("SomeBooleanArrayField"))[0], true);
+        assertTrue(dataCollectorMap.containsKey("SomeBooleanField"));
+        assertEquals((Boolean) dataCollectorMap.get("SomeBooleanField"), false);
+        assertTrue(dataCollectorMap.containsKey("SomeDateArrayField"));
+        assertEquals(((String[]) dataCollectorMap.get("SomeDateArrayField"))[0], "2024-01-01T00:00:00+0000");
+        assertTrue(dataCollectorMap.containsKey("SomeDateField"));
+        assertEquals(dataCollectorMap.get("SomeDateField"), "2024-01-03T00:00:00+0000");
+    }
+    
+    @Test
+    public void mapDataPayloadTestAutoconversionsBooleanConversionOff() {
+        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(false);
+        Map<String, Object> storageRecordLocalData = loadObject("/converter/index-autoconversions/wellStorageRecordData.json", storageRecordData.getClass());
+        IndexSchema indexLocalSchema = loadObject("/converter/index-autoconversions/wellStorageSchema.json", IndexSchema.class);
+        Map<String, Object> dataCollectorMap = payloadMapper.mapDataPayload(emptyAsIngestedCoordinatesPaths, indexLocalSchema, storageRecordLocalData, RECORD_TEST_ID);
+
+        assertTrue(dataCollectorMap.containsKey("SomeKeywordField"));
+        assertEquals(dataCollectorMap.get("SomeKeywordField"), 42.0);
+        assertTrue(dataCollectorMap.containsKey("SomeTextField"));
+        assertEquals(dataCollectorMap.get("SomeTextField"), 43.0);
+        assertTrue(dataCollectorMap.containsKey("SomeOtherTextField"));
+        assertEquals(dataCollectorMap.get("SomeOtherTextField"), true);
+        assertTrue(dataCollectorMap.containsKey("SomeKeywordArrayField"));
+        assertEquals(((List<Double>) dataCollectorMap.get("SomeKeywordArrayField")).get(0), 44.0, 0.0001);
+        assertTrue(dataCollectorMap.containsKey("SomeTextArrayField"));
+        assertEquals(((List<Double>) dataCollectorMap.get("SomeTextArrayField")).get(0), 46.1, 0.0001);
+        assertTrue(dataCollectorMap.containsKey("SomeIntegerArrayField"));
+        assertEquals(((Integer[]) dataCollectorMap.get("SomeIntegerArrayField"))[0].intValue(), 48);
+        assertTrue(dataCollectorMap.containsKey("SomeIntegerField"));
+        assertEquals(dataCollectorMap.get("SomeIntegerField"), 50);
+        assertTrue(dataCollectorMap.containsKey("SomeLongArrayField"));
+        assertEquals(((Long[]) dataCollectorMap.get("SomeLongArrayField"))[0].longValue(), 510000000000001L);
+        assertTrue(dataCollectorMap.containsKey("SomeLongField"));
+        assertEquals(dataCollectorMap.get("SomeLongField"), 530000000000001L);
+        assertTrue(dataCollectorMap.containsKey("SomeFloatArrayField"));
+        assertEquals(((Float[]) dataCollectorMap.get("SomeFloatArrayField"))[0].floatValue(), 54.11111, 0.0001);
+        assertTrue(dataCollectorMap.containsKey("SomeFloatField"));
+        assertEquals((Float) dataCollectorMap.get("SomeFloatField"), 56.11111, 0.0001);
+        assertTrue(dataCollectorMap.containsKey("SomeDoubleArrayField"));
+        assertEquals(((Double[]) dataCollectorMap.get("SomeDoubleArrayField"))[0].doubleValue(), 56.11111111111111D, 0.00000000001D);
+        assertTrue(dataCollectorMap.containsKey("SomeDoubleField"));
+        assertEquals((Double) dataCollectorMap.get("SomeDoubleField"), 58.11111111111111D, 0.00000000001D);
+        assertTrue(dataCollectorMap.containsKey("SomeBooleanArrayField"));
+        assertEquals(((Boolean[]) dataCollectorMap.get("SomeBooleanArrayField"))[0], true);
+        assertTrue(dataCollectorMap.containsKey("SomeBooleanField"));
+        assertEquals((Boolean) dataCollectorMap.get("SomeBooleanField"), false);
+        assertTrue(dataCollectorMap.containsKey("SomeDateArrayField"));
+        assertEquals(((String[]) dataCollectorMap.get("SomeDateArrayField"))[0], "2024-01-01T00:00:00+0000");
+        assertTrue(dataCollectorMap.containsKey("SomeDateField"));
+        assertEquals(dataCollectorMap.get("SomeDateField"), "2024-01-03T00:00:00+0000");
+    }
+
     private <T> T loadObject(String file, Class<T> valueType) {
         String jsonString = readResourceFile(file);
         return this.gson.fromJson(jsonString, valueType);
diff --git a/indexer-core/src/test/resources/converter/index-autoconversions/wellStorageRecordData.json b/indexer-core/src/test/resources/converter/index-autoconversions/wellStorageRecordData.json
new file mode 100644
index 000000000..869ff4a1e
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/index-autoconversions/wellStorageRecordData.json
@@ -0,0 +1,19 @@
+{
+    "SomeKeywordField": 42,
+    "SomeTextField": 43,
+    "SomeOtherTextField": true,
+    "SomeKeywordArrayField": [44, 45],
+    "SomeTextArrayField": [46.1, 47.1],
+    "SomeIntegerArrayField": ["48", "49"],
+    "SomeIntegerField": "50",
+    "SomeLongArrayField": ["510000000000001", "520000000000001"],
+    "SomeLongField": "530000000000001",
+    "SomeFloatArrayField": ["54.11111", "55.11111"],
+    "SomeFloatField": "56.11111",
+    "SomeDoubleArrayField": ["56.11111111111111", "57.11111111111111"],
+    "SomeDoubleField": "58.11111111111111",
+    "SomeBooleanArrayField": ["true", "false"],
+    "SomeBooleanField": "false",
+    "SomeDateArrayField": ["2024-01-01", "2024-01-02"],
+    "SomeDateField": "2024-01-03"
+}
\ No newline at end of file
diff --git a/indexer-core/src/test/resources/converter/index-autoconversions/wellStorageSchema.json b/indexer-core/src/test/resources/converter/index-autoconversions/wellStorageSchema.json
new file mode 100644
index 000000000..77afcec8d
--- /dev/null
+++ b/indexer-core/src/test/resources/converter/index-autoconversions/wellStorageSchema.json
@@ -0,0 +1,32 @@
+{
+  "kind": "osdu:wks:master-data--Well:1.2.0",
+  "type": "master-data--Well",
+  "dataSchema": {
+    "SomeKeywordField": "keyword",
+    "SomeTextField": "text",
+    "SomeOtherTextField": "text",
+    "SomeKeywordArrayField": "keyword_array",
+    "SomeTextArrayField": "text_array",
+    "SomeIntegerArrayField": "integer_array",
+    "SomeIntegerField": "integer",
+    "SomeLongArrayField": "long_array",
+    "SomeLongField": "long",
+    "SomeFloatArrayField": "float_array",
+    "SomeFloatField": "float",
+    "SomeDoubleArrayField": "double_array",
+    "SomeDoubleField": "double",
+    "SomeBooleanArrayField": "boolean_array",
+    "SomeBooleanField": "boolean",
+    "SomeDateArrayField": "date_array",
+    "SomeDateField": "date",
+    "SomeGeoPointField": "geo_point",
+    "SomeGeoShapeField": "geo_shape",
+    "SomeObjectField": {
+      "type": "nested",
+      "properties": {
+        "SomeNestedTextField": "text"
+      }
+    },
+    "SomeFlattenedField": "flattened"
+  }
+}
\ No newline at end of file
-- 
GitLab


From 2551c890595d3f1266fabe5c64de3885e391f810 Mon Sep 17 00:00:00 2001
From: Stanislaw Bieniecki <stanislaw.bieniecki@hitachivantara.com>
Date: Thu, 16 Jan 2025 12:59:29 +0100
Subject: [PATCH 13/18] Use partition level flag if service level off

(cherry picked from commit a990515acc76d0ec24fc5b6c66d82447b9e16f4a)
---
 .../src/main/resources/application.properties |  2 +-
 .../SchemaConverterPropertiesConfig.java      | 23 +++++++++++++++++--
 .../service/StorageIndexerPayloadMapper.java  | 23 +++++++++++++++++--
 .../converter/PropertiesProcessorTest.java    | 12 ++++++----
 .../SchemaToStorageFormatImplTest.java        |  6 ++++-
 .../StorageIndexerPayloadMapperTest.java      |  6 ++++-
 6 files changed, 61 insertions(+), 11 deletions(-)

diff --git a/indexer-core-plus/src/main/resources/application.properties b/indexer-core-plus/src/main/resources/application.properties
index 5d827e4f1..47fdb129c 100644
--- a/indexer-core-plus/src/main/resources/application.properties
+++ b/indexer-core-plus/src/main/resources/application.properties
@@ -63,7 +63,7 @@ rabbitmq-retry-limit=5
 
 # Feature flag settings
 featureFlag.strategy=dataPartition
-featureFlag.mapBooleanToString.enabled=true
+featureFlag.mapBooleanToString.enabled=false
 featureFlag.asIngestedCoordinates.enabled=false
 featureFlag.keywordLower.enabled=false
 featureFlag.bagOfWords.enabled=false
diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
index 077ae9925..7ee550a3c 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
@@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 
 import org.opengroup.osdu.core.common.feature.IFeatureFlag;
+import org.opengroup.osdu.indexer.util.BooleanFeatureFlagClient;
 import org.springframework.stereotype.Component;
 
 import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
@@ -30,9 +31,12 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
 
     @Autowired
     private IFeatureFlag featureFlagChecker;
+    @Autowired
+    private BooleanFeatureFlagClient partitionFlagChecker;
 
-    public SchemaConverterPropertiesConfig(IFeatureFlag flag) {
+    public SchemaConverterPropertiesConfig(IFeatureFlag flag, BooleanFeatureFlagClient flagClient) {
         if (flag != null) featureFlagChecker=flag;
+        if (flagClient != null) partitionFlagChecker=flagClient;
         skippedDefinitions = getDefaultSkippedDefinitions();
         supportedArrayTypes = getDefaultSupportedArrayTypes();
         specialDefinitionsMap = getDefaultSpecialDefinitionsMap();
@@ -72,7 +76,22 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
     private Map<String, String> getDefaultPrimitiveTypesMap() {
         Map<String, String> defaultPrimitiveTypesMap = new HashMap<>();
 
-        if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)) {
+        /*
+            Logic behing feature flag settings
+            If service-level FF is ON for a given deployment/environment, then the FF is ON for all the data partitions under the deployment/environment
+            If service-level FF is OFF but it is ON for a given data partition, then the FF is ON for the given data partition
+
+            With this solution, the service providers can decide which level of FF should be turned on. For example,
+            If there are only few data partitions in a given deployment and there are not many data needed to be indexed, 
+            the service provider can turn on the service-level FF and re-index all the data partitions in one shot.
+            If there are lots of data partitions or some data partitions have lots of data in a given deployment, step should be as following.
+
+            1. Turn the service-level FF to be OFF
+            2. Turn on the FF via partition service for a given data partition and re-index all the data in the given data partition
+            3. Repeat step 2 until all the data partitions have been re-indexed
+            4. Turn the service-level FF to be ON and re-deploy the service. So all new data partitions apply the fix
+         */
+        if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME) || partitionFlagChecker.isEnabled(MAP_BOOL2STRING_FEATURE_NAME, false)) {
             // in the earlier versions boolean was translated to bool and
             // this caused mapping boolean values like text as entry in StorageType entry in map is boolean
             // in some places boolean is still presented as bool so here both are normalized to boolean
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 4b20fd821..a43a1078f 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
@@ -35,6 +35,7 @@ import org.opengroup.osdu.indexer.util.PropertyUtil;
 import org.opengroup.osdu.indexer.util.geo.decimator.DecimatedResult;
 import org.opengroup.osdu.indexer.util.geo.decimator.GeoShapeDecimator;
 import org.opengroup.osdu.indexer.util.geo.extractor.PointExtractor;
+import org.opengroup.osdu.indexer.util.BooleanFeatureFlagClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -70,6 +71,9 @@ public class StorageIndexerPayloadMapper {
     @Autowired
     private IFeatureFlag featureFlagChecker;
 
+    @Autowired
+    private BooleanFeatureFlagClient booleanFeatureFlagClient;
+
     public Map<String, Object> mapDataPayload(ArrayList<String> asIngestedCoordinatesPaths, IndexSchema storageSchema, Map<String, Object> storageRecordData,
                                               String recordId) {
 
@@ -116,11 +120,26 @@ public class StorageIndexerPayloadMapper {
             switch (elasticType) {
                 case KEYWORD:
                 case TEXT:
+                    /*
+                        Logic behing feature flag settings
+                        If service-level FF is ON for a given deployment/environment, then the FF is ON for all the data partitions under the deployment/environment
+                        If service-level FF is OFF but it is ON for a given data partition, then the FF is ON for the given data partition
+
+                        With this solution, the service providers can decide which level of FF should be turned on. For example,
+                        If there are only few data partitions in a given deployment and there are not many data needed to be indexed, 
+                        the service provider can turn on the service-level FF and re-index all the data partitions in one shot.
+                        If there are lots of data partitions or some data partitions have lots of data in a given deployment, step should be as following.
+
+                        1. Turn the service-level FF to be OFF
+                        2. Turn on the FF via partition service for a given data partition and re-index all the data in the given data partition
+                        3. Repeat step 2 until all the data partitions have been re-indexed
+                        4. Turn the service-level FF to be ON and re-deploy the service. So all new data partitions apply the fix
+                    */
                     // Feature flag enforces conversion of values to string when index type is string, this is required for features using
                     // copy_to mechanic like bag of words, however originally index type for boolean values was string so this would convert
                     // those values to string without changing the index type, changing index type would require migration so it is also
                     // under this feature flag as not all users will be interested with it
-                    if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)) {
+                    if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME) || booleanFeatureFlagClient.isEnabled(MAP_BOOL2STRING_FEATURE_NAME, false)) {
                         this.attributeParsingService.tryParseString(recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
                     } else {
                         dataCollectorMap.put(schemaPropertyName, storageRecordValue);    
@@ -128,7 +147,7 @@ public class StorageIndexerPayloadMapper {
                     break;
                 case KEYWORD_ARRAY:
                 case TEXT_ARRAY:
-                    if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)) {
+                    if (this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME) || booleanFeatureFlagClient.isEnabled(MAP_BOOL2STRING_FEATURE_NAME, false)) {
                         this.attributeParsingService.tryParseValueArray(String.class, recordId, schemaPropertyName, storageRecordValue, dataCollectorMap);
                     } else {
                         dataCollectorMap.put(schemaPropertyName, storageRecordValue);
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
index 90a141eb6..5700a71d3 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/PropertiesProcessorTest.java
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 import org.opengroup.osdu.core.common.feature.IFeatureFlag;
+import org.opengroup.osdu.indexer.util.BooleanFeatureFlagClient;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
@@ -44,9 +45,9 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
-@Import({IFeatureFlag.class})
-@ContextConfiguration(classes = {PropertiesProcessorTest.class, IFeatureFlag.class})
-@SpringBootTest(classes = {IFeatureFlag.class})
+@Import({IFeatureFlag.class, BooleanFeatureFlagClient.class})
+@ContextConfiguration(classes = {PropertiesProcessorTest.class, IFeatureFlag.class, BooleanFeatureFlagClient.class})
+@SpringBootTest(classes = {IFeatureFlag.class, BooleanFeatureFlagClient.class})
 public class PropertiesProcessorTest {
 
     private static final String PATH = "given_path";
@@ -55,12 +56,15 @@ public class PropertiesProcessorTest {
     @MockBean
     private IFeatureFlag featureFlagChecker;
 
+    @MockBean
+    private BooleanFeatureFlagClient partitionFlagClient;
+
     private SchemaConverterPropertiesConfig schemaConverterConfig;
 
     @Before
     public void setup() throws IOException {
         initMocks(this);
-        schemaConverterConfig = new SchemaConverterPropertiesConfig(featureFlagChecker);
+        schemaConverterConfig = new SchemaConverterPropertiesConfig(featureFlagChecker, partitionFlagClient);
     }
 
     @Test
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
index 07960a3db..a7769064f 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
@@ -27,6 +27,7 @@ import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
 import org.opengroup.osdu.indexer.cache.partitionsafe.VirtualPropertiesSchemaCache;
 import org.opengroup.osdu.indexer.schema.converter.config.SchemaConverterPropertiesConfig;
 import org.opengroup.osdu.indexer.schema.converter.exeption.SchemaProcessingException;
+import org.opengroup.osdu.indexer.util.BooleanFeatureFlagClient;
 import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.MAP_BOOL2STRING_FEATURE_NAME;
 
 import org.springframework.context.annotation.Configuration;
@@ -63,13 +64,16 @@ public class SchemaToStorageFormatImplTest {
 
     private IFeatureFlag featureFlag;
 
+    private BooleanFeatureFlagClient partitionFlagClient;
+
     private SchemaConverterPropertiesConfig schemaConverterPropertiesConfig;
     @Before
     public void init() {
         MockitoAnnotations.initMocks(this);
         featureFlag = Mockito.mock(IFeatureFlag.class);
+        partitionFlagClient = Mockito.mock(BooleanFeatureFlagClient.class);
         virtualPropertiesSchemaCache = Mockito.mock(VirtualPropertiesSchemaCache.class);
-        schemaConverterPropertiesConfig = new SchemaConverterPropertiesConfig(featureFlag);
+        schemaConverterPropertiesConfig = new SchemaConverterPropertiesConfig(featureFlag, partitionFlagClient);
         schemaToStorageFormatImpl
             = new SchemaToStorageFormatImpl(objectMapper, jaxRsDpsLog,
                 schemaConverterPropertiesConfig, virtualPropertiesSchemaCache);
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
index 80fe386da..30e229a2c 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
@@ -27,6 +27,7 @@ import org.opengroup.osdu.indexer.util.geo.decimator.GeoShapeDecimator;
 import org.opengroup.osdu.indexer.util.geo.decimator.GeometryDecimator;
 import org.opengroup.osdu.indexer.util.geo.extractor.PointExtractor;
 import org.opengroup.osdu.indexer.util.parser.*;
+import org.opengroup.osdu.indexer.util.BooleanFeatureFlagClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
@@ -49,7 +50,7 @@ import static org.opengroup.osdu.indexer.model.Constants.AS_INGESTED_COORDINATES
         GeometryDecimator.class, PointExtractor.class, GeometryConversionService.class, FeatureFlagCache.class,
         DpsHeaders.class, JobStatus.class, SchemaConverterPropertiesConfig.class, JaxRsDpsLog.class,
         ServiceAccountJwtClientMock.class, VirtualPropertiesSchemaCacheMock.class, VirtualPropertiesSchemaCache.class, RequestInfoMock.class,
-        IFeatureFlag.class, StringParser.class}
+        IFeatureFlag.class, StringParser.class, BooleanFeatureFlagClient.class}
 )
 public class StorageIndexerPayloadMapperTest {
 
@@ -86,6 +87,9 @@ public class StorageIndexerPayloadMapperTest {
     @MockBean
     protected IFeatureFlag featureFlagChecker;
 
+    @MockBean
+    protected BooleanFeatureFlagClient partitionFlagChecker;
+
     @BeforeClass
     public static void setUp() {
         HashMap<String, Object> dataMap = new HashMap<>();
-- 
GitLab


From ace579bb3a69b7a4d379cb4fbbc57ca2e75a2025 Mon Sep 17 00:00:00 2001
From: Stanislaw Bieniecki <stanislaw.bieniecki@hitachivantara.com>
Date: Thu, 16 Jan 2025 13:42:51 +0100
Subject: [PATCH 14/18] Remove unnecessary feature flag mocks

(cherry picked from commit 469599fab7760cb09ef82da64faf98119bd032a9)
---
 .../osdu/indexer/service/StorageIndexerPayloadMapperTest.java  | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
index 30e229a2c..6b9267b45 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/StorageIndexerPayloadMapperTest.java
@@ -288,7 +288,6 @@ public class StorageIndexerPayloadMapperTest {
     @Test
     public void mapDataPayloadTestAsIngestedCoordinates() {
         when(this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
-        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -325,7 +324,6 @@ public class StorageIndexerPayloadMapperTest {
     @Test
     public void mapDataPayloadTestAsIngestedCoordinatesGeographicBottomHoleLocationAndSpatialLocation() {
         when(this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
-        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("GeographicBottomHoleLocation.AsIngestedCoordinates", "SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
@@ -389,7 +387,6 @@ public class StorageIndexerPayloadMapperTest {
     @Test
     public void mapDataPayloadTestAsIngestedCoordinatesWithEmptyZCoordinate() {
         when(this.featureFlagChecker.isFeatureEnabled(AS_INGESTED_COORDINATES_FEATURE_NAME)).thenReturn(true);
-        when(this.featureFlagChecker.isFeatureEnabled(MAP_BOOL2STRING_FEATURE_NAME)).thenReturn(true);
 
         ArrayList<String> asIngestedCoordinatesPaths = new ArrayList<>(Arrays.asList("SpatialLocation.AsIngestedCoordinates"));
         Map<String, Object> storageRecordData = new HashMap<>();
-- 
GitLab


From e4716e4ad7cc51a0477474413c349958ef6a8237 Mon Sep 17 00:00:00 2001
From: ylesnikau <ylesnikau@slb.com>
Date: Tue, 11 Feb 2025 12:16:04 +0100
Subject: [PATCH 15/18] add lazy initialization for the primitiveTypesMap of
 the SchemaConverterPropertiesConfig

(cherry picked from commit df4714caa5a6a4ad1b053d750030a2d76ae7fc76)
---
 .../SchemaConverterPropertiesConfig.java      | 22 +++++++++++--------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
index 7ee550a3c..7cc6a476b 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/config/SchemaConverterPropertiesConfig.java
@@ -5,9 +5,9 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+
 import lombok.Getter;
 import lombok.Setter;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 
 import org.opengroup.osdu.core.common.feature.IFeatureFlag;
@@ -29,18 +29,15 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
     private Set<String> processedArraysTypes;
     private String defaultObjectArraysType;
 
-    @Autowired
-    private IFeatureFlag featureFlagChecker;
-    @Autowired
-    private BooleanFeatureFlagClient partitionFlagChecker;
+    private final IFeatureFlag featureFlagChecker;
+    private final BooleanFeatureFlagClient partitionFlagChecker;
 
-    public SchemaConverterPropertiesConfig(IFeatureFlag flag, BooleanFeatureFlagClient flagClient) {
-        if (flag != null) featureFlagChecker=flag;
-        if (flagClient != null) partitionFlagChecker=flagClient;
+    public SchemaConverterPropertiesConfig(IFeatureFlag featureFlagChecker, BooleanFeatureFlagClient partitionFlagChecker) {
+        this.featureFlagChecker = featureFlagChecker;
+        this.partitionFlagChecker = partitionFlagChecker;
         skippedDefinitions = getDefaultSkippedDefinitions();
         supportedArrayTypes = getDefaultSupportedArrayTypes();
         specialDefinitionsMap = getDefaultSpecialDefinitionsMap();
-        primitiveTypesMap = getDefaultPrimitiveTypesMap();
         processedArraysTypes = getDefaultArraysTypesForProcessing();
         defaultObjectArraysType = getObjectArraysDefaultType();
     }
@@ -112,6 +109,13 @@ public class SchemaConverterPropertiesConfig implements SchemaConverterConfig {
         return defaultPrimitiveTypesMap;
     }
 
+    public Map<String, String> getPrimitiveTypesMap() {
+        if (primitiveTypesMap == null) {
+            primitiveTypesMap = getDefaultPrimitiveTypesMap();
+        }
+        return primitiveTypesMap;
+    }
+
     private Set<String> getDefaultArraysTypesForProcessing() {
         return new HashSet<>(Arrays.asList("nested"));
     }
-- 
GitLab


From 11f80de192f654688b4557307aa00e3fd56bd0d1 Mon Sep 17 00:00:00 2001
From: Mark Chance <mark.chance@hitachivantara.com>
Date: Tue, 11 Feb 2025 12:44:12 +0000
Subject: [PATCH 16/18] Edit NOTICE

(cherry picked from commit a66316090ff0461b938ccd36aa0b423a49371cd9)
---
 NOTICE | 1 -
 1 file changed, 1 deletion(-)

diff --git a/NOTICE b/NOTICE
index ac0f0c29b..322ddeb2d 100644
--- a/NOTICE
+++ b/NOTICE
@@ -58,7 +58,6 @@ The following software have components provided under the terms of this license:
 - Byte Buddy (without dependencies) (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy)
 - Byte Buddy Java agent (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent)
 - ClassMate (from http://github.com/cowtowncoder/java-classmate)
-- Cloud Key Management Service (KMS) API v1-rev20240801-2.0.0 (from https://repo1.maven.org/maven2/com/google/apis/google-api-services-cloudkms)
 - Collections (from https://repo1.maven.org/maven2/commons-collections/commons-collections)
 - Converter: Jackson (from https://github.com/square/retrofit, https://repo1.maven.org/maven2/com/squareup/retrofit2/converter-jackson)
 - Core functionality for the Reactor Netty library (from https://github.com/reactor/reactor-netty)
-- 
GitLab


From 1f108b3a231aae89d9b058369d836984afdb3246 Mon Sep 17 00:00:00 2001
From: ylesnikau <ylesnikau@slb.com>
Date: Wed, 12 Feb 2025 13:06:46 +0100
Subject: [PATCH 17/18] revert unnecessary code changes, try to fix tests for
 azure

(cherry picked from commit 2a457cc9b00d5f71b1feb462ca34bb95b288b9b5)
---
 .../schema/converter/SchemaToStorageFormatImpl.java        | 6 ------
 .../schema/converter/SchemaToStorageFormatImplTest.java    | 7 ++++++-
 .../src/main/resources/application.properties              | 4 ++--
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java
index 2b4f48d50..7631df84b 100644
--- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java
+++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImpl.java
@@ -49,16 +49,10 @@ public class SchemaToStorageFormatImpl implements SchemaToStorageFormat {
 
     @Inject
     public SchemaToStorageFormatImpl(ObjectMapper objectMapper, JaxRsDpsLog log, SchemaConverterConfig schemaConverterConfig) {
-        this(objectMapper, log, schemaConverterConfig, null);
-    }
-
-    public SchemaToStorageFormatImpl(ObjectMapper objectMapper, JaxRsDpsLog log, SchemaConverterConfig schemaConverterConfig,
-                                     VirtualPropertiesSchemaCache virtualPropertiesSchemaCache) {
         Preconditions.checkNotNull(objectMapper, "objectMapper cannot be null");
 
         this.objectMapper = objectMapper;
         this.schemaConverterConfig = schemaConverterConfig;
-        if (virtualPropertiesSchemaCache != null) this.virtualPropertiesSchemaCache = virtualPropertiesSchemaCache;
     }
 
     @Override
diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
index a7769064f..80bd8fcfe 100644
--- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
+++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/schema/converter/SchemaToStorageFormatImplTest.java
@@ -33,8 +33,10 @@ import static org.opengroup.osdu.indexer.config.IndexerConfigurationProperties.M
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.ReflectionUtils;
 
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
@@ -76,7 +78,10 @@ public class SchemaToStorageFormatImplTest {
         schemaConverterPropertiesConfig = new SchemaConverterPropertiesConfig(featureFlag, partitionFlagClient);
         schemaToStorageFormatImpl
             = new SchemaToStorageFormatImpl(objectMapper, jaxRsDpsLog,
-                schemaConverterPropertiesConfig, virtualPropertiesSchemaCache);
+                schemaConverterPropertiesConfig);
+        Field field = ReflectionUtils.findField(SchemaToStorageFormatImpl.class, "virtualPropertiesSchemaCache");
+        field.setAccessible(true);
+        ReflectionUtils.setField(field, schemaToStorageFormatImpl, virtualPropertiesSchemaCache);
     }
 
     @Test
diff --git a/provider/indexer-azure/src/main/resources/application.properties b/provider/indexer-azure/src/main/resources/application.properties
index 5a84c72c3..bbb3c57d7 100644
--- a/provider/indexer-azure/src/main/resources/application.properties
+++ b/provider/indexer-azure/src/main/resources/application.properties
@@ -105,7 +105,7 @@ redis.database=${REDIS_DATABASE}
 
 # Feature flag settings
 featureFlag.strategy=${featureFlag_appProperty:appProperty}
-featureFlag.mapBooleanToString.enabled=${featureFlag_mapBooleanToString_enabled:false}
+featureFlag.mapBooleanToString.enabled=${featureFlag_mapBooleanToString_enabled:true}
 featureFlag.asIngestedCoordinates.enabled=${featureFlag_asIngestedCoordinates_enabled:true}
 featureFlag.keywordLower.enabled=${featureFlag_keywordLower_enabled:true}
 featureFlag.bagOfWords.enabled=${featureFlag_bagOfWords_enabled:true}
@@ -118,4 +118,4 @@ api.server.fullUrl.enabled=${swaggerFullUrlEnabled:true}
 azure.storage.client.retry.MAX_ATTEMPTS=3
 azure.storage.client.retry.INITIAL_DELAY=1000
 
-elasticsearch.client.cache.size=100
\ No newline at end of file
+elasticsearch.client.cache.size=100
-- 
GitLab


From e0c355e59aed7a95442a0d0c77199c01c2c9346f Mon Sep 17 00:00:00 2001
From: ylesnikau <ylesnikau@slb.com>
Date: Thu, 20 Feb 2025 11:46:55 +0100
Subject: [PATCH 18/18] set azure featureFlag_mapBooleanToString_enabled flag
 default value to false

(cherry picked from commit 59efc203982f39ad3583f0f1ca9f930e6aaec79b)
---
 .../indexer-azure/src/main/resources/application.properties     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/provider/indexer-azure/src/main/resources/application.properties b/provider/indexer-azure/src/main/resources/application.properties
index bbb3c57d7..e0cefb3db 100644
--- a/provider/indexer-azure/src/main/resources/application.properties
+++ b/provider/indexer-azure/src/main/resources/application.properties
@@ -105,7 +105,7 @@ redis.database=${REDIS_DATABASE}
 
 # Feature flag settings
 featureFlag.strategy=${featureFlag_appProperty:appProperty}
-featureFlag.mapBooleanToString.enabled=${featureFlag_mapBooleanToString_enabled:true}
+featureFlag.mapBooleanToString.enabled=${featureFlag_mapBooleanToString_enabled:false}
 featureFlag.asIngestedCoordinates.enabled=${featureFlag_asIngestedCoordinates_enabled:true}
 featureFlag.keywordLower.enabled=${featureFlag_keywordLower_enabled:true}
 featureFlag.bagOfWords.enabled=${featureFlag_bagOfWords_enabled:true}
-- 
GitLab