Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions server/src/main/java/au/org/aodn/ogcapi/server/common/RestExtApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -29,6 +34,9 @@ public class RestExtApi {
@Autowired
protected RestExtService restExtService;

@Value("${ogcapi.debug.elasticsearch-explain-enabled:false}")
protected boolean elasticsearchExplainEnabled;

/**
* This call is cql aware, so if you provided the filter string, then the return value will be filtered by
* the cql clause.
Expand All @@ -47,6 +55,100 @@ public class RestExtApi {
) throws java.lang.Exception {
return searchService.getAutocompleteSuggestions(input, cql, CQLCrsType.convertFromUrl("https://epsg.io/4326"));
}

@GetMapping(path="/explain")
public ResponseEntity<JsonNode> getCollectionsExplain(
@Parameter(in = ParameterIn.QUERY, description = "Keyword search terms")
@Valid @RequestParam(value = "q", required = false) List<String> q,
@Parameter(in = ParameterIn.QUERY, description = "Filter expression")
@RequestParam(value = "filter", required = false) String filter,
@Parameter(in = ParameterIn.QUERY, description = "Properties used by the production search request")
@Valid @RequestParam(value = "properties", required = false) List<String> properties,
@Size(min = 1)
@Parameter(in = ParameterIn.QUERY, description = "Sort by a valid CQL property")
@Valid @RequestParam(value = "sortby", required = false, defaultValue = "-score,-rank") String sortBy,
@Parameter(in = ParameterIn.QUERY, description = "Coordinate system")
@RequestParam(value = "crs", required = false, defaultValue = "https://epsg.io/4326") String crs,
@Parameter(in = ParameterIn.QUERY, description = "Filter language")
@RequestParam(value = "filter-lang", required = false, defaultValue = "cql-text") String filterLang
) throws Exception {
if (!elasticsearchExplainEnabled) {
return ResponseEntity.notFound().build();
}

boolean isCqlFilter = "cql-text".equals(filterLang);
CQLCrsType convertedCrs = CQLCrsType.convertFromUrl(crs);

if (!isCqlFilter || convertedCrs != CQLCrsType.EPSG4326) {
List<String> reasons = new ArrayList<>();

if (!isCqlFilter) {
reasons.add("Unknown filter language, support cql-text only");
}

if (convertedCrs != CQLCrsType.EPSG4326) {
reasons.add("Unknown crs, support EPSG4326 only");
}

throw new NotImplementedException(String.join(",", reasons));
}

return ResponseEntity.ok(searchService.explainByParameters(
q,
filter,
properties,
sortBy,
convertedCrs));
}

@GetMapping(path="/explain/{uuid}")
public ResponseEntity<JsonNode> getCollectionExplain(
@Parameter(in = ParameterIn.PATH, description = "Elasticsearch document id")
@PathVariable String uuid,
@Parameter(in = ParameterIn.QUERY, description = "Keyword search terms")
@Valid @RequestParam(value = "q", required = false) List<String> q,
@Parameter(in = ParameterIn.QUERY, description = "Filter expression")
@RequestParam(value = "filter", required = false) String filter,
@Parameter(in = ParameterIn.QUERY, description = "Properties used by the production search request")
@Valid @RequestParam(value = "properties", required = false) List<String> properties,
@Size(min = 1)
@Parameter(in = ParameterIn.QUERY, description = "Sort by a valid CQL property")
@Valid @RequestParam(value = "sortby", required = false, defaultValue = "-score,-rank") String sortBy,
@Parameter(in = ParameterIn.QUERY, description = "Coordinate system")
@RequestParam(value = "crs", required = false, defaultValue = "https://epsg.io/4326") String crs,
@Parameter(in = ParameterIn.QUERY, description = "Filter language")
@RequestParam(value = "filter-lang", required = false, defaultValue = "cql-text") String filterLang
) throws Exception {
if (!elasticsearchExplainEnabled) {
return ResponseEntity.notFound().build();
}

boolean isCqlFilter = "cql-text".equals(filterLang);
CQLCrsType convertedCrs = CQLCrsType.convertFromUrl(crs);

if (!isCqlFilter || convertedCrs != CQLCrsType.EPSG4326) {
List<String> reasons = new ArrayList<>();

if (!isCqlFilter) {
reasons.add("Unknown filter language, support cql-text only");
}

if (convertedCrs != CQLCrsType.EPSG4326) {
reasons.add("Unknown crs, support EPSG4326 only");
}

throw new NotImplementedException(String.join(",", reasons));
}

return ResponseEntity.ok(searchService.explainByUuid(
uuid,
q,
filter,
properties,
sortBy,
convertedCrs));
}

/**
* Value cached to avoid excessive load
* @return - List of Json Vocabs
Expand Down
Loading