Skip to content

Commit

Permalink
[GEOS-8089] Integrated GWC does not work with layer and layer group s…
Browse files Browse the repository at this point in the history
…pecific services
  • Loading branch information
aaime committed Apr 13, 2017
1 parent c2f9c83 commit 4493988
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
import java.util.regex.Pattern;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.gwc.layer.CatalogConfiguration;
import org.geoserver.ows.AbstractDispatcherCallback;
import org.geoserver.ows.Dispatcher;
import org.geoserver.ows.DispatcherCallback;
import org.geoserver.ows.LocalPublished;
import org.geoserver.ows.LocalWorkspace;
import org.geoserver.ows.Request;
import org.geoserver.platform.ServiceException;
Expand All @@ -42,7 +45,8 @@ public class GwcServiceDispatcherCallback extends AbstractDispatcherCallback imp
// contains the current gwc operation
public static final ThreadLocal<String> GWC_OPERATION = new ThreadLocal<>();

private static final Pattern GWC_VIRTUAL_SERVICE_PATTERN = Pattern.compile("([^/]+)/gwc/service");
private static final Pattern GWC_WS_VIRTUAL_SERVICE_PATTERN = Pattern.compile("([^/]+)/gwc/service");
private static final Pattern GWC_LAYER_VIRTUAL_SERVICE_PATTERN = Pattern.compile("([^/]+)/([^/]+)/gwc/service");

private final Catalog catalog;

Expand Down Expand Up @@ -73,6 +77,7 @@ public Request init(Request request) {

// if we are in the presence of virtual service we need to adapt the request
WorkspaceInfo localWorkspace = LocalWorkspace.get();
PublishedInfo localPublished = LocalPublished.get();
if (localWorkspace != null) {
// this is a virtual service request
String layerName = (String) request.getKvp().get("LAYER");
Expand All @@ -86,9 +91,14 @@ public Request init(Request request) {
// we set the layer parameter with GWC expected name
kvp.put("LAYER", layerName);
}

String localPublishedName = localPublished != null ? localPublished.getName() : null;
// we need to setup a proper context path (gwc doesn't expect the workspace to be part of the URL)
request.setHttpRequest(new VirtualServiceRequest(request.getHttpRequest(), localWorkspace.getName(), layerName));
request.setHttpRequest(new VirtualServiceRequest(request.getHttpRequest(), localWorkspace.getName(), localPublishedName, layerName));
} else if(localPublished != null) {
request.setHttpRequest(new VirtualServiceRequest(request.getHttpRequest(), localPublished.getName(), null, null));
}


request.setKvp(kvp);
request.setRawKvp(kvp);
Expand All @@ -104,17 +114,28 @@ private boolean isGwcServiceTargeted(String context) {
// is gwc is targeted
return true;
}
// we may be in the context of a virtual service
Matcher matcher = GWC_VIRTUAL_SERVICE_PATTERN.matcher(context);
// we may be in the context of a workspace or group specific
Matcher matcher = GWC_WS_VIRTUAL_SERVICE_PATTERN.matcher(context);
if (matcher.matches()) {
// this is a virtual service, let's see if we have a valid workspace
if(LocalWorkspace.get() == null) {
if(LocalWorkspace.get() == null && !(LocalPublished.get() instanceof LayerGroupInfo)) {
// the workspace name has to be valid
throw new ServiceException("No such workspace '" + matcher.group(1) + "'");
}
// the local workspace is set so we have a valid workspace
return true;
}
matcher = GWC_LAYER_VIRTUAL_SERVICE_PATTERN.matcher(context);
if (matcher.matches()) {
// this is a laye specific virtual service, let's see if we have a valid workspace
if(LocalPublished.get() == null) {
// the workspace name has to be valid
throw new ServiceException("No such layer or layer group '" + matcher.group(2) + "'");
}
// the local workspace is set so we have a valid workspace
return true;
}

// this request is not targeting gwc service
return false;
}
Expand All @@ -126,13 +147,16 @@ private boolean isGwcServiceTargeted(String context) {
private final class VirtualServiceRequest extends HttpServletRequestWrapper {

private final String localWorkspaceName;
private String localPublishedName;
private final String layerName;

private final Map<String, String[]> parameters;


public VirtualServiceRequest(HttpServletRequest request, String localWorkspaceName, String layerName) {
public VirtualServiceRequest(HttpServletRequest request, String localWorkspaceName, String localPublishedName, String layerName) {
super(request);
this.localWorkspaceName = localWorkspaceName;
this.localPublishedName = localPublishedName;
this.layerName = layerName;
parameters = new HashMap<>(request.getParameterMap());
if (layerName != null) {
Expand All @@ -143,7 +167,11 @@ public VirtualServiceRequest(HttpServletRequest request, String localWorkspaceNa
@Override
public String getContextPath() {
// to GWC the workspace is part of the request context
return super.getContextPath() + "/" + localWorkspaceName;
if(localPublishedName == null) {
return super.getContextPath() + "/" + localWorkspaceName;
} else {
return super.getContextPath() + "/" + localWorkspaceName + "/" + localPublishedName;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.PublishedType;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.gwc.GWC;
import org.geoserver.ows.LocalPublished;
import org.geoserver.ows.LocalWorkspace;
import org.geoserver.wms.WMS;
import org.geotools.util.logging.Logging;
Expand Down Expand Up @@ -291,24 +293,45 @@ public GeoServerTileLayer getTileLayerById(final String layerId) {
layer = layerCache.get(layerId);
// let's see if this a virtual service request
WorkspaceInfo localWorkspace = LocalWorkspace.get();
PublishedInfo localPublished = LocalPublished.get();
if (localWorkspace != null) {
// yup this is a virtual service request, so we need to filter layers per workspace
WorkspaceInfo layerWorkspace;
LayerInfo layerInfo = layer.getLayerInfo();
if (layerInfo != null) {
PublishedInfo publishedInfo = layer.getPublishedInfo();
if (publishedInfo instanceof LayerInfo) {
// this is a normal layer
layerWorkspace = layer.getLayerInfo().getResource().getStore().getWorkspace();
layerWorkspace = ((LayerInfo) publishedInfo).getResource().getStore().getWorkspace();
} else {
// this is a layer group
layerWorkspace = layer.getLayerGroupInfo().getWorkspace();
layerWorkspace = ((LayerGroupInfo) publishedInfo).getWorkspace();
}
// check if the layer doesn't have an workspace (this is possible for layer groups)
if (layerWorkspace == null) {
// no workspace means that it doesn't belong to this workspace
return null;
}
// if the layer matches the virtual service workspace we return the layer otherwise NULL is returned
return localWorkspace.getName().equals(layerWorkspace.getName()) ? layer : null;
if(!localWorkspace.getName().equals(layerWorkspace.getName())) {
return null;
}

// are we in a layer specific case too?

if(localPublished != null && !localPublished.getName().equals(publishedInfo.getName())) {
return null;
}
} else if(localPublished != null) {
// this implies we're looking at a global layer group, there is no such a thing
// as a global layer
PublishedInfo publishedInfo = layer.getPublishedInfo();
if(!(publishedInfo instanceof LayerGroupInfo)) {
return null;
} else {
LayerGroupInfo lg = (LayerGroupInfo) publishedInfo;
if(lg.getWorkspace() != null || !lg.getName().equals(localPublished.getName())) {
return null;
}
}
}
} catch (ExecutionException e) {
throw propagate(e.getCause());
Expand Down
45 changes: 38 additions & 7 deletions src/gwc/src/test/java/org/geoserver/gwc/GWCIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@

import static org.geoserver.data.test.MockData.BASIC_POLYGONS;
import static org.geoserver.gwc.GWC.tileLayerName;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -987,6 +981,43 @@ public void testGetCapabilitiesWithLocalWorkspace() throws Exception {
assertThat(xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='" +
MockData.BUILDINGS.getLocalPart() + "'])", document), is("1"));
}

@Test
public void testGetCapabilitiesWithLocalLayer() throws Exception {
// initiating the xpath engine
Map<String, String> namespaces = new HashMap<>();
namespaces.put("xlink", "http://www.w3.org/1999/xlink");
namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
namespaces.put("ows", "http://www.opengis.net/ows/1.1");
namespaces.put("wmts", "http://www.opengis.net/wmts/1.0");
XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces));
XpathEngine xpath = XMLUnit.newXpathEngine();
// getting capabilities document for CITE workspace
Document document = getAsDOM(MockData.CITE_PREFIX + "/" + MockData.BUILDINGS.getLocalPart() + "/gwc/service/wmts?request=GetCapabilities");
// checking get capabilities result for CITE workspace
List<LayerInfo> citeLayers = getWorkspaceLayers(MockData.CITE_PREFIX);
assertThat(Integer.parseInt(xpath.evaluate("count(//wmts:Contents/wmts:Layer)", document)), equalTo(1));
assertThat(xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='" +
MockData.BUILDINGS.getLocalPart() + "'])", document), is("1"));
}

@Test
public void testGetCapabilitiesWithLocalGroup() throws Exception {
// initiating the xpath engine
Map<String, String> namespaces = new HashMap<>();
namespaces.put("xlink", "http://www.w3.org/1999/xlink");
namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
namespaces.put("ows", "http://www.opengis.net/ows/1.1");
namespaces.put("wmts", "http://www.opengis.net/wmts/1.0");
XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces));
XpathEngine xpath = XMLUnit.newXpathEngine();
// getting capabilities document for CITE workspace
Document document = getAsDOM(SIMPLE_LAYER_GROUP + "/gwc/service/wmts?request=GetCapabilities");
// checking get capabilities result for CITE workspace
assertThat(Integer.parseInt(xpath.evaluate("count(//wmts:Contents/wmts:Layer)", document)), equalTo(1));
assertThat(xpath.evaluate("count(//wmts:Contents/wmts:Layer[ows:Identifier='" +
SIMPLE_LAYER_GROUP + "'])", document), is("1"));
}

@Test
public void testGetTileWithLocalWorkspace() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Request init(Request request) {

int slash = first.indexOf('/');
if (slash > -1) {
last = first.substring(slash+1);
last = first.substring(slash + 1);
first = first.substring(0, slash);
}

Expand All @@ -58,6 +58,12 @@ public Request init(Request request) {
//hack up a qualified name
NamespaceInfo ns = catalog.getNamespaceByPrefix(ws.getName());
if (ns != null) {
// can have extra bits, like ws/layer/gwc/service
int slashInLayer = last.indexOf('/');
if(slashInLayer != -1) {
last = last.substring(0, slashInLayer);
}

LayerInfo l = catalog.getLayerByName(new NameImpl(ns.getURI(), last));
if (l != null) {
LocalPublished.set(l);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,9 @@ protected Object lookupHandler(String urlPath, HttpServletRequest request) throw

return h;
}

@Override
public String toString() {
return "OWSHandlerMapping[" + this.getHandlerMap() + "]";
}
}

0 comments on commit 4493988

Please sign in to comment.