diff --git a/pom.xml b/pom.xml
index e15fbc52..2eb0c234 100644
--- a/pom.xml
+++ b/pom.xml
@@ -173,7 +173,7 @@
org.apache.logging.log4j
log4j-layout-template-json
- 2.25.3
+ 2.24.3
diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsDefaultParam.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsDefaultParam.java
index 2c67af44..7f675d71 100644
--- a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsDefaultParam.java
+++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsDefaultParam.java
@@ -17,4 +17,5 @@ public class WfsDefaultParam {
private Map fields;
private Map download;
+ private Map capabilities;
}
diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServer.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServer.java
index e2c201d0..005b1918 100644
--- a/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServer.java
+++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServer.java
@@ -36,7 +36,6 @@
import static au.org.aodn.ogcapi.server.core.configuration.CacheConfig.DOWNLOADABLE_FIELDS;
import static au.org.aodn.ogcapi.server.core.configuration.CacheConfig.GET_CAPABILITIES_WFS_FEATURE_TYPES;
import static au.org.aodn.ogcapi.server.core.service.wfs.WfsDefaultParam.WFS_LINK_MARKER;
-import static au.org.aodn.ogcapi.server.core.service.wms.WmsDefaultParam.WMS_LINK_MARKER;
import static au.org.aodn.ogcapi.server.core.util.GeoserverUtils.*;
@Slf4j
@@ -94,6 +93,23 @@ protected List getWfsLinks(String collectionId) {
.toList();
}
+ protected String createCapabilitiesQueryUrl(String wfsServerUrl) {
+ // Parse the base URL to construct GetCapabilities request
+ UriComponents components = UriComponentsBuilder.fromUriString(wfsServerUrl).build();
+
+ // Build GetCapabilities URL
+ UriComponentsBuilder builder = UriComponentsBuilder
+ .newInstance()
+ .scheme("https") // hardcode to be https to avoid redirect
+ .port(components.getPort())
+ .host(components.getHost())
+ .path(components.getPath() != null ? components.getPath() : "/geoserver/ows");
+
+ Map params = wfsDefaultParam.getCapabilities();
+ params.forEach(builder::queryParam);
+
+ return builder.build().toUriString();
+ }
protected String createFeatureFieldQueryUrl(String url, FeatureRequest request) {
UriComponents components = UriComponentsBuilder.fromUriString(url).build();
@@ -336,20 +352,7 @@ public Optional getFeatureServerUrlByTitleOrQueryParam(String collection
@Cacheable(value = GET_CAPABILITIES_WFS_FEATURE_TYPES)
public List fetchCapabilitiesFeatureTypesByUrl(String wfsServerUrl) {
try {
- // Parse the base URL to construct GetCapabilities request
- UriComponents components = UriComponentsBuilder.fromUriString(wfsServerUrl).build();
-
- // Build GetCapabilities URL
- UriComponentsBuilder builder = UriComponentsBuilder
- .newInstance()
- .scheme("https") // hardcode to be https to avoid redirect
- .port(components.getPort())
- .host(components.getHost())
- .path(components.getPath() != null ? components.getPath() : "/geoserver/ows")
- .queryParam("service", "wfs")
- .queryParam("request", "GetCapabilities");
-
- String url = builder.build().toUriString();
+ String url = createCapabilitiesQueryUrl(wfsServerUrl);
log.debug("WFS GetCapabilities URL: {}", url);
// Make the HTTPS call
diff --git a/server/src/main/resources/application.yaml b/server/src/main/resources/application.yaml
index e8768374..386c0fca 100644
--- a/server/src/main/resources/application.yaml
+++ b/server/src/main/resources/application.yaml
@@ -31,6 +31,10 @@ wfs-default-param:
SERVICE: "WFS"
VERSION: "1.0.0" # TODO: Change to 2.0.0 after testing CQL query
REQUEST: "GetFeature"
+ capabilities:
+ SERVICE: "WFS"
+ VERSION: "1.0.0"
+ REQUEST: "GetCapabilities"
# Default parameter for wms call
wms-default-param:
diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/service/wfs/WfsServerTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServerTest.java
similarity index 88%
rename from server/src/test/java/au/org/aodn/ogcapi/server/service/wfs/WfsServerTest.java
rename to server/src/test/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServerTest.java
index 185b0cb2..1859fc76 100644
--- a/server/src/test/java/au/org/aodn/ogcapi/server/service/wfs/WfsServerTest.java
+++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/service/wfs/WfsServerTest.java
@@ -1,4 +1,4 @@
-package au.org.aodn.ogcapi.server.service.wfs;
+package au.org.aodn.ogcapi.server.core.service.wfs;
import au.org.aodn.ogcapi.server.core.exception.GeoserverFieldsNotFoundException;
import au.org.aodn.ogcapi.server.core.model.LinkModel;
@@ -8,14 +8,14 @@
import au.org.aodn.ogcapi.server.core.model.ogc.wfs.WFSFieldModel;
import au.org.aodn.ogcapi.server.core.service.ElasticSearchBase;
import au.org.aodn.ogcapi.server.core.service.Search;
-import au.org.aodn.ogcapi.server.core.service.wfs.WfsDefaultParam;
-import au.org.aodn.ogcapi.server.core.service.wfs.WfsServer;
import au.org.aodn.ogcapi.server.core.util.RestTemplateUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@@ -24,7 +24,6 @@
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import static au.org.aodn.ogcapi.server.core.service.wfs.WfsDefaultParam.WFS_LINK_MARKER;
import static org.junit.jupiter.api.Assertions.*;
@@ -32,6 +31,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+@SpringBootTest
public class WfsServerTest {
@Mock
@@ -43,7 +43,7 @@ public class WfsServerTest {
@Mock
HttpEntity> entity;
- @Mock
+ @Autowired
WfsDefaultParam wfsDefaultParam;
AutoCloseable closeableMock;
@@ -51,12 +51,6 @@ public class WfsServerTest {
@BeforeEach
public void setUp() {
closeableMock = MockitoAnnotations.openMocks(this);
- // Setup default param mock
- when(wfsDefaultParam.getFields()).thenReturn(Map.of(
- "service", "WFS",
- "version", "2.0.0",
- "request", "DescribeFeatureType"
- ));
}
@AfterEach
@@ -332,4 +326,41 @@ public void testGetDownloadableFieldsNoCollection() {
assertNull(result, "Should return null when no collection found");
}
+
+ @Test
+ void createFeatureFieldQueryUrl_buildsCorrectUrlWithTypename() {
+ // arrange
+ String baseUrl = "https://example.com/wfs?service=WFS&version=1.1.0&request=GetFeature";
+ FeatureRequest request = FeatureRequest
+ .builder()
+ .layerName("my:layer")
+ .build();
+
+ // act
+ WfsServer server = new WfsServer(mockSearch, restTemplate, new RestTemplateUtils(restTemplate), entity, wfsDefaultParam);
+ String result = server.createFeatureFieldQueryUrl(baseUrl, request);
+
+ // assert
+ assertNotNull(result);
+ assertTrue(result.contains("TYPENAME=my:layer"));
+ assertTrue(result.contains("SERVICE=WFS"));
+ assertTrue(result.contains("VERSION=2.0.0")); // from defaults
+ assertTrue(result.contains("REQUEST=DescribeFeatureType")); // original one is replaced
+ }
+
+ @Test
+ void createCapabilitiesQueryUrl_buildsCorrectUrl() {
+ // arrange
+ String baseUrl = "https://example.com/wfs?service=WFS&version=1.1.0&request=GetFeature";
+
+ // act
+ WfsServer server = new WfsServer(mockSearch, restTemplate, new RestTemplateUtils(restTemplate), entity, wfsDefaultParam);
+ String result = server.createCapabilitiesQueryUrl(baseUrl);
+
+ // assert
+ assertNotNull(result);
+ assertTrue(result.contains("SERVICE=WFS"));
+ assertTrue(result.contains("VERSION=1.0.0")); // from defaults
+ assertTrue(result.contains("REQUEST=GetCapabilities")); // original one is replaced
+ }
}