Skip to content

Commit

Permalink
[GEOS-8108] fix for null namespaces with GetPropertyValue and stored …
Browse files Browse the repository at this point in the history
…queries requests
  • Loading branch information
ridethepenguin committed Nov 21, 2017
1 parent d0906a9 commit 22565f6
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 39 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,23 +5,36 @@
*/ */
package org.geoserver.test; package org.geoserver.test;


import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.file.Files;
import java.util.AbstractMap.SimpleEntry;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.custommonkey.xmlunit.SimpleNamespaceContext; import org.custommonkey.xmlunit.SimpleNamespaceContext;
import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.XpathEngine; import org.custommonkey.xmlunit.XpathEngine;
import org.geoserver.util.IOUtils; import org.geoserver.util.IOUtils;
import org.geoserver.wfs.StoredQuery;
import org.geoserver.wfs.StoredQueryProvider;
import org.geotools.wfs.v2_0.WFS;
import org.geotools.wfs.v2_0.WFSConfiguration;
import org.geotools.xml.Parser;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.w3c.dom.Document; import org.w3c.dom.Document;


import java.io.File; import net.opengis.wfs20.StoredQueryDescriptionType;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;


/** /**
* Tests that namespaces are correctly handled by WFS and app-schema when * Tests that namespaces are correctly handled by WFS and app-schema when
Expand All @@ -31,6 +44,44 @@ public final class NamespacesWfsTest extends AbstractAppSchemaTestSupport {


private static final File TEST_ROOT_DIRECTORY; private static final File TEST_ROOT_DIRECTORY;


private static final String TEST_STORED_QUERY_ID = "NamespacesTestStoredQuery";

/* Should return the same result as a GetFeature request against the Station feature type */
private static final String TEST_STORED_QUERY_DEFINITION =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<wfs:StoredQueryDescription id='" + TEST_STORED_QUERY_ID + "'" +
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"" +
" xmlns:ows=\"http://www.opengis.net/ows/1.1\"" +
" xmlns:gml=\"${GML_NAMESPACE}\"" +
" xmlns:wfs=\"http://www.opengis.net/wfs/2.0\"" +
" xmlns:fes=\"http://www.opengis.net/fes/2.0\">>\n" +
" <wfs:QueryExpressionText\n" +
" returnFeatureTypes='st_${GML_PREFIX}:Station_${GML_PREFIX}'\n" +
" language='urn:ogc:def:queryLanguage:OGC-WFS::WFS_QueryExpression'\n" +
" isPrivate='false'>\n" +
" <wfs:Query typeNames='st_${GML_PREFIX}:Station_${GML_PREFIX}'>\n" +
" <fes:Filter>\n" +
" <fes:PropertyIsEqualTo>\n" +
" <fes:ValueReference>st_${GML_PREFIX}:measurements/ms_${GML_PREFIX}:Measurement/ms_${GML_PREFIX}:name</fes:ValueReference>\n" +
" <fes:Literal>wind</fes:Literal>\n" +
" </fes:PropertyIsEqualTo>\n" +
" </fes:Filter>\n" +
" </wfs:Query>\n" +
" </wfs:QueryExpressionText>\n" +
"</wfs:StoredQueryDescription>";

private static final Map<String, String> GML31_PARAMETERS = Collections.unmodifiableMap(Stream.of(
new SimpleEntry<>("GML_PREFIX", "gml31"),
new SimpleEntry<>("GML_NAMESPACE", "http://www.opengis.net/gml"),
new SimpleEntry<>("GML_LOCATION", "http://schemas.opengis.net/gml/3.1.1/base/gml.xsd"))
.collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

private static final Map<String, String> GML32_PARAMETERS = Collections.unmodifiableMap(Stream.of(
new SimpleEntry<>("GML_PREFIX", "gml32"),
new SimpleEntry<>("GML_NAMESPACE", "http://www.opengis.net/gml/3.2"),
new SimpleEntry<>("GML_LOCATION", "http://schemas.opengis.net/gml/3.2.1/gml.xsd"))
.collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

static { static {
try { try {
// create the tests root directory // create the tests root directory
Expand Down Expand Up @@ -79,17 +130,9 @@ public void addContent() {
putNamespace(STATIONS_PREFIX_GML32, STATIONS_URI_GML32); putNamespace(STATIONS_PREFIX_GML32, STATIONS_URI_GML32);
putNamespace(MEASUREMENTS_PREFIX_GML32, MEASUREMENTS_URI_GML32); putNamespace(MEASUREMENTS_PREFIX_GML32, MEASUREMENTS_URI_GML32);
// add GML 3.1 feature type // add GML 3.1 feature type
Map<String, String> gml31Parameters = new HashMap<>(); addFeatureType(STATIONS_PREFIX_GML31, "gml31", GML31_PARAMETERS);
gml31Parameters.put("GML_PREFIX", "gml31"); // add GML 3.2 feature type
gml31Parameters.put("GML_NAMESPACE", "http://www.opengis.net/gml"); addFeatureType(STATIONS_PREFIX_GML32, "gml32", GML32_PARAMETERS);
gml31Parameters.put("GML_LOCATION", "http://schemas.opengis.net/gml/3.1.1/base/gml.xsd");
addFeatureType(STATIONS_PREFIX_GML31, "gml31", gml31Parameters);
// add GML 3.1 feature type
Map<String, String> gml32Parameters = new HashMap<>();
gml32Parameters.put("GML_PREFIX", "gml32");
gml32Parameters.put("GML_NAMESPACE", "http://www.opengis.net/gml/3.2");
gml32Parameters.put("GML_LOCATION", "http://schemas.opengis.net/gml/3.2.1/gml.xsd");
addFeatureType(STATIONS_PREFIX_GML32, "gml32", gml32Parameters);
} }


/** /**
Expand Down Expand Up @@ -131,11 +174,7 @@ private void addFeatureType(String namespacePrefix, String gmlPrefix, Map<String
private static void substituteParameters(String resourceName, Map<String, String> parameters, File newFile) { private static void substituteParameters(String resourceName, Map<String, String> parameters, File newFile) {
// read the resource content // read the resource content
String resourceContent = resourceToString(resourceName); String resourceContent = resourceToString(resourceName);
for (Map.Entry<String, String> parameter : parameters.entrySet()) { resourceContent = substituteParametersInTemplateString(resourceContent, parameters);
// substitute the parameter on the resource content
resourceContent = resourceContent.replace(
String.format("${%s}", parameter.getKey()), parameter.getValue());
}
try { try {
// write the final resource content to the provided location // write the final resource content to the provided location
Files.write(newFile.toPath(), resourceContent.getBytes()); Files.write(newFile.toPath(), resourceContent.getBytes());
Expand All @@ -145,6 +184,18 @@ private static void substituteParameters(String resourceName, Map<String, String
} }
} }


private static String substituteParametersInTemplateString(String templateString,
Map<String, String> parameters) {
String processedString = templateString;

for (Map.Entry<String, String> parameter : parameters.entrySet()) {
processedString = processedString
.replace(String.format("${%s}", parameter.getKey()), parameter.getValue());
}

return processedString;
}

/** /**
* Helper method the reads a resource content to a string. * Helper method the reads a resource content to a string.
*/ */
Expand Down Expand Up @@ -180,32 +231,139 @@ public void beforeTest() {
"gml", "http://www.opengis.net/gml/3.2"); "gml", "http://www.opengis.net/gml/3.2");
} }


/*** GetFeature tests ***/

@Test @Test
public void globalServiceNamespacesWfs11() throws Exception { public void globalServiceGetFeatureNamespacesWfs11() throws Exception {
Document document = getAsDOM("wfs?request=GetFeature&version=1.1.0&typename=st_gml31:Station_gml31"); Document document = getAsDOM("wfs?request=GetFeature&version=1.1.0&typename=st_gml31:Station_gml31");
checkWfs11StationsGetFeatureResult(document); checkWfs11StationsGetFeatureResult(document);
} }


@Test @Test
public void virtualServiceNamespacesWfs11() throws Exception { public void virtualServiceGetFeatureNamespacesWfs11() throws Exception {
Document document = getAsDOM("st_gml31/wfs?request=GetFeature&version=1.1.0&typename=st_gml31:Station_gml31"); Document document = getAsDOM("st_gml31/wfs?request=GetFeature&version=1.1.0&typename=st_gml31:Station_gml31");
checkWfs11StationsGetFeatureResult(document); checkWfs11StationsGetFeatureResult(document);
} }


@Test @Test
public void globalServiceNamespacesWfs20() throws Exception { public void globalServiceGetFeatureNamespacesWfs20() throws Exception {
Document document = getAsDOM("wfs?request=GetFeature&version=2.0&typename=st_gml32:Station_gml32"); Document document = getAsDOM("wfs?request=GetFeature&version=2.0&typename=st_gml32:Station_gml32");
checkWfs20StationsGetFeatureResult(document); checkWfs20StationsGetFeatureResult(document);
} }


@Test @Test
public void virtualServiceNamespacesWfs20() throws Exception { public void virtualServiceGetFeatureNamespacesWfs20() throws Exception {
Document document = getAsDOM("st_gml32/wfs?request=GetFeature&version=2.0&typename=st_gml32:Station_gml32"); Document document = getAsDOM("st_gml32/wfs?request=GetFeature&version=2.0&typename=st_gml32:Station_gml32");
checkWfs20StationsGetFeatureResult(document); checkWfs20StationsGetFeatureResult(document);
} }


/*** GetPropertyValue tests ***/

@Test
public void globalServiceGetPropertyValueNamespacesGml32() throws Exception {
Document document = getAsDOM("wfs?request=GetPropertyValue&version=2.0&typename=st_gml32:Station_gml32&valueReference=st_gml32:measurements");
checkGml32StationsGetPropertyValueResult(document);
}

@Test
public void virtualServiceGetPropertyValueNamespacesGml32() throws Exception {
Document document = getAsDOM("st_gml32/wfs?request=GetPropertyValue&version=2.0&typename=st_gml32:Station_gml32&valueReference=st_gml32:measurements");
checkGml32StationsGetPropertyValueResult(document);
}

/*** StoredQuery tests ***/

@Test
public void globalServiceStoredQueryNamespacesGml32() throws Exception {
StoredQueryProvider storedQueryProvider = new StoredQueryProvider(getCatalog());
try {
createTestStoredQuery(storedQueryProvider, GML32_PARAMETERS);

Document document = getAsDOM("wfs?request=GetFeature&version=2.0&StoredQueryID=" + TEST_STORED_QUERY_ID);
checkWfs20StationsGetFeatureResult(document);
} finally {
storedQueryProvider.removeAll();
assertTrue(storedQueryProvider.listStoredQueries().size() == 1);
}
}

@Test
public void virtualServiceStoredQueryNamespacesGml32() throws Exception {
StoredQueryProvider storedQueryProvider = new StoredQueryProvider(getCatalog());
try {
createTestStoredQuery(storedQueryProvider, GML32_PARAMETERS);

Document document = getAsDOM(
"st_gml32/wfs?request=GetFeature&version=2.0&StoredQueryID="
+ TEST_STORED_QUERY_ID);
checkWfs20StationsGetFeatureResult(document);
} finally {
storedQueryProvider.removeAll();
assertTrue(storedQueryProvider.listStoredQueries().size() == 1);
}
}

@Test
public void globalServiceStoredQueryNamespacesGml31() throws Exception {
StoredQueryProvider storedQueryProvider = new StoredQueryProvider(getCatalog());
try {
createTestStoredQuery(storedQueryProvider, GML31_PARAMETERS);

Document document = getAsDOM(
"wfs?request=GetFeature&version=2.0&outputFormat=gml3&StoredQueryID="
+ TEST_STORED_QUERY_ID);
checkWfs11StationsGetFeatureResult(document);
} finally {
storedQueryProvider.removeAll();
assertTrue(storedQueryProvider.listStoredQueries().size() == 1);
}
}

@Test
public void virtualServiceStoredQueryNamespacesGml31() throws Exception {
StoredQueryProvider storedQueryProvider = new StoredQueryProvider(getCatalog());
try {
createTestStoredQuery(storedQueryProvider, GML31_PARAMETERS);

Document document = getAsDOM(
"st_gml31/wfs?request=GetFeature&version=2.0&outputFormat=gml3&StoredQueryID="
+ TEST_STORED_QUERY_ID);
checkWfs11StationsGetFeatureResult(document);
} finally {
storedQueryProvider.removeAll();
assertTrue(storedQueryProvider.listStoredQueries().size() == 1);
}
}

private void createTestStoredQuery(StoredQueryProvider storedQueryProvider,
Map<String, String> parameters) throws Exception {
StoredQueryDescriptionType storedQueryDescriptionType = createTestStoredQueryDefinition(
parameters);
StoredQuery result = storedQueryProvider.createStoredQuery(storedQueryDescriptionType);

assertTrue(storedQueryProvider.listStoredQueries().size() == 2);
assertThat(result.getName(), is(TEST_STORED_QUERY_ID));
assertThat(storedQueryProvider.getStoredQuery(TEST_STORED_QUERY_ID).getName(),
is(TEST_STORED_QUERY_ID));
}

private StoredQueryDescriptionType createTestStoredQueryDefinition(
Map<String, String> parameters) throws Exception {
Parser p = new Parser(new WFSConfiguration());
p.setRootElementType(WFS.StoredQueryDescriptionType);

String queryDefinition = MockData
.substituteParametersInTemplateString(TEST_STORED_QUERY_DEFINITION, parameters);
StringReader reader = new StringReader(queryDefinition);
try {
return (StoredQueryDescriptionType) p.parse(reader);
} finally {
reader.close();
}
}

/** /**
* Check the result of a WFS 1.1 get feature request targeting stations data set. * Check the result of a WFS 1.1 (GML 3.1) get feature request targeting stations data set.
*/ */
private void checkWfs11StationsGetFeatureResult(Document document) { private void checkWfs11StationsGetFeatureResult(Document document) {
checkCount(WFS11_XPATH_ENGINE, document, 1, "/wfs:FeatureCollection/gml:featureMember/" + checkCount(WFS11_XPATH_ENGINE, document, 1, "/wfs:FeatureCollection/gml:featureMember/" +
Expand All @@ -215,7 +373,7 @@ private void checkWfs11StationsGetFeatureResult(Document document) {
} }


/** /**
* Check the result of a WFS 2.0 get feature request targeting stations data set. * Check the result of a WFS 2.0 (GML 3.2) get feature request targeting stations data set.
*/ */
private void checkWfs20StationsGetFeatureResult(Document document) { private void checkWfs20StationsGetFeatureResult(Document document) {
checkCount(WFS20_XPATH_ENGINE, document, 1, "/wfs:FeatureCollection/wfs:member/" + checkCount(WFS20_XPATH_ENGINE, document, 1, "/wfs:FeatureCollection/wfs:member/" +
Expand All @@ -224,6 +382,16 @@ private void checkWfs20StationsGetFeatureResult(Document document) {
"st_gml32:Station_gml32[@gml:id='st.1']/st_gml32:location/gml:Point[gml:pos='1.0 -1.0']"); "st_gml32:Station_gml32[@gml:id='st.1']/st_gml32:location/gml:Point[gml:pos='1.0 -1.0']");
} }


/**
* Check the result of a WFS 2.0 (GML 3.2) get property value request targeting the Station feature type.
*/
private void checkGml32StationsGetPropertyValueResult(Document document) {
checkCount(WFS20_XPATH_ENGINE, document, 1, "/wfs:ValueCollection/wfs:member/" +
"st_gml32:measurements/ms_gml32:Measurement[ms_gml32:name='temperature']");
checkCount(WFS20_XPATH_ENGINE, document, 1, "/wfs:ValueCollection/wfs:member/" +
"st_gml32:measurements/ms_gml32:Measurement[ms_gml32:name='wind']");
}

/** /**
* Helper method that evaluates a xpath and checks if the number of nodes found * Helper method that evaluates a xpath and checks if the number of nodes found
* correspond to the expected number, * correspond to the expected number,
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -190,9 +190,11 @@ private void ensureFeatureNamespaceUriMatches(List features,
} }


void qualifyTypeNames(List names, WorkspaceInfo ws, NamespaceInfo ns) { void qualifyTypeNames(List names, WorkspaceInfo ws, NamespaceInfo ns) {
for (int i = 0; i < names.size(); i++) { if (names != null) {
QName name = (QName) names.get(i); for (int i = 0; i < names.size(); i++) {
names.set(i, qualifyTypeName(name, ws, ns)); QName name = (QName) names.get(i);
names.set(i, qualifyTypeName(name, ws, ns));
}
} }
} }


Expand Down

0 comments on commit 22565f6

Please sign in to comment.