diff --git a/service/src/main/java/gov/nasa/pds/api/registry/controllers/ProductsController.java b/service/src/main/java/gov/nasa/pds/api/registry/controllers/ProductsController.java index a48c99dd..ddceb655 100644 --- a/service/src/main/java/gov/nasa/pds/api/registry/controllers/ProductsController.java +++ b/service/src/main/java/gov/nasa/pds/api/registry/controllers/ProductsController.java @@ -30,6 +30,7 @@ import gov.nasa.pds.api.registry.ConnectionContext; import gov.nasa.pds.api.registry.model.ErrorMessageFactory; import gov.nasa.pds.api.registry.model.exceptions.AcceptFormatNotSupportedException; +import gov.nasa.pds.api.registry.model.exceptions.MissSortWithSearchAfterException; import gov.nasa.pds.api.registry.model.exceptions.NotFoundException; import gov.nasa.pds.api.registry.model.exceptions.UnhandledException; import gov.nasa.pds.api.registry.model.api_responses.PdsProductBusinessObject; @@ -50,6 +51,7 @@ public class ProductsController implements ProductsApi { private final RegistrySearchRequestBuilder registrySearchRequestBuilder; private final ErrorMessageFactory errorMessageFactory; private final ObjectMapper objectMapper; + private OpenSearchClient openSearchClient; private SearchRequest presetSearchRequest; // TODO move that at a better place, it is not specific to this controller @@ -60,6 +62,8 @@ static Map> getFormatters() { return formatters; } + static Integer DEFAULT_LIMIT = 100; + static { // TODO move that at a better place, it is not specific to this controller formatters.put("*", PdsProductBusinessObject.class); @@ -90,6 +94,7 @@ public ProductsController(ConnectionContext connectionContext, this.registrySearchRequestBuilder = new RegistrySearchRequestBuilder(connectionContext); + this.openSearchClient = this.connectionContext.getOpenSearchClient(); } @@ -135,7 +140,7 @@ private ResponseEntity formatMultipleProducts(RawMultipleProductResponse if (!ProductsController.formatters.containsKey(acceptHeaderValue)) { throw new AcceptFormatNotSupportedException( - "format " + acceptHeaderValue + "is not supported."); + "format " + acceptHeaderValue + " is not supported."); } Class formatterClass = @@ -213,8 +218,8 @@ public ResponseEntity selectByLidvidLatest(String identifier, List selectByLidvidAll(String identifier, List fields, - Integer limit, List sort, List searchAfter) - throws UnhandledException, NotFoundException, AcceptFormatNotSupportedException { + Integer limit, List sort, List searchAfter) throws UnhandledException, + NotFoundException, AcceptFormatNotSupportedException, MissSortWithSearchAfterException { RawMultipleProductResponse response; @@ -225,6 +230,7 @@ public ResponseEntity selectByLidvidAll(String identifier, List response = new RawMultipleProductResponse(this.getLidVid(pdsIdentifier, fields)); } else { + limit = (limit == null) ? DEFAULT_LIMIT : limit; response = this.getAllLidVid(pdsIdentifier, fields, limit, sort, searchAfter); } @@ -250,13 +256,11 @@ private HashMap getLidVid(PdsProductIdentifier identifier, List< SearchRequest searchRequest = registrySearchRequestBuilder.addLidvidMatch(identifier).build(); - - OpenSearchClient client = this.connectionContext.getOpenSearchClient(); - // useless to detail here that the HashMap is parameterized // because of compilation features, see // https://stackoverflow.com/questions/2390662/java-how-do-i-get-a-class-literal-from-a-generic-type - SearchResponse searchResponse = client.search(searchRequest, HashMap.class); + SearchResponse searchResponse = + this.openSearchClient.search(searchRequest, HashMap.class); if (searchResponse.hits().total().value() == 0) { throw new NotFoundException("No product found with identifier " + identifier.toString()); } @@ -267,6 +271,7 @@ private HashMap getLidVid(PdsProductIdentifier identifier, List< } + @SuppressWarnings("unchecked") private HashMap getLatestLidVid(PdsProductIdentifier identifier, List fields) throws OpenSearchException, IOException, NotFoundException { @@ -276,13 +281,11 @@ private HashMap getLatestLidVid(PdsProductIdentifier identifier, SearchRequest searchRequest = registrySearchRequestBuilder.addLidMatch(identifier).onlyLatest().build(); - - OpenSearchClient client = this.connectionContext.getOpenSearchClient(); - // useless to detail here that the HashMap is parameterized // because of compilation features, see // https://stackoverflow.com/questions/2390662/java-how-do-i-get-a-class-literal-from-a-generic-type - SearchResponse searchResponse = client.search(searchRequest, HashMap.class); + SearchResponse searchResponse = + this.openSearchClient.search(searchRequest, HashMap.class); if (searchResponse.hits().total().value() == 0) { throw new NotFoundException("No product found with identifier " + identifier.toString()); @@ -296,20 +299,35 @@ private HashMap getLatestLidVid(PdsProductIdentifier identifier, private RawMultipleProductResponse getAllLidVid(PdsProductIdentifier identifier, List fields, Integer limit, List sort, List searchAfter) - throws OpenSearchException, IOException, NotFoundException { + throws OpenSearchException, IOException, NotFoundException, MissSortWithSearchAfterException { RegistrySearchRequestBuilder registrySearchRequestBuilder = new RegistrySearchRequestBuilder(this.registrySearchRequestBuilder); - SearchRequest searchRequest = registrySearchRequestBuilder.addLidMatch(identifier).build(); + registrySearchRequestBuilder = registrySearchRequestBuilder.addLidMatch(identifier); + + if ((sort != null) && (!sort.isEmpty())) { + registrySearchRequestBuilder.sort(sort); + } + + registrySearchRequestBuilder.size(limit); + + if ((searchAfter != null) && (!searchAfter.isEmpty())) { + if ((sort == null) || (sort.isEmpty())) { + throw new MissSortWithSearchAfterException(); + } + registrySearchRequestBuilder.searchAfter(searchAfter); + } + - OpenSearchClient client = this.connectionContext.getOpenSearchClient(); + SearchRequest searchRequest = registrySearchRequestBuilder.build(); // useless to detail here that the HashMap is parameterized // because of compilation features, see // https://stackoverflow.com/questions/2390662/java-how-do-i-get-a-class-literal-from-a-generic-type - SearchResponse searchResponse = client.search(searchRequest, HashMap.class); + SearchResponse searchResponse = + this.openSearchClient.search(searchRequest, HashMap.class); if (searchResponse.hits().total().value() == 0) { throw new NotFoundException("No product found with identifier " + identifier.toString());