Skip to content

Commit 258d445

Browse files
Rewrite url when missing workspace
1 parent 621a956 commit 258d445

3 files changed

Lines changed: 78 additions & 3 deletions

File tree

server/src/main/java/au/org/aodn/ogcapi/server/core/service/CacheWarm.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class CacheWarm {
2727
"https://www.cmar.csiro.au/geoserver/ereefs/wms",
2828
"https://www.cmar.csiro.au/geoserver/ea-be/wms",
2929
"https://www.cmar.csiro.au/geoserver/gsfm/wms",
30+
"https://www.cmar.csiro.au/geoserver/local/wms",
31+
"https://www.cmar.csiro.au/geoserver/mnf/wms",
3032
"https://www.cmar.csiro.au/geoserver/nerp/wms",
3133
"https://www.cmar.csiro.au/geoserver/AusSeabed/wms",
3234
"https://geoserver.apps.aims.gov.au/aims/wms",
@@ -78,7 +80,7 @@ protected void evictGetCapabilities(String key){
7880
);
7981
}
8082

81-
@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
83+
@Retryable(maxAttempts = 5, backoff = @Backoff(delay = 1000))
8284
protected void warmGetCapabilities(String url) {
8385
try {
8486
// Call and warm cache

server/src/main/java/au/org/aodn/ogcapi/server/core/service/wms/WmsServer.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,44 @@ protected List<String> createMapDescribeUrl(String url, String uuid, FeatureRequ
311311
}
312312
return null;
313313
}
314+
/**
315+
* Some URL provided will miss the workspace in url event the layername is xxx:yyy where xxx is workspace
316+
* it is a typo in the metadata but manual fix will be very time consuming, so we can safely assume rewrite
317+
* the URL will work as it is a geoserver standard.
318+
* @param url - URl that may or may not missing the work space
319+
* @param request - Request that contains layer name
320+
* @return - A rewrite URL or original URL depends on logic
321+
*/
322+
protected static String rewriteUrlWithWorkSpace(String url, FeatureRequest request) {
323+
if(request.getLayerName().contains(":")) {
324+
String workspace = request.getLayerName().split(":")[0];
325+
UriComponents components = UriComponentsBuilder.fromUriString(url).build();
314326

327+
String workspacePatternInURL = String.format("/%s/", workspace);
328+
if(components.getPath() != null && !components.getPath().contains(workspacePatternInURL)) {
329+
// Need rewrite, get a writable list
330+
List<String> segments = new ArrayList<>(components.getPathSegments());
331+
segments.add(segments.size() - 1, workspace);
332+
333+
return UriComponentsBuilder.newInstance()
334+
.scheme(components.getScheme())
335+
.host(components.getHost())
336+
.path("/" + String.join("/", segments))
337+
.queryParams(components.getQueryParams())
338+
.build()
339+
.toUriString();
340+
}
341+
}
342+
return url;
343+
}
344+
/**
345+
* Create the URL to WMS to get the map feature, in this case it will be the content of the popup when you click
346+
* the map.
347+
* @param url - URL to WMS
348+
* @param uuid - UUID of record
349+
* @param request - Feature requested
350+
* @return - List of URL point to the wms queuing map features
351+
*/
315352
protected List<String> createMapFeatureQueryUrl(String url, String uuid, FeatureRequest request) {
316353
try {
317354
UriComponents components = UriComponentsBuilder.fromUriString(url).build();
@@ -490,7 +527,6 @@ public DescribeLayerResponse describeLayer(String collectionId, FeatureRequest r
490527
}
491528
return null;
492529
}
493-
494530
/**
495531
* Get the wms image/png tile
496532
*
@@ -602,7 +638,13 @@ public List<LayerInfo> fetchCapabilitiesLayersByUrl(String wmsServerUrl) {
602638
* Get filtered layers from WMS GetCapabilities for a specific collection, we use this function because we do not
603639
* trust the WMS layer value because it can be wrong, we use the WFS link to infer the layer and therefore the layer
604640
* name return will be operational with WFS function.
641+
* <p />
605642
* First fetches all layers (cached by URL), then filters by WFS links (cached by UUID)
643+
* <p />
644+
* Sometimes the URL provided by WMS link is not optimal, for example
645+
* <a href="https://www.cmar.csiro.au/geoserver/wms?&CQL_FILTER=SURVEY_NAME%20%3D%20%27FR199410%27">...</a>
646+
* will result in timeout due to too big query, if layername inside request have format xxx:yyyy then
647+
* we can use xxx as the workspace name and rewrite the URL to https://www.cmar.csiro.au/geoserver/xxx/wms
606648
*
607649
* @param collectionId - The uuid
608650
* @param request - The request param
@@ -613,7 +655,9 @@ public List<LayerInfo> getCapabilitiesLayers(String collectionId, FeatureRequest
613655

614656
if (mapServerUrl.isPresent()) {
615657
// Fetch all layers from GetCapabilities (this call is cached by URL)
616-
List<LayerInfo> allLayers = self.fetchCapabilitiesLayersByUrl(mapServerUrl.get());
658+
// Special rewrite to speed up query
659+
String url = rewriteUrlWithWorkSpace(mapServerUrl.get(), request);
660+
List<LayerInfo> allLayers = self.fetchCapabilitiesLayersByUrl(url);
617661

618662
if (!allLayers.isEmpty()) {
619663
// Filter layers based on WFS link matching

server/src/test/java/au/org/aodn/ogcapi/server/core/service/wms/WmsServerTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,4 +599,33 @@ public void verifyCreateCQLRangeDateTimeWithCQL() {
599599

600600
assertEquals("CQL_FILTER=start_juld >= 2023-01-01 AND end_juld <= 2023-12-31 AND set_code=1234", result);
601601
}
602+
603+
@Test
604+
void testRewriteUrlWithWorkSpace() {
605+
FeatureRequest req = FeatureRequest.builder()
606+
.layerName("xxx:yyy")
607+
.build();
608+
609+
// Case 1: Layer with workspace, URL without workspace
610+
String url1 = "https://example.com/geoserver/wms?service=WMS";
611+
String result1 = WmsServer.rewriteUrlWithWorkSpace(url1, req);
612+
assertEquals("https://example.com/geoserver/xxx/wms?service=WMS", result1);
613+
614+
// Case 2: No workspace in layer name
615+
req.setLayerName("yyy");
616+
String result2 = WmsServer.rewriteUrlWithWorkSpace(url1, req);
617+
assertEquals(url1, result2);
618+
619+
// Case 3: Workspace already in URL
620+
req.setLayerName("xxx:yyy");
621+
String url3 = "https://example.com/geoserver/xxx/wms";
622+
String result3 = WmsServer.rewriteUrlWithWorkSpace(url3, req);
623+
assertEquals(url3, result3);
624+
625+
// Case 4: Different service (wfs)
626+
req.setLayerName("xxx:yyy");
627+
String url4 = "https://example.com/geoserver/wfs";
628+
String result4 = WmsServer.rewriteUrlWithWorkSpace(url4, req);
629+
assertEquals("https://example.com/geoserver/xxx/wfs", result4);
630+
}
602631
}

0 commit comments

Comments
 (0)