/*
* Constellation - An open source and standard compliant SDI
* http://www.constellation-sdi.org
*
* Copyright 2014 Geomatys.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.constellation.ws.embedded;
// JUnit dependencies
import org.constellation.business.IServiceBusiness;
import org.constellation.configuration.ConfigDirectory;
import org.constellation.admin.SpringHelper;
import org.constellation.configuration.ConfigurationException;
import org.constellation.configuration.DataSourceType;
import org.constellation.configuration.SOSConfiguration;
import org.constellation.generic.database.Automatic;
import org.constellation.generic.database.BDD;
import org.constellation.sos.ws.soap.SOService;
import org.constellation.test.utils.Order;
import org.constellation.test.utils.SpringTestRunner;
import org.constellation.util.Util;
import org.geotoolkit.internal.sql.DefaultDataSource;
import org.geotoolkit.internal.sql.ScriptRunner;
import org.geotoolkit.observation.xml.v100.ObservationCollectionType;
import org.geotoolkit.ows.xml.v110.ExceptionReport;
import org.geotoolkit.ows.xml.v110.Operation;
import org.geotoolkit.sampling.xml.v100.SamplingPointType;
import org.geotoolkit.sml.xml.AbstractSensorML;
import org.geotoolkit.sos.xml.ResponseModeType;
import org.geotoolkit.sos.xml.SOSMarshallerPool;
import org.geotoolkit.sos.xml.v100.Capabilities;
import org.geotoolkit.sos.xml.v100.DescribeSensor;
import org.geotoolkit.sos.xml.v100.GetCapabilities;
import org.geotoolkit.sos.xml.v100.GetFeatureOfInterest;
import org.geotoolkit.sos.xml.v100.GetObservation;
import org.geotoolkit.sos.xml.v200.CapabilitiesType;
import org.geotoolkit.sos.xml.v200.GetCapabilitiesType;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.geotoolkit.util.FileUtilities;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.BeforeClass;
import org.springframework.test.context.ActiveProfiles;
/**
*
* @author Guilhem Legal (Geomatys)
*/
@RunWith(SpringTestRunner.class)
@ContextConfiguration("classpath:/cstl/spring/test-context.xml")
@ActiveProfiles({"standard"})
public class SOSRequestTest extends AbstractGrizzlyServer implements ApplicationContextAware {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger("org.constellation.ws.embedded");
protected ApplicationContext applicationContext;
private static boolean initialized = false;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Inject
private IServiceBusiness serviceBusiness;
private static String getDefaultURL() {
return "http://localhost:" + grizzly.getCurrentPort() + "/sos/default?";
}
private static String getTestURL() {
return "http://localhost:" + grizzly.getCurrentPort() + "/sos/test?";
}
private static File configDirectory;
@BeforeClass
public static void initTestDir() {
configDirectory = ConfigDirectory.setupTestEnvironement("SOSRequestTest");
}
/**
* Initialize the list of layers from the defined providers in Constellation's configuration.
*/
@PostConstruct
public void initPool() {
SpringHelper.setApplicationContext(applicationContext);
if (!initialized) {
try {
try {
serviceBusiness.deleteAll();
} catch (Exception ex) {
LOGGER.warn(ex.getMessage());
}
final String url = "jdbc:derby:memory:TestOM2;create=true";
final DefaultDataSource ds = new DefaultDataSource(url);
Connection con = ds.getConnection();
final ScriptRunner exec = new ScriptRunner(con);
String sql = FileUtilities.getStringFromStream(Util.getResourceAsStream("org/constellation/om2/structure_observations.sql"));
sql = sql.replace("$SCHEMA", "");
exec.run(sql);
exec.run(Util.getResourceAsStream("org/constellation/sql/sos-data-om2.sql"));
con.close();
final File dataDirectory = new File(configDirectory, "dataSos");
dataDirectory.mkdir();
writeDataFile(dataDirectory, "urn-ogc-object-sensor-SunSpot-0014.4F01.0000.261A");
writeDataFile(dataDirectory, "urn-ogc-object-sensor-SunSpot-0014.4F01.0000.2626");
writeDataFile(dataDirectory, "urn-ogc-object-sensor-SunSpot-2");
final Automatic smlConfig = new Automatic(null, dataDirectory.getPath());
final Automatic omCOnfig = new Automatic(null, new BDD("derby", url, null, null));
final SOSConfiguration sosconf = new SOSConfiguration(smlConfig, omCOnfig);
sosconf.setObservationFilterType(DataSourceType.OM2);
sosconf.setObservationReaderType(DataSourceType.OM2);
sosconf.setObservationWriterType(DataSourceType.OM2);
sosconf.setSMLType(DataSourceType.FILESYSTEM);
sosconf.setProfile("transactional");
sosconf.setObservationIdBase("urn:ogc:object:observation:SunSpot:");
sosconf.setSensorIdBase("urn:ogc:object:sensor:SunSpot:");
sosconf.setPhenomenonIdBase("urn:phenomenon:");
sosconf.setObservationTemplateIdBase("urn:ogc:object:observationTemplate:SunSpot:");
sosconf.setVerifySynchronization(false);
try {
serviceBusiness.delete("sos", "default");
serviceBusiness.delete("sos", "test");
} catch (ConfigurationException ex) {}
serviceBusiness.create("sos", "default", sosconf, null);
serviceBusiness.create("sos", "test", sosconf, null);
final Map<String, Object> map = new HashMap<>();
map.put("sos", new SOService());
initServer(null, map);
// Get the list of layers
pool = SOSMarshallerPool.getInstance();
initialized = true;
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
}
}
@AfterClass
public static void shutDown() {
try {
final IServiceBusiness service = SpringHelper.getBean(IServiceBusiness.class);
if (service != null) {
service.deleteAll();
}
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
File f = new File("derby.log");
if (f.exists()) {
f.delete();
}
ConfigDirectory.shutdownTestEnvironement("SOSRequestTest");
finish();
}
@Test
@Order(order=1)
public void testSOSInvalidRequest() throws Exception {
waitForStart();
// Creates a valid GetCapabilities url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
postRequestPlain(conec, "test");
Object obj = unmarshallResponse(conec);
assertTrue(obj instanceof ExceptionReport);
ExceptionReport report = (ExceptionReport) obj;
assertEquals("InvalidRequest", report.getException().get(0).getExceptionCode());
}
@Test
@Order(order=2)
public void testSOSGetCapabilities() throws Exception {
// Creates a valid GetCapabilities url.
URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
final GetCapabilities request = new GetCapabilities("1.0.0", "text/xml");
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
assertTrue(obj instanceof Capabilities);
Capabilities c = (Capabilities) obj;
assertTrue(c.getOperationsMetadata() != null);
Operation op = c.getOperationsMetadata().getOperation("GetObservation");
assertTrue(op != null);
assertTrue(op.getDCP().size() > 0);
assertEquals(op.getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref(), getDefaultURL());
// Creates a valid GetCapabilties url.
getCapsUrl = new URL(getTestURL() + "request=GetCapabilities&service=SOS&version=1.0.0");
// Try to marshall something from the response returned by the server.
// The response should be a Capabilities.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj, obj instanceof Capabilities);
c = (Capabilities) obj;
op = c.getOperationsMetadata().getOperation("GetObservation");
assertEquals(op.getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref(), getTestURL());
// Creates a valid GetCapabilties url.
getCapsUrl = new URL(getDefaultURL()+ "request=GetCapabilities&service=SOS&version=1.0.0");
// Try to marshall something from the response returned by the server.
// The response should be a Capabilities.
obj = unmarshallResponse(getCapsUrl);
assertTrue(obj instanceof Capabilities);
c = (Capabilities) obj;
op = c.getOperationsMetadata().getOperation("GetObservation");
assertEquals(op.getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref(), getDefaultURL());
}
@Test
@Order(order=3)
public void testSOSGetCapabilitiesv2() throws Exception {
// Creates a valid GetCapabilities url.
URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
final GetCapabilitiesType request = new GetCapabilitiesType("2.0.0", "text/xml");
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
assertTrue(obj instanceof CapabilitiesType);
CapabilitiesType c = (CapabilitiesType) obj;
assertTrue(c.getOperationsMetadata() != null);
Operation op = c.getOperationsMetadata().getOperation("GetObservation");
assertTrue(op != null);
assertTrue(op.getDCP().size() > 0);
assertEquals(op.getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref(), getDefaultURL());
// Creates a valid GetCapabilties url.
getCapsUrl = new URL(getTestURL() + "request=GetCapabilities&service=SOS&version=2.0.0");
// Try to marshall something from the response returned by the server.
// The response should be a Capabilities.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj, obj instanceof CapabilitiesType);
c = (CapabilitiesType) obj;
op = c.getOperationsMetadata().getOperation("GetObservation");
assertEquals(op.getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref(), getTestURL());
// Creates a valid GetCapabilties url.
getCapsUrl = new URL(getDefaultURL()+ "request=GetCapabilities&service=SOS&version=2.0.0");
// Try to marshall something from the response returned by the server.
// The response should be a Capabilities.
obj = unmarshallResponse(getCapsUrl);
assertTrue(obj instanceof CapabilitiesType);
c = (CapabilitiesType) obj;
op = c.getOperationsMetadata().getOperation("GetObservation");
assertEquals(op.getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref(), getDefaultURL());
}
@Test
@Order(order=4)
public void testSOSDescribeSensor() throws Exception {
// Creates a valid DescribeSensor url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
final DescribeSensor request = new DescribeSensor("1.0.0","SOS","urn:ogc:object:sensor:SunSpot:0014.4F01.0000.261A", "text/xml;subtype=\"SensorML/1.0.1\"");
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
String type = "null";
if (obj != null) {
type = obj.getClass().getName();
}
assertTrue("expecting AbstractSensorML but was: " + type, obj instanceof AbstractSensorML);
}
@Test
@Order(order=5)
public void testSOSGetObservation() throws Exception {
// Creates a valid GetObservation url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
GetObservation request = new GetObservation("1.0.0",
"offering-3",
null,
Arrays.asList("urn:ogc:object:sensor:GEOM:3"),
Arrays.asList("urn:ogc:def:phenomenon:GEOM:depth"),
null,
null,
"text/xml; subtype=\"om/1.0.0\"",
null,
ResponseModeType.INLINE,
null);
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
String type = "null";
if (obj != null) {
type = obj.getClass().getName();
}
assertTrue("expecting ObservationCollectionType but was: " + type, obj instanceof ObservationCollectionType);
}
@Test
@Order(order=6)
public void testSOSGetFeatureOfInterest() throws Exception {
// Creates a valid GetObservation url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
GetFeatureOfInterest request = new GetFeatureOfInterest("1.0.0", "SOS", "station-001");
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
String type = "null";
if (obj != null) {
type = obj.getClass().getName();
}
assertTrue("expecting SamplingPointType but was: " + type, obj instanceof SamplingPointType);
// Creates a valid GetFeatureFInterest url.
final URL getFoiUrl = new URL(getDefaultURL() + "request=GetFeatureOfInterest&service=SOS&version=1.0.0&FeatureOfInterestId=station-001");
// Try to marshall something from the response returned by the server.
// The response should be a Capabilities.
obj = unmarshallResponse(getFoiUrl);
assertTrue("expecting SamplingPointType but was: " + obj, obj instanceof SamplingPointType);
}
public static void writeDataFile(File dataDirectory, String resourceName) throws IOException {
final File dataFile;
if (System.getProperty("os.name", "").startsWith("Windows")) {
final String windowsIdentifier = resourceName.replace(':', '-');
dataFile = new File(dataDirectory, windowsIdentifier + ".xml");
} else {
dataFile = new File(dataDirectory, resourceName + ".xml");
}
FileWriter fw = new FileWriter(dataFile);
InputStream in = Util.getResourceAsStream("org/constellation/embedded/test/" + resourceName + ".xml");
byte[] buffer = new byte[1024];
int size;
while ((size = in.read(buffer, 0, 1024)) > 0) {
fw.write(new String(buffer, 0, size));
}
in.close();
fw.close();
}
}