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 3506c2ca092db2688a6f15a2eca790082ab9b05b..d98b1f77281138a9c3de3304350da461cda9ac08 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 @@ -56,8 +56,10 @@ public class PropertiesProcessor { public Stream<Map<String, Object>> processItem(AllOfItem allOfItem) { Preconditions.checkNotNull(allOfItem, "allOfItem cannot be null"); - if (Objects.nonNull(allOfItem.getAllOf())) { - return allOfItem.getAllOf().stream().flatMap(this::processItem); + Stream<Map<String, Object>> ofItems = processOfItems(allOfItem.getAllOf(), allOfItem.getAnyOf(), allOfItem.getOneOf()); + + if (Objects.nonNull(ofItems)) { + return ofItems; } String ref = allOfItem.getRef(); @@ -89,13 +91,34 @@ public class PropertiesProcessor { new AppException(HttpStatus.SC_NOT_FOUND, "Failed to find definition:" + definitionSubRef, "Unknown definition:" + definitionSubRef)); - if (Objects.nonNull(definition.getAllOf())) { - return definition.getAllOf().stream().flatMap(this::processItem); + Stream<Map<String, Object>> ofItems = + processOfItems(definition.getAllOf(), definition.getAnyOf(), definition.getOneOf()); + + if (Objects.nonNull(ofItems)) { + return ofItems; } return processProperties(definition.getProperties()); } + private Stream<Map<String, Object>> processOfItems(List<AllOfItem> allOf, List<AllOfItem> anyOf, List<AllOfItem> oneOf) { + Stream<Map<String, Object>> ofItems = null; + + if (Objects.nonNull(allOf)) { + ofItems = allOf.stream().flatMap(this::processItem); + } + + if (Objects.nonNull(anyOf)) { + ofItems = Stream.concat(Optional.ofNullable(ofItems).orElseGet(Stream::empty), anyOf.stream().flatMap(this::processItem)); + } + + if (Objects.nonNull(oneOf)) { + ofItems = Stream.concat(Optional.ofNullable(ofItems).orElseGet(Stream::empty), oneOf.stream().flatMap(this::processItem)); + } + + return ofItems; + } + public Stream<Map<String, Object>> processProperties(Map<String, TypeProperty> properties){ return properties.entrySet().stream().flatMap(this::processPropertyEntry); } @@ -118,11 +141,10 @@ public class PropertiesProcessor { return Stream.empty(); } - if (Objects.nonNull(entry.getValue().getAllOf())) { - PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey() - , log, new SchemaConverterPropertiesConfig()); + Stream<Map<String, Object>> ofItems = processOfItems(entry); - return entry.getValue().getAllOf().stream().flatMap(propertiesProcessor::processItem); + if (Objects.nonNull(ofItems)) { + return ofItems; } if (Objects.nonNull(entry.getValue().getProperties())) { @@ -139,6 +161,35 @@ public class PropertiesProcessor { return storageSchemaEntry(getTypeByDefinitionProperty(entry.getValue()), pathPrefixWithDot + entry.getKey()); } + private Stream<Map<String, Object>> processOfItems(Map.Entry<String, TypeProperty> entry) { + Stream<Map<String, Object>> ofItems = null; + + if (Objects.nonNull(entry.getValue().getAllOf())) { + PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey() + , log, new SchemaConverterPropertiesConfig()); + + ofItems = entry.getValue().getAllOf().stream().flatMap(propertiesProcessor::processItem); + } + + if (Objects.nonNull(entry.getValue().getAnyOf())) { + PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey() + , log, new SchemaConverterPropertiesConfig()); + + ofItems = Stream.concat(Optional.ofNullable(ofItems).orElseGet(Stream::empty), + entry.getValue().getAnyOf().stream().flatMap(propertiesProcessor::processItem)); + } + + if (Objects.nonNull(entry.getValue().getOneOf())) { + PropertiesProcessor propertiesProcessor = new PropertiesProcessor(definitions, pathPrefixWithDot + entry.getKey() + , log, new SchemaConverterPropertiesConfig()); + + ofItems = Stream.concat(Optional.ofNullable(ofItems).orElseGet(Stream::empty), + entry.getValue().getOneOf().stream().flatMap(propertiesProcessor::processItem)); + } + + return ofItems; + } + private Stream<Map<String, Object>> storageSchemaEntry(String kind, String path) { Preconditions.checkNotNullOrEmpty(kind, "kind cannot be null or empty"); Preconditions.checkNotNullOrEmpty(path, "path cannot be null or empty"); 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 1dc63193b3db8c761f492165f9363390a709bdca..f613d9f9c77e433f62a333b4688ad47b8e67a245 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 @@ -97,6 +97,18 @@ public class SchemaToStorageFormatImpl implements SchemaToStorageFormat { .collect(Collectors.toList())); } + if (schemaData.getAnyOf() != null) { + storageSchemaItems.addAll(schemaServiceSchema.getProperties().getData().getAnyOf().stream() + .flatMap(propertiesProcessor::processItem) + .collect(Collectors.toList())); + } + + if (schemaData.getOneOf() != null) { + storageSchemaItems.addAll(schemaServiceSchema.getProperties().getData().getOneOf().stream() + .flatMap(propertiesProcessor::processItem) + .collect(Collectors.toList())); + } + if (schemaData.getRef() != null) { storageSchemaItems.addAll(propertiesProcessor.processRef(schemaData.getRef()) .collect(Collectors.toList())); 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 845325962f475bd6c02e3999d02a32b43b7fafba..3b5e146c5760cd3084651a612fae228d5a80c035 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 @@ -299,4 +299,67 @@ Ignored for now (array of references) ``` -\"kind\": \"long\" \ No newline at end of file +\"kind\": \"long\" + +Processing specifics +---------------------------------------------------------------------------- + +allOf, anyOf and oneOf tags are processed at the same way. All internal data(properties) are included into converted schema. + +For instance +```json +{ + "definitions": { + "wellboreData1": { + "properties": { + "prop1": { + "type": "string" + } + } + }, + "wellboreData2": { + "properties": { + "prop2": { + "type": "string" + } + } + } + }, + "properties": { + "data": { + "allOf": [ + { + "anyOf": [ + { + "$ref": "#/definitions/wellboreData1" + } ], + "oneOf": [ + { + "$ref": "#/definitions/wellboreData2" + } + ] + } + ] + } + } +} + +``` + +is converted to + +```json +{ + "kind": "KIND_VAL", + "schema": [ + { + "kind": "string", + "path": "prop1" + }, + { + "kind": "string", + "path": "prop2" + } + ] +} +``` diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/AllOfItem.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/AllOfItem.java index bef9a14bc622a148ddb9d2603914015d1d1bad73..1354c3bd1b1dde40a19214ae1f3d5e56298f5b2a 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/AllOfItem.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/AllOfItem.java @@ -27,4 +27,6 @@ public class AllOfItem { private String type; private Map<String, TypeProperty> properties; private List<AllOfItem> allOf; + private List<AllOfItem> oneOf; + private List<AllOfItem> anyOf; } \ No newline at end of file diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/Definition.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/Definition.java index be8292a287a15885b64f7da6b4770451b5b4d088..4665c6a82c796dc96ec209f30e9257788b70b8f0 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/Definition.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/Definition.java @@ -23,4 +23,6 @@ import java.util.Map; public class Definition { private Map<String, TypeProperty> properties; private List<AllOfItem> allOf; + private List<AllOfItem> oneOf; + private List<AllOfItem> anyOf; } diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/PropertiesData.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/PropertiesData.java index 6c09c0116b6fbe269d93c13931a46493950fbc9a..61f1edb98ab5aa76438ece4eee8c0d15cac85fc1 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/PropertiesData.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/PropertiesData.java @@ -23,6 +23,8 @@ import java.util.Map; @Data public class PropertiesData { private List<AllOfItem> allOf; + private List<AllOfItem> oneOf; + private List<AllOfItem> anyOf; @JsonProperty("$ref") private String ref; private Map<String, TypeProperty> properties; diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/TypeProperty.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/TypeProperty.java index 3053e5d20a85ee5165d5436147b9e5c9a1bafc37..b929bad43f401e97fbc4f5b3ce8fd22344e14a76 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/TypeProperty.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/schema/converter/tags/TypeProperty.java @@ -30,4 +30,6 @@ public class TypeProperty { private Items items; private Map<String, TypeProperty> properties; private List<AllOfItem> allOf; + private List<AllOfItem> oneOf; + private List<AllOfItem> anyOf; } 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 c90092879cf6047a76bb03a0f876abb59e40d358..07642442dc178ce37cf934fdfbdbf7a0d044171e 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 @@ -94,6 +94,21 @@ public class SchemaToStorageFormatImplTest { testSingleFile("/converter/tags/allOf/indefinitions.json", KIND); } + @Test + public void oneOfInDefinitions() { + testSingleFile("/converter/tags/oneOf/indefinitions.json", KIND); + } + + @Test + public void anyOfInDefinitions() { + testSingleFile("/converter/tags/anyOf/indefinitions.json", KIND); + } + + @Test + public void mixAllAnyOneOf() { + testSingleFile("/converter/tags/mixAllAnyOneOf/mix.json", KIND); + } + @Test public void folderPassed() throws URISyntaxException, IOException { diff --git a/indexer-core/src/test/resources/converter/integration-tests/index_records_1.schema b/indexer-core/src/test/resources/converter/integration-tests/index_records_1.schema index 672c3d965d50194ac5c80adecfddbeb24d51a856..779d2d20921f97aa86bed06943358d76c3d5f71f 100644 --- a/indexer-core/src/test/resources/converter/integration-tests/index_records_1.schema +++ b/indexer-core/src/test/resources/converter/integration-tests/index_records_1.schema @@ -20,7 +20,11 @@ }, "County": { "type": "string" - }, + }}}], + "anyOf": [ + { + "type": "object", + "properties": { "State": { "type": "string" }, @@ -41,7 +45,11 @@ }, "EmptyAttribute": { "type": "string" - }, + }}}], + "oneOf": [ + { + "type": "object", + "properties": { "Rank": { "type": "integer" }, diff --git a/indexer-core/src/test/resources/converter/tags/anyOf/indefinitions.json b/indexer-core/src/test/resources/converter/tags/anyOf/indefinitions.json new file mode 100644 index 0000000000000000000000000000000000000000..4733286c10bd2d081ae85fa44ee22d499a86908d --- /dev/null +++ b/indexer-core/src/test/resources/converter/tags/anyOf/indefinitions.json @@ -0,0 +1,29 @@ +{ + "definitions": { + "wellboreData1": { + "properties": { + "prop1": { + "type": "string" + } + } + }, + "wellboreData2": { + "anyOf": [ + { + "$ref": "#/definitions/wellboreData1" + } + ] + } + }, + "properties": { + "data": { + "type": "object", + "properties": { + "Field": { + "$ref": "#/definitions/wellboreData2" + } + } + } + } +} + diff --git a/indexer-core/src/test/resources/converter/tags/anyOf/indefinitions.json.res b/indexer-core/src/test/resources/converter/tags/anyOf/indefinitions.json.res new file mode 100644 index 0000000000000000000000000000000000000000..e17ce90d066d023859f6b91d7756717b494a7a45 --- /dev/null +++ b/indexer-core/src/test/resources/converter/tags/anyOf/indefinitions.json.res @@ -0,0 +1,9 @@ +{ + "kind": "KIND_VAL", + "schema": [ + { + "kind": "string", + "path": "Field.prop1" + } + ] +} \ No newline at end of file diff --git a/indexer-core/src/test/resources/converter/tags/mixAllAnyOneOf/mix.json b/indexer-core/src/test/resources/converter/tags/mixAllAnyOneOf/mix.json new file mode 100644 index 0000000000000000000000000000000000000000..2eb9de93a9911ad6407366a362fa0604219f7361 --- /dev/null +++ b/indexer-core/src/test/resources/converter/tags/mixAllAnyOneOf/mix.json @@ -0,0 +1,57 @@ +{ + "definitions": { + "wellboreData1": { + "properties": { + "prop1": { + "type": "string" + } + } + }, + "wellboreData2": { + "properties": { + "prop2": { + "type": "string" + } + } + }, + "wellboreData3": { + "properties": { + "prop3": { + "type": "string" + } + } + }, + "wellboreData4": { + "properties": { + "prop4": { + "type": "string" + } + } + } + }, + "properties": { + "data": { + "allOf": [ + { + "anyOf": [ + { + "$ref": "#/definitions/wellboreData1" + } ], + "oneOf": [ + { + "$ref": "#/definitions/wellboreData2" + } + ] + }, + { + "$ref": "#/definitions/wellboreData3" + }, + { + "$ref": "#/definitions/wellboreData4" + } + ] + } + } +} + + diff --git a/indexer-core/src/test/resources/converter/tags/mixAllAnyOneOf/mix.json.res b/indexer-core/src/test/resources/converter/tags/mixAllAnyOneOf/mix.json.res new file mode 100644 index 0000000000000000000000000000000000000000..22a8e6a806ba17e51adbd690f0ef56ac4f9f7bbe --- /dev/null +++ b/indexer-core/src/test/resources/converter/tags/mixAllAnyOneOf/mix.json.res @@ -0,0 +1,21 @@ +{ + "kind": "KIND_VAL", + "schema": [ + { + "kind": "string", + "path": "prop1" + }, + { + "kind": "string", + "path": "prop2" + }, + { + "kind": "string", + "path": "prop3" + }, + { + "kind": "string", + "path": "prop4" + } + ] +} \ No newline at end of file diff --git a/indexer-core/src/test/resources/converter/tags/oneOf/indefinitions.json b/indexer-core/src/test/resources/converter/tags/oneOf/indefinitions.json new file mode 100644 index 0000000000000000000000000000000000000000..4733286c10bd2d081ae85fa44ee22d499a86908d --- /dev/null +++ b/indexer-core/src/test/resources/converter/tags/oneOf/indefinitions.json @@ -0,0 +1,29 @@ +{ + "definitions": { + "wellboreData1": { + "properties": { + "prop1": { + "type": "string" + } + } + }, + "wellboreData2": { + "anyOf": [ + { + "$ref": "#/definitions/wellboreData1" + } + ] + } + }, + "properties": { + "data": { + "type": "object", + "properties": { + "Field": { + "$ref": "#/definitions/wellboreData2" + } + } + } + } +} + diff --git a/indexer-core/src/test/resources/converter/tags/oneOf/indefinitions.json.res b/indexer-core/src/test/resources/converter/tags/oneOf/indefinitions.json.res new file mode 100644 index 0000000000000000000000000000000000000000..e17ce90d066d023859f6b91d7756717b494a7a45 --- /dev/null +++ b/indexer-core/src/test/resources/converter/tags/oneOf/indefinitions.json.res @@ -0,0 +1,9 @@ +{ + "kind": "KIND_VAL", + "schema": [ + { + "kind": "string", + "path": "Field.prop1" + } + ] +} \ No newline at end of file diff --git a/testing/indexer-test-core/src/main/resources/testData/index_records_1.schema.json b/testing/indexer-test-core/src/main/resources/testData/index_records_1.schema.json index 2a6e6301a41b6b4f8d82839c2faca994336a46a3..9e54b33862a2f0b8d81277f79e2959b3b141e7bf 100644 --- a/testing/indexer-test-core/src/main/resources/testData/index_records_1.schema.json +++ b/testing/indexer-test-core/src/main/resources/testData/index_records_1.schema.json @@ -4,7 +4,7 @@ "authority": "tenant1", "source": "indexer-int-test", "entityType": "sample-schema-1", - "schemaVersionMajor": "1", + "schemaVersionMajor": "2", "schemaVersionMinor": "0", "schemaVersionPatch": "4" }, @@ -32,7 +32,14 @@ }, "County": { "type": "string" - }, + } + } + } + ], + "anyOf": [ + { + "type": "object", + "properties": { "State": { "type": "string" }, @@ -53,7 +60,14 @@ }, "EmptyAttribute": { "type": "string" - }, + } + } + } + ], + "oneOf": [ + { + "type": "object", + "properties": { "Rank": { "type": "integer" },