package org.geoserver.gss;
import static org.custommonkey.xmlunit.XMLAssert.*;
import static org.geoserver.gss.GSSCore.*;
import static org.geotools.data.DataUtilities.*;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.custommonkey.xmlunit.SimpleNamespaceContext;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.XpathEngine;
import org.geoserver.config.GeoServer;
import org.geoserver.data.test.LiveDbmsData;
import org.geoserver.data.test.TestData;
import org.geoserver.gss.GSSInfo.GSSMode;
import org.geoserver.gss.xml.GSSConfiguration;
import org.geoserver.test.GeoServerAbstractTestSupport;
import org.geotools.data.FeatureStore;
import org.geotools.data.VersioningDataStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.xml.Parser;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.FilterFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import com.mockrunner.mock.web.MockHttpServletResponse;
/**
* Base class for gss functional testing, sets up a proper testing enviroment for gss test with a
* real data dir and a connection to a postgis data store
*
* @author Andrea Aime - TOPP
*
*/
public abstract class GSSTestSupport extends GeoServerAbstractTestSupport {
static XpathEngine xpath;
FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
DefaultGeoServerSynchronizationService gss;
VersioningDataStore synchStore;
// protected String getLogConfiguration() {
// return "/DEFAULT_LOGGING.properties";
// }
@Override
public TestData buildTestData() throws Exception {
File base = new File("./src/test/resources/");
LiveDbmsData data = new LiveDbmsData(new File(base, "data_dir"), "unit", new File(base,
"unit.sql"));
List<String> filteredPaths = data.getFilteredPaths();
filteredPaths.clear();
filteredPaths.add("workspaces/topp/synch/datastore.xml");
return data;
}
@Override
protected void setUpInternal() throws Exception {
// configure the GSS service
GeoServer gs = getGeoServer();
GSSInfo gssInfo = gs.getService(GSSInfo.class);
gssInfo.setMode(GSSMode.Unit);
gssInfo.setVersioningDataStore(getCatalog().getDataStoreByName("synch"));
gs.save(gssInfo);
// initialize the GSS service
Map gssBeans = applicationContext
.getBeansOfType(DefaultGeoServerSynchronizationService.class);
gss = (DefaultGeoServerSynchronizationService) gssBeans.values().iterator().next();
gss.core.ensureUnitEnabled();
// mark some tables as version enabled
synchStore = (VersioningDataStore) getCatalog().getDataStoreByName("synch").getDataStore(
null);
FeatureStore<SimpleFeatureType, SimpleFeature> fs = (FeatureStore<SimpleFeatureType, SimpleFeature>) synchStore
.getFeatureSource(SYNCH_TABLES);
SimpleFeatureBuilder fb = new SimpleFeatureBuilder(fs.getSchema());
fs.addFeatures(collection(fb.buildFeature(null, new Object[] { "restricted", "2" })));
fs.addFeatures(collection(fb.buildFeature(null, new Object[] { "roads", "2" })));
synchStore.setVersioned("restricted", true, null, null);
synchStore.setVersioned("roads", true, null, null);
assertNotNull(synchStore.getSchema(SYNCH_HISTORY));
assertFalse(synchStore.isVersioned(SYNCH_HISTORY));
assertNotNull(synchStore.getSchema(SYNCH_TABLES));
assertFalse(synchStore.isVersioned(SYNCH_TABLES));
assertEquals(0, gss.getActiveConflicts("restricted").size());
assertEquals(0, gss.getActiveConflicts("roads").size());
}
@Override
protected void oneTimeSetUp() throws Exception {
super.oneTimeSetUp();
// init xmlunit
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("wfs", "http://www.opengis.net/gss");
namespaces.put("wfs", "http://www.opengis.net/wfs");
namespaces.put("wfsv", "http://www.opengis.net/wfsv");
namespaces.put("ows", "http://www.opengis.net/ows");
namespaces.put("ogc", "http://www.opengis.net/ogc");
namespaces.put("gml", "http://www.opengis.net/gml");
namespaces.put("sf", "http://www.openplans.org/spearfish");
namespaces.put("gss", "http://geoserver.org/gss");
namespaces.put("xs", "http://www.w3.org/2001/XMLSchema");
namespaces.put("", "http://www.opengis.net/ogc");
XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(namespaces));
xpath = XMLUnit.newXpathEngine();
}
/**
* Returns the url of the WFSV entry point
*
* @return
*/
protected String root() {
return root(false);
}
protected String root(boolean validate) {
return "ows?" + (validate ? "strict=true&" : "");
}
/**
* Validates
*
* @param document
* @throws Exception
*/
protected void validate(MockHttpServletResponse response) throws Exception {
GSSConfiguration configuration = (GSSConfiguration) applicationContext
.getBean("gssXmlConfiguration");
Parser parser = new Parser(configuration);
parser.validate(new StringReader(response.getOutputStreamContent()));
if (parser.getValidationErrors().size() > 0) {
for (Iterator it = parser.getValidationErrors().iterator(); it.hasNext();) {
SAXParseException se = (SAXParseException) it.next();
System.out.println(se);
}
// print(dom(response));
fail("Document is not valid, see standard output for a document dump and validation exceptions");
}
}
/**
* Parses the mock response into a DOM tree
*/
protected Document dom(MockHttpServletResponse response) throws IOException, SAXException,
ParserConfigurationException {
return dom(new ByteArrayInputStream(response.getOutputStreamContent().getBytes()));
}
/**
* Loads a text file in the classpath into a String
*
* @param path
* Path relative to the calling class
* @return
* @throws Exception
*/
protected String loadTextResource(String path) throws Exception {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(this.getClass()
.getResourceAsStream(path)));
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
br.close();
return sb.toString();
}
/**
* Makes sure the response is a valid and positive PostDiff one
*/
protected Document checkPostDiffSuccessResponse(MockHttpServletResponse response)
throws Exception {
validate(response);
Document dom = dom(response);
// print(dom);
// basic response checks
assertXpathExists("/gss:PostDiffResponse", dom);
assertXpathEvaluatesTo("true", "/gss:PostDiffResponse/@success", dom);
return dom;
}
}