diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLURLBuilder.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLURLBuilder.java index 23381d82e58..14228000aef 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLURLBuilder.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLURLBuilder.java @@ -140,21 +140,6 @@ private boolean canCascade(LayerInfo layerInfo) { // Not supporting cross-requests yet: // GetTiles against remote WMS // GetMap against remote WMTS - String service = params.get(SERVICE); - String request = params.get(REQUEST); - if (storeInfo instanceof WMTSStoreInfo) { - if (GETMAP.equalsIgnoreCase(request) - || (GETFEATUREINFO.equalsIgnoreCase(request) - && WMS.equalsIgnoreCase(service))) { - return false; - } - } else if (storeInfo instanceof WMSStoreInfo) { - if (GETTILE.equalsIgnoreCase(request) - || (GETFEATUREINFO.equalsIgnoreCase(request) - && WMTS.equalsIgnoreCase(service))) { - return false; - } - } return TiledCRSConstants.getSupportedOutputCRS(proj) != null; } return false; @@ -184,6 +169,7 @@ private String generateURL(String path, HashMap params, LayerInf boolean isSupportedOutputCRS = outputCRS != null; if (resourceInfo != null) { String capabilitiesURL = null; + URL getResourceURL = null; String tileMatrixSet = null; StoreInfo storeInfo = resourceInfo.getStore(); String requestedCRS = isSupportedOutputCRS ? outputCRS : proj; @@ -195,6 +181,7 @@ private String generateURL(String path, HashMap params, LayerInf try { WMSCapabilities capabilities = wmsStoreInfo.getWebMapServer(null).getCapabilities(); + getResourceURL = capabilities.getRequest().getGetMap().getGet(); version = capabilities.getVersion(); List layerList = capabilities.getLayerList(); // Check on GetFeatureInfo @@ -241,6 +228,7 @@ private String generateURL(String path, HashMap params, LayerInf try { WMTSCapabilities capabilities = wmtsStoreInfo.getWebMapTileServer(null).getCapabilities(); + getResourceURL = capabilities.getRequest().getGetTile().getGet(); version = capabilities.getVersion(); List layerList = capabilities.getLayerList(); // Check on GetFeatureInfo @@ -284,9 +272,24 @@ private String generateURL(String path, HashMap params, LayerInf if (cascadeToRemote) { // if we reach this point, we can finally cascade. // Let's update all the params for the cascading - String[] baseUrlAndPath = getBaseUrlAndPath(capabilitiesURL); - baseUrl = baseUrlAndPath[0]; - path = baseUrlAndPath[1]; + // getResourceURL may be null if the capabilities doc is misconfigured; + if (getResourceURL != null) { + baseUrl = + getResourceURL.getProtocol() + + "://" + + getResourceURL.getHost() + + (getResourceURL.getPort() == -1 + ? "" + : ":" + getResourceURL.getPort()) + + "/"; + + path = getResourceURL.getPath(); + } else { + // if misconfigured capabilites, use cap document URL as base + String[] baseUrlAndPath = getBaseUrlAndPath(capabilitiesURL); + baseUrl = baseUrlAndPath[0]; + path = baseUrlAndPath[1]; + } urlType = URLMangler.URLType.EXTERNAL; updateRequestParams( params, layerName, version, requestedCRS, tileMatrixSet, infoFormats); diff --git a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLBaseProxyTest.java b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLBaseProxyTest.java index 4d84bb11989..ec497837d7f 100644 --- a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLBaseProxyTest.java +++ b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLBaseProxyTest.java @@ -13,9 +13,13 @@ import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import java.io.ByteArrayInputStream; +import java.net.URL; import java.util.Map; +import java.util.regex.Pattern; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.XpathEngine; +import org.geotools.ows.wms.WMSCapabilities; +import org.geotools.ows.wms.WebMapServer; import org.junit.AfterClass; import org.junit.Before; import org.springframework.http.MediaType; @@ -105,11 +109,29 @@ protected void checkCascading( } } - protected void assertCascading(boolean shouldCascade, String url) { + protected void assertCascading(boolean shouldCascade, String url) throws Exception { + if (shouldCascade) { - assertTrue( - url.startsWith( - "http://localhost:" + mockService.port() + MOCK_SERVER + CONTEXT)); + URL getResourceURL = null; + Pattern serviceTypeRE = Pattern.compile(".*SERVICE=WMS.*", Pattern.CASE_INSENSITIVE); + boolean cascadingWMS = serviceTypeRE.matcher(getCapabilitiesURL()).find(); + assertTrue(cascadingWMS); + WebMapServer wms = new WebMapServer(new URL(getCapabilitiesURL())); + WMSCapabilities capabilities = wms.getCapabilities(); + getResourceURL = capabilities.getRequest().getGetMap().getGet(); + URL baseResourceURL = + getResourceURL != null ? getResourceURL : new URL(getCapabilitiesURL()); + URL base = + new URL( + baseResourceURL.getProtocol() + + "://" + + baseResourceURL.getHost() + + (baseResourceURL.getPort() == -1 + ? "" + : ":" + baseResourceURL.getPort()) + + "/"); + String path = baseResourceURL.getPath(); + assertTrue(url.startsWith((new URL(base, path)).toString())); assertTrue(url.contains("layers=topp:states")); } else { assertTrue(url.startsWith("http://localhost:8080/geoserver" + CONTEXT)); diff --git a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMTSProxyTest.java b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMTSProxyTest.java index 63db249b3ed..11ebced9ba3 100644 --- a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMTSProxyTest.java +++ b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMTSProxyTest.java @@ -4,11 +4,14 @@ */ package org.geoserver.mapml; +import static org.geoserver.mapml.MapMLBaseProxyTest.getCapabilitiesURL; import static org.geowebcache.grid.GridSubsetFactory.createGridSubSet; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.net.URL; +import java.util.regex.Pattern; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.ResourceInfo; @@ -19,6 +22,8 @@ import org.geoserver.gwc.config.GWCConfig; import org.geoserver.gwc.layer.GeoServerTileLayer; import org.geoserver.mapml.gwc.gridset.MapMLGridsets; +import org.geotools.ows.wmts.WebMapTileServer; +import org.geotools.ows.wmts.model.WMTSCapabilities; import org.geowebcache.grid.GridSubset; import org.geowebcache.mime.TextMime; import org.junit.BeforeClass; @@ -118,15 +123,31 @@ public void testRemoteVsNotRemote() throws Exception { } @Override - protected void assertCascading(boolean shouldCascade, String url) { - assertTrue(url.contains("service=WMTS")); + protected void assertCascading(boolean shouldCascade, String url) throws Exception { + URL getResourceURL = null; + Pattern serviceTypeRE = Pattern.compile(".*SERVICE=WMTS.*", Pattern.CASE_INSENSITIVE); + boolean isWMTSService = serviceTypeRE.matcher(getCapabilitiesURL()).find(); + assertTrue(isWMTSService); if (shouldCascade) { + WebMapTileServer wmts = new WebMapTileServer(new URL(getCapabilitiesURL())); + WMTSCapabilities capabilities = wmts.getCapabilities(); + getResourceURL = capabilities.getRequest().getGetTile().getGet(); + URL baseResourceURL = + getResourceURL != null ? getResourceURL : new URL(getCapabilitiesURL()); + URL base = + new URL( + baseResourceURL.getProtocol() + + "://" + + baseResourceURL.getHost() + + (baseResourceURL.getPort() == -1 + ? "" + : ":" + baseResourceURL.getPort()) + + "/"); + String path = baseResourceURL.getPath(); + assertTrue(url.startsWith((new URL(base, path)).toString())); // The remote capabilities defines a custom GridSet that matches // the OSMTILE with a different name: MATCHING_OSMTILE // Identifiers are also not simple numbers but contain a common prefix. - assertTrue( - url.startsWith( - "http://localhost:" + mockService.port() + MOCK_SERVER + CONTEXT)); assertTrue(url.contains("layer=topp:states")); assertTrue(url.contains("tilematrixset=MATCHING_OSMTILE")); // Common prefix has been pre-pended to the tilematrix z input