diff --git a/.gitignore b/.gitignore index 305ee94..bed2a1c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,11 +8,7 @@ target/ !**/src/test/**/target/ ### IntelliJ IDEA ### -.idea/misc.xml -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea *.iws *.iml *.ipr diff --git a/src/main/java/com/datastax/oss/cass_stac/controller/SearchController.java b/src/main/java/com/datastax/oss/cass_stac/controller/SearchController.java index b6c7b0a..8850eab 100644 --- a/src/main/java/com/datastax/oss/cass_stac/controller/SearchController.java +++ b/src/main/java/com/datastax/oss/cass_stac/controller/SearchController.java @@ -114,7 +114,7 @@ The bounding box is provided as four or six numbers, depending on whether the co try { ItemCollection response = itemService.search( bbox, - GeoJsonParser.parseGeometry(intersects), + intersects != null ? GeoJsonParser.parseGeometry(intersects) : null, datetime, limit, ids, diff --git a/src/main/java/com/datastax/oss/cass_stac/service/ItemService.java b/src/main/java/com/datastax/oss/cass_stac/service/ItemService.java index 6c7225b..7d8fe42 100644 --- a/src/main/java/com/datastax/oss/cass_stac/service/ItemService.java +++ b/src/main/java/com/datastax/oss/cass_stac/service/ItemService.java @@ -271,7 +271,7 @@ public Map parseDatetime(String datetime) { if (datetime.contains("/")) { String[] parts = datetime.split("/"); - Instant rangeCenter = Instant.parse("2023-01-01T00:00:00.00Z"); + Instant rangeCenter = Instant.parse("2023-01-01T00:00:00.00Z"); result.put("minDate", parts[0].equals("..") ? rangeCenter.minusSeconds(15770000L).toString() : parts[0]); result.put("minOffsetDate", parts[0].equals("..") ? rangeCenter.minusSeconds(15770000L).toString() : parts[0]); @@ -289,10 +289,12 @@ public Map parseDatetime(String datetime) { public List getPartitions(Geometry intersects, List ids, Map dateTimes) { final GeoTimePartition partitioner = new GeoTimePartition(); List partitions = new ArrayList<>(); - if (intersects != null && ids == null) + if (intersects == null && (ids == null || ids.isEmpty())) + throw new RuntimeException("Filter on either ids or intersects should be passed to search"); + if (ids == null) partitions = switch (intersects.getGeometryType()) { case "Point": - yield partitioner.getGeoTimePartitionsForPoint(intersects.getCentroid(), + yield partitioner.getGeoTimePartitionsForPoint(intersects.getCentroid(), OffsetDateTime.parse(dateTimes.get("minOffsetDate")), OffsetDateTime.parse(dateTimes.get("maxOffsetDate"))); case "Polygon": @@ -302,7 +304,7 @@ public List getPartitions(Geometry intersects, List ids, Map(ids.stream().map(id -> { final ItemId itemId = itemIdDao.findById(id).orElse(null); if (itemId != null) { @@ -318,8 +320,7 @@ private List fetchItemsForPartition(String partitionId, List bbox, Instant minDate, Instant maxDate, - List collectionsArray, - Integer pageSize) { + List collectionsArray) { List itemPage; Query dbQuery = Query.query(Criteria.where("partition_id").is(partitionId)); @@ -338,12 +339,11 @@ private List fetchItemsForPartition(String partitionId, } @Async("asyncExecutor") - private CompletableFuture> fetchItemsForPartitionAsync(String partitionId, - List bbox, - Instant minDate, - Instant maxDate, - List collectionsArray, - Integer pageSize) { + protected CompletableFuture> fetchItemsForPartitionAsync(String partitionId, + List bbox, + Instant minDate, + Instant maxDate, + List collectionsArray) { List itemPage; Query dbQuery = Query.query(Criteria.where("partition_id").is(partitionId)); @@ -391,64 +391,58 @@ public ItemCollection search(List bbox, limit = limit == null ? 10 : limit; - if (datetime == null) - throw new RuntimeException("datetime is required to filter out data"); - Map dateTimes = parseDatetime(datetime); List partitionIds = getPartitions(intersects, ids, dateTimes); - assert partitionIds != null; List>> futures = new ArrayList<>(); for (String partitionId : partitionIds) { - logger.info("Fetching items for partitionId: " + partitionId); + logger.info("Fetching items for partitionId: {}", partitionId); CompletableFuture> future = fetchItemsForPartitionAsync(partitionId, bbox, Instant.parse(dateTimes.get("minDate")), Instant.parse(dateTimes.get("maxDate")), - collectionsArray, limit); + collectionsArray); futures.add(future); } CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); - CompletableFuture> allItemsFuture = allFutures.thenApply(v -> - futures.stream() - .flatMap(future -> future.join().stream()) - .collect(Collectors.toList()) + CompletableFuture> allItemsFuture = allFutures.thenApply(v -> + futures.stream() + .flatMap(future -> future.join().stream()) + .filter(_item -> { + boolean valid = true; + if (ids != null) { + valid = ids.contains(_item.getId().getId()); + } + + if (bbox != null) { + ItemDto itemDto; + try { + itemDto = convertItemToDto(_item); + } catch (IOException e) { + throw new RuntimeException(e); + } + valid = BboxIntersects(itemDto.getBbox(), bbox); + } + + if (query != null) { + QueryEvaluator evaluator = new QueryEvaluator(); + Map additionalAttributes; + JsonNode attributes; + try { + attributes = objectMapper.readValue(_item.getProperties(), JsonNode.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + additionalAttributes = objectMapper.convertValue(attributes, new TypeReference<>() { + }); + valid = evaluator.evaluate(query, additionalAttributes); + } + return valid; + }) + .collect(Collectors.toList()) ); - - List allItems = allItemsFuture.get(); - - allItems = allItems.stream().filter(_item -> { - boolean valid = true; - if (ids != null) { - valid = ids.contains(_item.getId().getId()); - } - - if (bbox != null) { - ItemDto itemDto; - try { - itemDto = convertItemToDto(_item); - } catch (IOException e) { - throw new RuntimeException(e); - } - valid = BboxIntersects(itemDto.getBbox(), bbox); - } - - if (query != null) { - QueryEvaluator evaluator = new QueryEvaluator(); - Map additionalAttributes; - JsonNode attributes; - try { - attributes = objectMapper.readValue(_item.getProperties(), JsonNode.class); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - additionalAttributes = objectMapper.convertValue(attributes, new TypeReference<>() { - }); - valid = evaluator.evaluate(query, additionalAttributes); - } - return valid; - }).toList(); + List allItems = allItemsFuture.get(); if (sort != null && !sort.isEmpty()) { allItems = SortUtils.sortItems(allItems, sort);