From bff9f5a04055d22649b129481c0bac0023b3c0c2 Mon Sep 17 00:00:00 2001 From: rng Date: Fri, 7 Aug 2026 12:20:51 +1000 Subject: [PATCH] Remove all calls related to the item/summary which is obsoleted --- .../server/core/service/ElasticSearch.java | 295 +----------------- .../server/core/service/OGCApiService.java | 18 -- .../ogcapi/server/core/service/Search.java | 2 - .../aodn/ogcapi/server/features/RestApi.java | 24 -- .../ogcapi/server/features/RestServices.java | 6 +- .../server/features/RestServicesTest.java | 19 -- .../server/service/ElasticSearchTest.java | 121 +------ 7 files changed, 8 insertions(+), 477 deletions(-) diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/ElasticSearch.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/ElasticSearch.java index c3c529dd..4e3e8392 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/ElasticSearch.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/ElasticSearch.java @@ -1,7 +1,5 @@ package au.org.aodn.ogcapi.server.core.service; -import au.org.aodn.ogcapi.features.model.FeatureGeoJSON; -import au.org.aodn.ogcapi.server.core.model.EsFeatureCollectionModel; import au.org.aodn.stac.model.SearchSuggestionsModel; import au.org.aodn.stac.model.StacCollectionModel; import au.org.aodn.ogcapi.server.core.model.enumeration.*; @@ -22,7 +20,6 @@ import org.geotools.filter.text.commons.CompilerUtil; import org.geotools.filter.text.commons.Language; import org.geotools.filter.text.cql2.CQLException; -import org.openapitools.jackson.nullable.JsonNullable; import org.opengis.filter.Filter; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; @@ -601,297 +598,7 @@ protected static FieldValue toFieldValue(String s) { // we will prefix it with STR_INDICATOR return FieldValue.of(s.replaceFirst(STR_INDICATOR, "").trim()); } - // Assume it is string + // Assume it is a string return FieldValue.of(s.trim()); } - /** - * We will need to create a aggregation for each of the feature query, this one target the summary feature - * which create a summary of the indexed count group by geometry and date range for the cloud optimized data. - * Below code equals this: - * { - * "aggregations": { - * "coordinates": { - * "aggregations": { - * "total_count": { - * "sum": { - * "field": "properties.count" - * } - * }, - * "max_time": { - * "max": { - * "field": "properties.time" - * } - * }, - * "min_time": { - * "min": { - * "field": "properties.time" - * } - * }, - * "coordinates": { - * "top_hits": { - * "size": 1, - * "sort": [ - * { - * "collection.keyword": { - * "order": "asc" - * } - * }, - * { - * "geometry.geometry.coordinates": { - * "order": "asc" - * } - * }, - * ] - * } - * } - * }, - * "composite": { - * "size": 2200, - * "sources": [ - * { - * "collection": { - * "terms": { - * "field": "collection.keyword" - * } - * } - * }, - * { - * "coordinates": { - * "terms": { - * "script": { - * "source": "doc['geometry.geometry.coordinates'].value.toString()", - * "lang": "painless" - * } - * } - * } - * } - * ] - * } - * } - * }, - * "size": 0 - * } - * - * @param collectionId - The metadata set id - * @param properties - The field you want to return - * @param filter - Any filter applied to the summary operation - * @return - Result - */ -// @Override -// public ElasticSearchBase.SearchResult searchFeatureSummary(String collectionId, List properties, String filter) { -// -// final String COORDINATES = "coordinates"; -// final String TOTAL_COUNT = "total_count"; -// final String MIN_TIME = "min_time"; -// final String MAX_TIME = "max_time"; -// -// BiFunction, Map, SearchRequest.Builder> builderSupplier = ( -// arguments, afterKey) -> { -// -// SearchRequest.Builder builder = new SearchRequest.Builder(); -// -// builder.query(q -> q -// .term(t -> t -// .field(CQLFeatureFields.collection.searchField) -// .value(arguments.get("collectionId")) -// ) -// ); -// -// // Group by lng -// CompositeAggregationSource lng = CompositeAggregationSource.of(c -> c.terms(t -> t -// .field(CQLFeatureFields.lng.searchField))); -// -// // Group by lat -// CompositeAggregationSource lat = CompositeAggregationSource.of(c -> c.terms(t -> t -// .field(CQLFeatureFields.lat.searchField))); -// -// // Use afterKey to page to another batch of records if exist -// Aggregation compose = afterKey == null ? -// new Aggregation.Builder().composite(c -> c -// .sources(List.of( -// Map.of(CQLFeatureFields.lng.name(), lng), -// Map.of(CQLFeatureFields.lat.name(), lat)) -// ) -// .size(pageSize) -// ).build() -// : -// new Aggregation.Builder().composite(c -> c -// .sources(List.of( -// Map.of(CQLFeatureFields.lng.name(), lng), -// Map.of(CQLFeatureFields.lat.name(), lat)) -// ) -// .size(pageSize) -// .after(afterKey) -// ).build(); -// -// -// // Sum of count -// Aggregation sum = SumAggregation.of(s -> s.field(CQLFeatureFields.count.searchField))._toAggregation(); -// -// // Min value of field -// Aggregation min = MinAggregation.of(s -> s.field(CQLFeatureFields.temporal.searchField))._toAggregation(); -// -// // Max value of field -// Aggregation max = MaxAggregation.of(s -> s.field(CQLFeatureFields.temporal.searchField))._toAggregation(); -// -// // Field value to return, think of it as select part of SQL -// Aggregation field = new Aggregation.Builder().topHits(th -> th.size(1) -// .sort(createSortOptions( -// String.format("%s,%s", CQLFeatureFields.lng.name(), CQLFeatureFields.lat.name()), -// CQLFeatureFields.class))) -// .build(); -// -// Aggregation aggregation = new Aggregation.Builder() -// .composite(compose.composite()) -// .aggregations(Map.of( -// TOTAL_COUNT, sum, -// MIN_TIME, min, -// MAX_TIME, max, -// COORDINATES, field -// )) -// .build(); -// -// // There is a limitation that all sort field, assume to be inside the properties -// Aggregation nested = new Aggregation.Builder().nested(n -> n -// .path("properties") -// ) -// .aggregations(COORDINATES, aggregation) -// .build(); -// -// -// builder.index(dataIndexName) -// .size(0) // Do not return hits, only aggregations, that is the hits().hit() section will be empty -// .aggregations(COORDINATES, nested); -// -// return builder; -// }; -// -// try { -// var queryTimer = new StopWatch(); -// queryTimer.start("query timer"); -// ElasticSearchBase.SearchResult result = new ElasticSearchBase.SearchResult<>(); -// result.setCollections(new ArrayList<>()); -// -// Map arguments = Map.of( -// "collectionId", FieldValue.of(collectionId), -// "aggKey", FieldValue.of(COORDINATES) -// ); -// Iterable response = pageableAggregation(builderSupplier, CompositeBucket.class, arguments, null); -// -// queryTimer.stop(); -// log.info(queryTimer.prettyPrint()); -// var analyzingTimer = new StopWatch(); -// analyzingTimer.start("analyzing timer"); -// for (CompositeBucket node : response) { -// if (node != null) { -// StacItemModel. StacItemModelBuilder model = StacItemModel.builder(); -// -// result.setTotal(result.getTotal() + node.docCount()); -// -// TopHitsAggregate th = node.aggregations().get(COORDINATES).topHits(); -// model.uuid(th.hits().hits().get(0).id()); -// -// JsonData jd = th.hits().hits().get(0).source(); -// if(jd != null) { -// Map map = jd.to(Map.class); -// BigDecimal lng = BigDecimal.valueOf((double)map.get("lng")); -// BigDecimal lat = BigDecimal.valueOf((double)map.get("lat")); -// model.geometry(Map.of("geometry", Map.of( -// "coordinates", List.of(lng, lat) -// ))); -// } -// -// SumAggregate sa = node.aggregations().get(TOTAL_COUNT).sum(); -// MinAggregate min = node.aggregations().get(MIN_TIME).min(); -// MaxAggregate max = node.aggregations().get(MAX_TIME).max(); -// -// model.properties(Map.of( -// FeatureProperty.COUNT.getValue(), sa.value(), -// FeatureProperty.START_TIME.getValue(), min.valueAsString() == null ? "" : min.valueAsString(), -// FeatureProperty.END_TIME.getValue(), max.valueAsString() == null ? "" : max.valueAsString() -// )); -// -// result.getCollections().add(model.build()); -// } -// } -// analyzingTimer.stop(); -// log.info(analyzingTimer.prettyPrint()); -// return result; -// } -// catch (Exception e) { -// log.error("Error while searching dataset.", e); -// } -// return null; -// } - - @Override - public SearchResult searchFeatureSummary(String collectionId, List properties, String filter) { - try { - SearchRequest searchRequest = new SearchRequest.Builder() - .index(dataIndexName) - .query(q -> q.term(t -> t - .field("properties.collection.keyword") - .value(collectionId) - )) - .size(1000) - .build(); - - var response = esClient.search(searchRequest, EsFeatureCollectionModel.class); - - SearchResult result = new SearchResult<>(); - List features = new ArrayList<>(); - for (var hit : response.hits().hits()) { - EsFeatureCollectionModel hitFeatureCollection = hit.source(); - if (hitFeatureCollection != null && hitFeatureCollection.getFeatures() != null) { - // A collectionID may map to several dataset key. So we need to identify features with dataset keys. TO get a dataset key which sits in hit.properties.key. For example: - // "properties": { - // "date": "2011-04", - // "collection": "4d3d4aca-472e-4616-88a5-df0f5ab401ba", - // "key": "mooring_acidification_realtime_qc.parquet" - // } - String datasetKey = null; - if (hitFeatureCollection.getProperties() != null) { - Object keyObj = hitFeatureCollection.getProperties().get("key"); - if (keyObj != null) { - datasetKey = keyObj.toString(); - } - } - - List documentFeatures = - hitFeatureCollection.toFeatureCollectionGeoJSON().getFeatures(); - - for (FeatureGeoJSON feature : documentFeatures) { - // add key in property field for each feature - if (datasetKey != null) { - JsonNullable propertiesWrapper = feature.getProperties(); - Map featurePropsMap = new HashMap<>(); - - if (propertiesWrapper != null - && propertiesWrapper.isPresent() - && propertiesWrapper.get() instanceof Map existingProps) { - existingProps.forEach((k, v) -> featurePropsMap.put(String.valueOf(k), v)); - } - - featurePropsMap.put("key", datasetKey); - feature.setProperties(JsonNullable.of(featurePropsMap)); - } - features.add(feature); - } - } - } - - log.info("feature size: {}", features.size()); - - result.setCollections(features); - if (response.hits().total() != null) { - result.setTotal(response.hits().total().value()); - } - - return result; - - } catch (IOException e) { - log.error("Error while searching dataset.", e); - } - return null; - } } diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/OGCApiService.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/OGCApiService.java index 3d88c439..b96b7d5b 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/OGCApiService.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/OGCApiService.java @@ -31,9 +31,6 @@ public abstract class OGCApiService { @Autowired protected Search search; - // Hard coded dataset to avoid summary query, the AMSA should be skipped - private static final String EMPTY_SUMMARY_COLLECTION_ID = "2a5739e7-0cb8-444a-b83b-b2bc841b0ce8"; - /** * You can find conformance id * here @@ -46,21 +43,6 @@ public ResponseEntity getFeature(String collectionId, List properties, String filter) throws Exception { switch(fid) { - case summary -> { - if (EMPTY_SUMMARY_COLLECTION_ID.equals(collectionId)) { - var featureCollection = new FeatureCollectionGeoJSON(); - featureCollection.setType(FeatureCollectionGeoJSON.TypeEnum.FEATURECOLLECTION); - featureCollection.setFeatures(List.of()); - return ResponseEntity.ok().body(featureCollection); - } - - var result = search.searchFeatureSummary(collectionId, properties, filter); - var featureCollection = new FeatureCollectionGeoJSON(); - featureCollection.setType(FeatureCollectionGeoJSON.TypeEnum.FEATURECOLLECTION); - featureCollection.setFeatures(result.getCollections()); - return ResponseEntity.ok() - .body(featureCollection); - } default -> { // Individual item return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/Search.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/Search.java index f105283d..49cadeb3 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/Search.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/Search.java @@ -1,6 +1,5 @@ package au.org.aodn.ogcapi.server.core.service; -import au.org.aodn.ogcapi.features.model.FeatureGeoJSON; import au.org.aodn.stac.model.StacCollectionModel; import au.org.aodn.ogcapi.server.core.model.enumeration.CQLCrsType; import co.elastic.clients.transport.endpoints.BinaryResponse; @@ -18,7 +17,6 @@ public interface Search { ElasticSearchBase.SearchResult searchCollections(String id); ElasticSearchBase.SearchResult searchCollections(List ids, String sortBy); ElasticSearchBase.SearchResult searchAllCollections(String sortBy) throws Exception; - ElasticSearchBase.SearchResultsearchFeatureSummary(String collectionId, List properties, String filter) throws Exception; ElasticSearchBase.SearchResult searchByParameters( List targets, diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/features/RestApi.java b/server/src/main/java/au/org/aodn/ogcapi/server/features/RestApi.java index 5a47a2c6..236f630c 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/features/RestApi.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/features/RestApi.java @@ -3,9 +3,7 @@ import au.org.aodn.ogcapi.features.api.CollectionsApi; import au.org.aodn.ogcapi.features.model.*; import au.org.aodn.ogcapi.features.model.Exception; -import au.org.aodn.ogcapi.server.core.model.enumeration.CQLFields; import au.org.aodn.ogcapi.server.core.model.enumeration.FeatureId; -import au.org.aodn.ogcapi.server.core.service.OGCApiService; import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Operation; @@ -93,28 +91,6 @@ public ResponseEntity getFeature( @ParameterObject @Valid FeatureRequest request) { FeatureId fid = FeatureId.valueOf(FeatureId.class, featureId); switch (fid) { - case summary -> { - String filter = null; - - if (request.getDatetime() != null) { - filter = OGCApiService.processDatetimeParameter(CQLFields.temporal.name(), request.getDatetime(), filter); - } - - if (request.getBbox() != null) { - filter = OGCApiService.processBBoxParameter(CQLFields.geometry.name(), request.getBbox(), filter); - } - - try { - return featuresService.getFeature( - collectionId, - fid, - request.getProperties(), - filter != null ? "filter=" + filter : null - ); - } catch (Throwable e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - } - } case dataset_metadata -> { return featuresService.getDatasetMetadata(collectionId); } diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/features/RestServices.java b/server/src/main/java/au/org/aodn/ogcapi/server/features/RestServices.java index c5df22da..bbbcc700 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/features/RestServices.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/features/RestServices.java @@ -137,7 +137,7 @@ public ResponseEntity getWmsLegend(String collectionId, FeatureRequest r * This is used to get the WFS fields given a WFS layer * * @param collectionId - The uuid of dataset - * @param request -Request to get field given a WFS layer name; if no layer name provided, it will return fields for all WFS links in the collection + * @param request - Request to get a field given a WFS layer name; if no layer name provided, it will return fields for all WFS links in the collection * @return - The WFS fields */ public ResponseEntity getWfsFields(String collectionId, FeatureRequest request) { @@ -151,7 +151,7 @@ public ResponseEntity getWfsFields(String collectionId, FeatureRequest reques } /** * Get the list of values from the WFS, the FeatureRequest have predefined enum to control what can pass in for the - * properties name. You may need to update it if you want to expand the list. + * property name. You may need to update it if you want to expand the list. * @param collectionId - The uuid of the metadata * @param request - The request property you want to query * @return - The return value, which is sorted by desc @@ -216,7 +216,7 @@ public ResponseEntity getWfsFieldValue(String collectionId, FeatureRequest re * @return - The WMS fields, or UNAUTHORIZED if it is not in white list */ public ResponseEntity getWmsFields(String collectionId, FeatureRequest request) { - // Temp block and show only white list uuid, the other uuid need QA check before release. + // Temp block and show only whitelist uuid, the other uuid need QA check before release. if (request.getEnableGeoServerWhiteList() && wmsDefaultParam.getAllowId() != null && !wmsDefaultParam.getAllowId().contains(collectionId)) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } else { diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/features/RestServicesTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/features/RestServicesTest.java index 2196249e..c293b9a6 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/features/RestServicesTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/features/RestServicesTest.java @@ -6,8 +6,6 @@ import au.org.aodn.ogcapi.server.core.service.das.DasService; import au.org.aodn.ogcapi.server.core.service.geoserver.wfs.WfsServer; import au.org.aodn.ogcapi.server.core.service.geoserver.wms.WmsServer; -import au.org.aodn.ogcapi.features.model.FeatureCollectionGeoJSON; -import au.org.aodn.ogcapi.server.core.model.enumeration.FeatureId; import au.org.aodn.ogcapi.server.core.service.Search; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -360,21 +358,4 @@ public void testGetWfsTimeFieldWorks() { assertInstanceOf(Map.class, response.getBody()); } - - @Test - public void testGetFeatureSummaryReturnsEmptyCollectionForAmsaWithoutSearching() throws Exception { - ResponseEntity response = restServices.getFeature( - "2a5739e7-0cb8-444a-b83b-b2bc841b0ce8", - FeatureId.summary, - null, - null - ); - - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); - assertEquals(FeatureCollectionGeoJSON.TypeEnum.FEATURECOLLECTION, response.getBody().getType()); - assertTrue(response.getBody().getFeatures().isEmpty()); - - verify(search, never()).searchFeatureSummary(anyString(), any(), any()); - } } diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java index 3c3c4df9..fe75737b 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/service/ElasticSearchTest.java @@ -1,35 +1,18 @@ package au.org.aodn.ogcapi.server.service; -import au.org.aodn.ogcapi.features.model.FeatureGeoJSON; -import au.org.aodn.ogcapi.server.core.model.EsFeatureCollectionModel; -import au.org.aodn.ogcapi.server.core.model.EsFeatureModel; -import au.org.aodn.ogcapi.server.core.model.EsPolygonModel; import au.org.aodn.ogcapi.server.core.model.enumeration.CQLCrsType; import au.org.aodn.ogcapi.server.core.service.ElasticSearch; -import au.org.aodn.ogcapi.server.core.service.ElasticSearchBase; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.FieldValue; import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch.core.SearchRequest; -import co.elastic.clients.elasticsearch.core.SearchResponse; -import co.elastic.clients.elasticsearch.core.search.Hit; -import co.elastic.clients.elasticsearch.core.search.HitsMetadata; -import co.elastic.clients.elasticsearch.core.search.TotalHits; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.openapitools.jackson.nullable.JsonNullable; -import org.openapitools.jackson.nullable.JsonNullableModule; - -import java.io.IOException; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.function.Supplier; import static org.junit.jupiter.api.Assertions.*; @@ -37,110 +20,10 @@ public class ElasticSearchTest { private ElasticsearchClient mockClient; - private ElasticSearch elasticSearch; @BeforeEach public void setUp() { mockClient = mock(ElasticsearchClient.class); - elasticSearch = new ElasticSearch( - mockClient, - null, // CacheNoLandGeometry - new ObjectMapper(), - "test-index", - 100, - 10 - ); - } - - @Test - public void searchFeatureSummaryTest() throws IOException { - - // Arrange - String collectionId = "test-collection"; - List properties = List.of("*"); - String filter = null; - - SearchResponse mockResponse = mock(SearchResponse.class); - Hit hit = mock(Hit.class); - var esFeatureCollection = new EsFeatureCollectionModel(); - Map featureCollectionProperties = new HashMap<>(); - featureCollectionProperties.put("date", "2004-01"); - featureCollectionProperties.put("collection", "2d496463-600c-465a-84a1-8a4ab76bd505"); - featureCollectionProperties.put("key", "satellite_ghrsst_l4_gamssa_1day_multi_sensor_world.zarr"); - esFeatureCollection.setProperties(featureCollectionProperties); - List>> coords = new ArrayList<>(); - var esFeature = new EsFeatureModel(); - - // mock the feature properties - Map featureProperties = new HashMap<>(); - featureProperties.put("date", "1939-09"); - featureProperties.put("count", 5); - esFeature.setProperties(featureProperties); - - // mock a single point [147.338884, -43.190779] - List> ring = new ArrayList<>(); - List point = List.of( - new BigDecimal("147.338884"), - new BigDecimal("-43.190779") - ); - ring.add(point); - coords.add(ring); - - var polygon = new EsPolygonModel(); - polygon.setCoordinates(coords); - - esFeature.setGeometry(polygon); - - esFeatureCollection.setFeatures(List.of(esFeature)); - - when(hit.source()).thenReturn(esFeatureCollection); - - when(mockClient.search(any(SearchRequest.class), eq(EsFeatureCollectionModel.class))) - .thenReturn(mockResponse); - - HitsMetadata hitsMetadata = mock(HitsMetadata.class); - when(hitsMetadata.hits()).thenReturn(List.of(hit)); - TotalHits totalHits = mock(TotalHits.class); - when(totalHits.value()).thenReturn(1L); - when(hitsMetadata.total()).thenReturn(totalHits); - - when(mockResponse.hits()).thenReturn(hitsMetadata); - - when(mockClient.search(any(SearchRequest.class), eq(EsFeatureCollectionModel.class))).thenReturn(mockResponse); - - ElasticSearchBase.SearchResult result = elasticSearch.searchFeatureSummary(collectionId, properties, filter); - - // Assert - assertNotNull(result); - assertEquals(1, result.getCollections().size()); - assertEquals(1L, result.getTotal()); - // validate geometry keeps same after adding key property - assertEquals(esFeature.toFeatureGeoJSON().getGeometry(), - result.getCollections().get(0).getGeometry()); - - // validate key is in properties - FeatureGeoJSON returnedFeature = result.getCollections().get(0); - JsonNullable props = returnedFeature.getProperties(); - - assertInstanceOf(Map.class, props.get()); - Map featureProps = (Map)props.get(); - - assertTrue(featureProps.containsKey("key")); - assertEquals("satellite_ghrsst_l4_gamssa_1day_multi_sensor_world.zarr", - featureProps.get("key")); - - // validate the feature properties are correctly serialised - assertEquals("1939-09", featureProps.get("date")); - assertEquals(5, featureProps.get("count")); - - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JsonNullableModule()); - - String json = mapper.writeValueAsString(returnedFeature); - - assertTrue(json.contains("\"date\":\"1939-09\"")); - assertTrue(json.contains("\"count\":5")); - assertFalse(json.contains("\"present\":true")); } @Test @@ -214,6 +97,7 @@ public void explainByParametersUsesScriptScoreRequestForKeywords() throws Except assertEquals("captured", result.path("status").asText()); assertEquals(100, capturingSearch.explainRequest.size()); + assertNotNull(capturingSearch.explainRequest.query()); assertTrue(capturingSearch.explainRequest.query().isScriptScore()); assertEquals(10, capturingSearch.explainRequest.query().scriptScore() .query().bool().should().size()); @@ -236,9 +120,11 @@ public void explainByParametersUsesCollectionQueryForEmptySearch() throws Except SearchRequest request = capturingSearch.explainRequest; assertEquals(100, request.size()); + assertNotNull(request.query()); assertTrue(request.query().isBool()); assertEquals("type", request.query().bool().must().get(0).match().field()); assertEquals("Collection", request.query().bool().must().get(0).match().query().stringValue()); + assertNotNull(request.source()); assertTrue(request.source().isFetch()); assertTrue(request.source().fetch(), "Empty parameter searches must preserve searchAllCollections source behavior"); @@ -270,6 +156,7 @@ public void normalAndExplainRequestsMatchForKeywordAndCqlSettings() throws Excep assertEquals(normalRequest.toString(), explainRequest.toString()); assertEquals(3, explainRequest.size()); assertEquals(1.3, explainRequest.minScore()); + assertNotNull(explainRequest.query()); assertTrue(explainRequest.query().isScriptScore()); assertFalse(explainRequest.query().scriptScore().query().bool().filter().isEmpty()); }