diff --git a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java index 017a126087bdbd308bd2772c75fb4e3e2fc1562b..42d8a8a4645aad05f9ea3a8457fa0d9ba53ee6b9 100644 --- a/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java +++ b/indexer-core/src/main/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImpl.java @@ -18,14 +18,6 @@ import com.google.common.base.Strings; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Array; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import javax.inject.Inject; import org.apache.http.HttpStatus; import org.opengroup.osdu.core.common.model.indexer.ElasticType; import org.opengroup.osdu.core.common.model.indexer.IndexingStatus; @@ -37,6 +29,16 @@ import org.opengroup.osdu.indexer.util.parser.NumberParser; import org.springframework.stereotype.Service; import org.springframework.web.context.annotation.RequestScope; +import javax.inject.Inject; +import java.lang.reflect.Array; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; + @Service @RequestScope public class AttributeParsingServiceImpl implements IAttributeParsingService { @@ -54,6 +56,8 @@ public class AttributeParsingServiceImpl implements IAttributeParsingService { @Inject private JobStatus jobStatus; + private Gson gson = new Gson(); + @Override public void tryParseValueArray(Class<?> attributeClass, String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) { BiFunction<String, Object, ?> parser; @@ -158,7 +162,7 @@ public class AttributeParsingServiceImpl implements IAttributeParsingService { try { Type type = new TypeToken<Map<String, Double>>() {}.getType(); - Map<String, Double> positionMap = new Gson().fromJson(attributeVal.toString(), type); + Map<String, Double> positionMap = this.gson.fromJson(attributeVal.toString(), type); if (positionMap == null || positionMap.isEmpty()) return; @@ -177,8 +181,20 @@ public class AttributeParsingServiceImpl implements IAttributeParsingService { public void tryParseGeojson(String recordId, String attributeName, Object attributeVal, Map<String, Object> dataMap) { try { - Type type = new TypeToken<Map<String, Object>>() {}.getType(); - Map<String, Object> geoJsonMap = new Gson().fromJson(attributeVal.toString(), type); + Map<String, Object> geoJsonMap = new HashMap<>(); + if (attributeVal instanceof Map) { + try { + geoJsonMap = (Map<String, Object>) attributeVal; + } catch (ClassCastException e) { + String parsingError = String.format("geo-json shape parsing error: %s attribute: %s", e.getMessage(), attributeName); + jobStatus.addOrUpdateRecordStatus(recordId, IndexingStatus.WARN, HttpStatus.SC_BAD_REQUEST, parsingError, String.format("record-id: %s | %s", recordId, parsingError)); + } + } + + if (geoJsonMap.isEmpty()) { + Type type = new TypeToken<Map<String, Object>>() {}.getType(); + geoJsonMap = this.gson.fromJson(this.gson.toJson(attributeVal, type), type); + } if (geoJsonMap == null || geoJsonMap.isEmpty()) return; @@ -191,19 +207,19 @@ public class AttributeParsingServiceImpl implements IAttributeParsingService { } } - @Override - public void tryParseNested(String recordId, String name, Object value, Map<String, Object> dataMap) { - dataMap.put(name,value); - } + @Override + public void tryParseNested(String recordId, String name, Object value, Map<String, Object> dataMap) { + dataMap.put(name, value); + } - @Override - public void tryParseObject(String recordId, String name, Object value, Map<String, Object> dataMap) { - dataMap.put(name,value); - } + @Override + public void tryParseObject(String recordId, String name, Object value, Map<String, Object> dataMap) { + dataMap.put(name, value); + } @Override public void tryParseFlattened(String recordId, String name, Object value, Map<String, Object> dataMap) { - dataMap.put(name,value); + dataMap.put(name, value); } diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImplTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImplTest.java index 1372a8c45330ee2d8ecb600f664502776d456e6b..94d06cf2e81414807f5b7ddc55c3747dec708a70 100644 --- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImplTest.java +++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/service/AttributeParsingServiceImplTest.java @@ -31,11 +31,15 @@ import org.opengroup.osdu.indexer.util.parser.NumberParser; import org.springframework.test.context.junit4.SpringRunner; import java.lang.reflect.Type; +import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.Date; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; @@ -315,8 +319,21 @@ public class AttributeParsingServiceImplTest { @Test public void should_returnGeoShape_given_validTreeMap_tryGetGeoShapeTest() { final String shapeJson = "{\"type\":\"Polygon\",\"coordinates\":[[[100,0],[101,0],[101,1],[100,1],[100,0]]]}"; - Map<String, Object> storageData = new HashMap<>(); - storageData.put("location", parseJson(shapeJson)); + Map<String, Object> storageData = parseJson(shapeJson); + + when(this.geoShapeParser.parseGeoJson(storageData)).thenReturn(new HashMap<>()); + + Map<String, Object> dataMap = new HashMap<>(); + + this.sut.tryParseGeojson("", "location", storageData, dataMap); + + assertFalse(dataMap.isEmpty()); + } + + @Test + public void should_returnGeoShape_given_validTreeMap_tryGetGeoShapeWithPropertiesTest() { + final String shapeJson = "{\"features\":[{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-105.01621,39.57422]},\"properties\":{\"id\":\"opendes:work-product-component--GenericRepresentation:0be3c0de-7844-4bcb-a17d-83de84cd2eca\",\"uri\":\"wdms:opendes:1188d27c-9132-41ec-b281-502a6245d00c:f597df66-4197-4347-99c2-acb58ce27ef3:0be3c0de-7844-4bcb-a17d-83de84cd2eca\"},\"type\":\"Feature\"}],\"type\":\"FeatureCollection\"}"; + Map<String, Object> storageData = parseJson(shapeJson); when(this.geoShapeParser.parseGeoJson(storageData)).thenReturn(new HashMap<>()); @@ -330,8 +347,7 @@ public class AttributeParsingServiceImplTest { @Test public void should_throwException_given_geoShapeParingFailed() { final String shapeJson = "{\"type\":\"Polygon\",\"coordinates\":[[[100,NaN],[101,0],[101,1],[100,1],[100,0]]]}"; - Map<String, Object> storageData = new HashMap<>(); - storageData.put("location", parseJson(shapeJson)); + Map<String, Object> storageData = parseJson(shapeJson); when(this.geoShapeParser.parseGeoJson(any())).thenThrow(new IllegalArgumentException("geo coordinates must be numbers")); @@ -374,4 +390,4 @@ public class AttributeParsingServiceImplTest { */ void accept(T t, U u, V v, W w, X x); } -} \ No newline at end of file +} diff --git a/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/GeoShapeParserTest.java b/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/GeoShapeParserTest.java index fdec7478428205923da22ffc9d7d53040845830f..3107c5277f67b7c7140da1e8c21173de6423da4c 100644 --- a/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/GeoShapeParserTest.java +++ b/indexer-core/src/test/java/org/opengroup/osdu/indexer/util/parser/GeoShapeParserTest.java @@ -89,6 +89,13 @@ public class GeoShapeParserTest { this.validateInput(this.sut::parseGeoJson, shapeJson, expectedParsedShape, Strings.EMPTY); } + @Test + public void should_parseValidWithPropertyPoint() { + String shapeJson = getGeoShapeFromFile("input/valid_point_with_property.json"); + String expectedParsedShape = getGeoShapeFromFile("expected/valid_point.json"); + this.validateInput(this.sut::parseGeoJson, shapeJson, expectedParsedShape, Strings.EMPTY); + } + @Test public void should_parseValidMultiPoint() { String shapeJson = getGeoShapeFromFile("input/valid_multi_point.json"); diff --git a/indexer-core/src/test/resources/geojson/parsing/input/valid_point_with_property.json b/indexer-core/src/test/resources/geojson/parsing/input/valid_point_with_property.json new file mode 100644 index 0000000000000000000000000000000000000000..f2b6e304a388b4e7e16caa2561601b6b365963ec --- /dev/null +++ b/indexer-core/src/test/resources/geojson/parsing/input/valid_point_with_property.json @@ -0,0 +1,19 @@ +{ + "features": [ + { + "geometry": { + "type": "Point", + "coordinates": [ + -105.01621, + 39.57422 + ] + }, + "properties": { + "id": "opendes:work-product-component--GenericRepresentation:0be3c0de-7844-4bcb-a17d-83de84cd2eca", + "uri": "wdms:opendes:1188d27c-9132-41ec-b281-502a6245d00c:f597df66-4197-4347-99c2-acb58ce27ef3:0be3c0de-7844-4bcb-a17d-83de84cd2eca" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +}