From da0efeb3becda09b61314ce80a8c555effd91b67 Mon Sep 17 00:00:00 2001 From: rng Date: Fri, 26 Jun 2026 14:28:59 +1000 Subject: [PATCH 1/2] Add api call to metadata info --- .../au/org/aodn/ogcapi/server/Server.java | 3 ++ .../server/core/configuration/DASConfig.java | 20 ++++----- .../server/core/model/DatasetMetadata.java | 41 +++++++++++++++++++ .../core/model/enumeration/FeatureId.java | 1 + .../server/core/service/DasService.java | 29 +++++++++---- .../aodn/ogcapi/server/features/RestApi.java | 3 ++ .../ogcapi/server/features/RestServices.java | 11 +++++ .../server/core/service/DasServiceTest.java | 4 +- 8 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/Server.java b/server/src/main/java/au/org/aodn/ogcapi/server/Server.java index 4240838d..21f2e4c1 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/Server.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/Server.java @@ -1,12 +1,15 @@ package au.org.aodn.ogcapi.server; +import au.org.aodn.ogcapi.server.core.configuration.DASConfig; import jakarta.annotation.PostConstruct; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import java.util.TimeZone; @SpringBootApplication +@EnableConfigurationProperties(DASConfig.class) public class Server { @PostConstruct diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java index 18eb7d51..b54c2835 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java @@ -1,14 +1,10 @@ package au.org.aodn.ogcapi.server.core.configuration; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; - - -@Configuration -public class DASConfig { - - @Value("${data-access-service.host}") - public String host; - @Value("${data-access-service.secret}") - public String secret; -} +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "data-access-service") +public record DASConfig( + String host, + String secret, + String internal +) {} \ No newline at end of file diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java new file mode 100644 index 00000000..68f73def --- /dev/null +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java @@ -0,0 +1,41 @@ +package au.org.aodn.ogcapi.server.core.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import java.util.Map; + +@Data +@NoArgsConstructor +public class DatasetMetadata { + + // Allows Jackson to deserialize the root JSON object directly into this wrapper class + @JsonValue + private Map datasets; + + @JsonCreator + public DatasetMetadata(Map datasets) { + this.datasets = datasets; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class DatasetInfo { + private String uuid; + private String dname; + private CoordinateBounds lat; + private CoordinateBounds lng; + private Double depth; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class CoordinateBounds { + private Double min; + private Double max; + } +} \ No newline at end of file diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/FeatureId.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/FeatureId.java index 73192a0b..072d28fe 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/FeatureId.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/FeatureId.java @@ -2,6 +2,7 @@ public enum FeatureId { summary("summary"), + dataset_metadata("dataset_metadata"), wfs_fields("wfs_fields"), // Query field based on pure wfs and given layer wfs_field_value("wfs_field_value"), wms_fields("wms_fields"), // Query field based on value from wms describe layer query diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/DasService.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/DasService.java index c9e777bd..bcc356a8 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/DasService.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/DasService.java @@ -1,11 +1,9 @@ package au.org.aodn.ogcapi.server.core.service; import au.org.aodn.ogcapi.server.core.configuration.DASConfig; +import au.org.aodn.ogcapi.server.core.model.DatasetMetadata; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; +import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -30,7 +28,8 @@ public class DasService { public void init() { HttpHeaders headers = new HttpHeaders(); headers.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); - headers.set("X-API-KEY", dasConfig.secret); + headers.set("X-API-KEY", dasConfig.secret()); + headers.set("x-internal-das-header-secret", dasConfig.internal()); httpEntity = new HttpEntity<>(headers); } @@ -41,7 +40,7 @@ public void init() { * {@code pathVariables}. */ private byte[] getFeatureCollection(String path, String start, String end, Map pathVariables) { - UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(dasConfig.host + path); + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(dasConfig.host() + path); Map params = new HashMap<>(pathVariables); if (start != null) { @@ -62,7 +61,7 @@ public byte[] getWaveBuoysBetweenDates(String start, String end) { } public byte[] getWaveBuoysLatestAvailableDate() { - String waveBuoysUrlTemplate = UriComponentsBuilder.fromUriString(dasConfig.host + "/api/v1/das/data/feature-collection/wave-buoy/latest") + String waveBuoysUrlTemplate = UriComponentsBuilder.fromUriString(dasConfig.host() + "/api/v1/das/data/feature-collection/wave-buoy/latest") .encode() .toUriString(); @@ -78,7 +77,7 @@ public byte[] getMooringsBetweenDates(String start, String end) { } public byte[] getMooringsLatestAvailableDate() { - String mooringsUrlTemplate = UriComponentsBuilder.fromUriString(dasConfig.host + "/api/v1/das/data/feature-collection/mooring/latest") + String mooringsUrlTemplate = UriComponentsBuilder.fromUriString(dasConfig.host() + "/api/v1/das/data/feature-collection/mooring/latest") .encode() .toUriString(); @@ -88,4 +87,18 @@ public byte[] getMooringsLatestAvailableDate() { public byte[] getMooringDetailsBetweenDates(String startDateTime, String endDateTime, String mooring) { return getFeatureCollection("/api/v1/das/data/feature-collection/mooring/{mooring}", startDateTime, endDateTime, Map.of("mooring", mooring)); } + + public ResponseEntity getDatasetMetadata(String datasetId) { + ResponseEntity response = httpClient.exchange( + dasConfig.host() + "/api/v1/das/metadata/" + datasetId, + HttpMethod.GET, + httpEntity, + DatasetMetadata.class + ); + // We need to do this so that the response is closed + return ResponseEntity + .status(response.getStatusCode()) + .contentType(MediaType.APPLICATION_JSON) + .body(response.getBody()); + } } 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 975b5cc5..3f402c35 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 @@ -115,6 +115,9 @@ public ResponseEntity getFeature( return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } + case dataset_metadata -> { + return featuresService.getDatasetMetadata(collectionId); + } case wave_buoys_between_dates -> { return featuresService.getWaveBuoysBetweenDates( request.getStartDateTime(), request.getEndDateTime()); } 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 83e65dd1..99f8240f 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 @@ -1,6 +1,7 @@ package au.org.aodn.ogcapi.server.features; import au.org.aodn.ogcapi.features.model.Collection; +import au.org.aodn.ogcapi.server.core.model.DatasetMetadata; import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest; import au.org.aodn.ogcapi.server.core.model.ogc.wfs.FeatureTypeInfo; import au.org.aodn.ogcapi.server.core.model.ogc.wfs.WfsField; @@ -77,6 +78,16 @@ public ResponseEntity getCollection(String id) throws NoSuchElementE } } + public ResponseEntity getDatasetMetadata(String id) { + try { + return dasService.getDatasetMetadata(id); + } + catch (Exception e) { + log.error("Error fetching metadata of id: {}, {}", id, e.getMessage()); + return ResponseEntity.internalServerError().build(); + } + } + public ResponseEntity getWmsMapFeature(String collectionId, FeatureRequest request) { try { return ResponseEntity.ok() diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/core/service/DasServiceTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/service/DasServiceTest.java index f37254d9..4dcdaa2d 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/core/service/DasServiceTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/service/DasServiceTest.java @@ -36,9 +36,7 @@ public class DasServiceTest { public void setUp() { httpClient = mock(RestTemplate.class); - DASConfig config = new DASConfig(); - config.host = HOST; - config.secret = "test-secret"; + DASConfig config = new DASConfig(HOST, "test-secret", ""); dasService = new DasService(); dasService.dasConfig = config; From f17e48b9ec77a9e686be2f5ad0a11668cdae248a Mon Sep 17 00:00:00 2001 From: rng Date: Fri, 26 Jun 2026 14:32:54 +1000 Subject: [PATCH 2/2] Pre-commit --- .../au/org/aodn/ogcapi/server/core/configuration/DASConfig.java | 2 +- .../au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java index b54c2835..e834b038 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/DASConfig.java @@ -7,4 +7,4 @@ public record DASConfig( String host, String secret, String internal -) {} \ No newline at end of file +) {} diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java index 68f73def..c70a35f5 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/DatasetMetadata.java @@ -38,4 +38,4 @@ public static class CoordinateBounds { private Double min; private Double max; } -} \ No newline at end of file +}