/*
* 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;
import org.constellation.business.IServiceBusiness;
import org.constellation.configuration.ConfigDirectory;
import org.constellation.admin.SpringHelper;
import org.constellation.configuration.StringList;
import org.constellation.generic.database.Automatic;
import org.constellation.generic.database.GenericDatabaseMarshallerPool;
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.csw.xml.DomainValues;
import org.geotoolkit.csw.xml.ElementSetType;
import org.geotoolkit.csw.xml.ResultType;
import org.geotoolkit.csw.xml.TypeNames;
import org.geotoolkit.csw.xml.v202.Capabilities;
import org.geotoolkit.csw.xml.v202.DescribeRecordResponseType;
import org.geotoolkit.csw.xml.v202.DistributedSearchType;
import org.geotoolkit.csw.xml.v202.DomainValuesType;
import org.geotoolkit.csw.xml.v202.ElementSetNameType;
import org.geotoolkit.csw.xml.v202.GetCapabilitiesType;
import org.geotoolkit.csw.xml.v202.GetDomainResponseType;
import org.geotoolkit.csw.xml.v202.GetDomainType;
import org.geotoolkit.csw.xml.v202.GetRecordByIdResponseType;
import org.geotoolkit.csw.xml.v202.GetRecordByIdType;
import org.geotoolkit.csw.xml.v202.GetRecordsResponseType;
import org.geotoolkit.csw.xml.v202.GetRecordsType;
import org.geotoolkit.csw.xml.v202.ListOfValuesType;
import org.geotoolkit.csw.xml.v202.ObjectFactory;
import org.geotoolkit.csw.xml.v202.QueryConstraintType;
import org.geotoolkit.csw.xml.v202.QueryType;
import org.geotoolkit.ebrim.xml.EBRIMMarshallerPool;
import org.geotoolkit.ows.xml.v100.ExceptionReport;
import org.geotoolkit.ows.xml.v100.Operation;
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 javax.xml.namespace.QName;
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.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.BeforeClass;
import org.springframework.test.context.ActiveProfiles;
// JUnit dependencies
/**
*
* @author Guilhem Legal (Geomatys)
*/
@RunWith(SpringTestRunner.class)
@ContextConfiguration("classpath:/cstl/spring/test-context.xml")
@ActiveProfiles({"standard"})
public class CSWRequestTest extends AbstractGrizzlyServer implements ApplicationContextAware {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger("org.constellation.ws.embedded");
protected ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Inject
private IServiceBusiness serviceBusiness;
private static boolean initialized = false;
private static File configDirectory;
@BeforeClass
public static void initTestDir() {
configDirectory = ConfigDirectory.setupTestEnvironement("CSWRequestTest");
}
/**
* Initialize the list of layers from the defined providers in Constellation's configuration.
*/
@PostConstruct
public void initPool() {
SpringHelper.setApplicationContext(applicationContext);
if (!initialized) {
try {
//clean services
try {
serviceBusiness.deleteAll();
} catch (Exception ex) {
LOGGER.warn(ex.getMessage());
}
final File dataDirectory2 = new File(configDirectory, "dataCsw2");
dataDirectory2.mkdir();
writeDataFile(dataDirectory2, "urn-uuid-e8df05c2-d923-4a05-acce-2b20a27c0e58");
final Automatic config2 = new Automatic("filesystem", dataDirectory2.getPath());
config2.putParameter("shiroAccessible", "false");
config2.putParameter("CSWCascading", "http://localhost:9090/csw/default");
serviceBusiness.create("csw", "csw2", config2, null);
final File dataDirectory = new File(configDirectory, "dataCsw");
dataDirectory.mkdir();
writeDataFile(dataDirectory, "urn-uuid-19887a8a-f6b0-4a63-ae56-7fba0e17801f");
writeDataFile(dataDirectory, "urn-uuid-1ef30a8b-876d-4828-9246-c37ab4510bbd");
writeDataFile(dataDirectory, "urn-uuid-66ae76b7-54ba-489b-a582-0f0633d96493");
writeDataFile(dataDirectory, "urn-uuid-6a3de50b-fa66-4b58-a0e6-ca146fdd18d4");
writeDataFile(dataDirectory, "urn-uuid-784e2afd-a9fd-44a6-9a92-a3848371c8ec");
writeDataFile(dataDirectory, "urn-uuid-829babb0-b2f1-49e1-8cd5-7b489fe71a1e");
writeDataFile(dataDirectory, "urn-uuid-88247b56-4cbc-4df9-9860-db3f8042e357");
writeDataFile(dataDirectory, "urn-uuid-94bc9c83-97f6-4b40-9eb8-a8e8787a5c63");
writeDataFile(dataDirectory, "urn-uuid-9a669547-b69b-469f-a11f-2d875366bbdc");
writeDataFile(dataDirectory, "urn-uuid-e9330592-0932-474b-be34-c3a3bb67c7db");
final File subDataDirectory = new File(dataDirectory, "sub1");
subDataDirectory.mkdir();
writeDataFile(subDataDirectory, "urn-uuid-ab42a8c4-95e8-4630-bf79-33e59241605a");
final File subDataDirectory2 = new File(dataDirectory, "sub2");
subDataDirectory2.mkdir();
writeDataFile(subDataDirectory2, "urn-uuid-a06af396-3105-442d-8b40-22b57a90d2f2");
final Automatic config = new Automatic("filesystem", dataDirectory.getPath());
config.putParameter("shiroAccessible", "false");
serviceBusiness.create("csw", "default", config, null);
final Map<String, Object> map = new HashMap<>();
map.put("sos", new SOService());
initServer(null, map);
// Get the list of layers
pool = EBRIMMarshallerPool.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("CSWRequestTest");
finish();
}
private static String getDefaultURL() {
return "http://localhost:" + grizzly.getCurrentPort() + "/csw/default?";
}
private static String getCsw2URL() {
return "http://localhost:" + grizzly.getCurrentPort() + "/csw/csw2?";
}
@Test
@Order(order=1)
public void testCSWGetCapabilities() throws Exception {
waitForStart();
//update the federated catalog in case of busy port
URL fedCatURL = new URL("http://localhost:" + grizzly.getCurrentPort() + "/1/CSW/csw2/federatedCatalog");
URLConnection conec = fedCatURL.openConnection();
postRequestObject(conec, new StringList(Arrays.asList(getDefaultURL())), GenericDatabaseMarshallerPool.getInstance());
// Creates a valid GetCapabilities url.
URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
conec = getCapsUrl.openConnection();
final GetCapabilitiesType request = new GetCapabilitiesType("CSW");
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
assertTrue(obj instanceof Capabilities);
Capabilities c = (Capabilities) obj;
assertTrue(c.getOperationsMetadata() != null);
Operation op = c.getOperationsMetadata().getOperation("GetRecords");
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(getDefaultURL() + "request=GetCapabilities&service=CSW&version=2.0.2");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
assertTrue(obj instanceof Capabilities);
Capabilities capa = (Capabilities) obj;
String currentURL = capa.getOperationsMetadata().getOperation("getRecords").getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref();
assertEquals(getDefaultURL(), currentURL);
// Creates a valid GetCapabilties url.
getCapsUrl = new URL(getCsw2URL() + "request=GetCapabilities&service=CSW&version=2.0.2");
obj = unmarshallResponse(getCapsUrl);
assertTrue(obj instanceof Capabilities);
capa = (Capabilities) obj;
currentURL = capa.getOperationsMetadata().getOperation("getRecords").getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref();
assertEquals(getCsw2URL(), currentURL);
// Creates a valid GetCapabilties url.
getCapsUrl = new URL(getDefaultURL() + "request=GetCapabilities&service=CSW&version=2.0.2");
obj = unmarshallResponse(getCapsUrl);
assertTrue(obj instanceof Capabilities);
capa = (Capabilities) obj;
currentURL = capa.getOperationsMetadata().getOperation("getRecords").getDCP().get(0).getHTTP().getGetOrPost().get(0).getHref();
assertEquals(getDefaultURL(), currentURL);
}
@Test
@Order(order=2)
public void testCSWError() throws Exception {
// Creates a valid GetCapabilities url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
final GetCapabilitiesType request = new GetCapabilitiesType("SOS");
postRequestObject(conec, request);
Object obj = unmarshallResponse(conec);
assertTrue(obj instanceof ExceptionReport);
ExceptionReport result = (ExceptionReport) obj;
assertEquals("InvalidParameterValue", result.getException().get(0).getExceptionCode());
}
@Test
@Order(order=3)
public void testCSWGetDomain() throws Exception {
// Creates a valid GetCapabilities url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
GetDomainType request = new GetDomainType("CSW", "2.0.2", null, "GetCapabilities.sections");
postRequestObject(conec, request);
Object result = unmarshallResponse(conec);
assertTrue(result instanceof GetDomainResponseType);
List<DomainValues> values = new ArrayList<>();
ListOfValuesType list = new ListOfValuesType(Arrays.asList("All", "ServiceIdentification", "ServiceProvider", "OperationsMetadata","Filter_Capabilities"));
values.add(new DomainValuesType("GetCapabilities.sections", null, list, new QName("http://www.opengis.net/cat/csw/2.0.2", "Capabilities")));
GetDomainResponseType expResult = new GetDomainResponseType(values);
assertEquals(expResult, result);
request = new GetDomainType("CSW", "2.0.2", "title", null);
conec = getCapsUrl.openConnection();
postRequestObject(conec, request);
result = unmarshallResponse(conec);
assertTrue(result instanceof GetDomainResponseType);
values = new ArrayList<>();
list = new ListOfValuesType(Arrays.asList("Aliquam fermentum purus quis arcu","Fuscé vitae ligulä","Lorem ipsum","Lorem ipsum dolor sit amet",
"Maecenas enim","Mauris sed neque","Ut facilisis justo ut lacus","Vestibulum massa purus","Ñunç elementum"));
values.add(new DomainValuesType(null, "title", list, new QName("http://www.isotc211.org/2005/gmd", "MD_Metadata")));
expResult = new GetDomainResponseType(values);
assertEquals(expResult, result);
}
@Test
@Order(order=4)
public void testCSWGetRecordByID() throws Exception {
// Creates a valid GetCapabilities url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
GetRecordByIdType request = new GetRecordByIdType("CSW", "2.0.2", new ElementSetNameType(ElementSetType.FULL),
"text/xml", null, Arrays.asList("urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"));
final ObjectFactory factory = new ObjectFactory();
postRequestObject(conec, factory.createGetRecordById(request));
Object result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordByIdResponseType);
GetRecordByIdResponseType grResult = (GetRecordByIdResponseType) result;
assertEquals(1, grResult.getAny().size());
request = new GetRecordByIdType("CSW", "2.0.2", new ElementSetNameType(ElementSetType.FULL),
"text/xml", null, Arrays.asList("urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a"));
conec = getCapsUrl.openConnection();
postRequestObject(conec, factory.createGetRecordById(request));
result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordByIdResponseType);
grResult = (GetRecordByIdResponseType) result;
assertEquals(1, grResult.getAny().size());
}
@Test
@Order(order=5)
public void testCSWGetRecords() throws Exception {
// Creates a valid GetCapabilities url.
final URL getCapsUrl = new URL(getDefaultURL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
QueryConstraintType constraint = new QueryConstraintType("identifier='urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f'", "1.1.0");
QueryType query = new QueryType(Arrays.asList(TypeNames.RECORD_QNAME), new ElementSetNameType(ElementSetType.FULL), null, constraint);
GetRecordsType request = new GetRecordsType("CSW", "2.0.2", ResultType.RESULTS, null, null, null, 1, 10, query, null);
postRequestObject(conec, request);
Object result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordsResponseType);
GetRecordsResponseType grResult = (GetRecordsResponseType) result;
assertEquals(1, grResult.getSearchResults().getAny().size());
/**
* get all the records
*/
conec = getCapsUrl.openConnection();
constraint = new QueryConstraintType("identifier like '%%'", "1.1.0");
query = new QueryType(Arrays.asList(TypeNames.RECORD_QNAME), new ElementSetNameType(ElementSetType.FULL), null, constraint);
request = new GetRecordsType("CSW", "2.0.2", ResultType.RESULTS, null, null, null, 1, 20, query, null);
postRequestObject(conec, request);
result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordsResponseType);
grResult = (GetRecordsResponseType) result;
assertEquals(12, grResult.getSearchResults().getAny().size());
}
@Test
@Order(order=6)
public void testDistributedCSWGetRecords() throws Exception {
System.out.println("\n\n DISTIBUTED SEARCH \n\n");
// Creates a valid GetCapabilities url.
final URL getCapsUrl = new URL(getCsw2URL());
// for a POST request
URLConnection conec = getCapsUrl.openConnection();
QueryConstraintType constraint = new QueryConstraintType("identifier like '%%'", "1.1.0");
QueryType query = new QueryType(Arrays.asList(TypeNames.RECORD_QNAME), new ElementSetNameType(ElementSetType.FULL), null, constraint);
DistributedSearchType dist = new DistributedSearchType(1);
GetRecordsType request = new GetRecordsType("CSW", "2.0.2", ResultType.RESULTS, null, null, null, 1, 20, query, dist);
postRequestObject(conec, request);
Object result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordsResponseType);
GetRecordsResponseType grResult = (GetRecordsResponseType) result;
assertEquals(13, grResult.getSearchResults().getAny().size());
// no distribution
conec = getCapsUrl.openConnection();
constraint = new QueryConstraintType("identifier like '%%'", "1.1.0");
query = new QueryType(Arrays.asList(TypeNames.RECORD_QNAME), new ElementSetNameType(ElementSetType.FULL), null, constraint);
request = new GetRecordsType("CSW", "2.0.2", ResultType.RESULTS, null, null, null, 1, 20, query, null);
postRequestObject(conec, request);
result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordsResponseType);
grResult = (GetRecordsResponseType) result;
assertEquals(1, grResult.getSearchResults().getAny().size());
// distribution with 0 hopcount
conec = getCapsUrl.openConnection();
constraint = new QueryConstraintType("identifier like '%%'", "1.1.0");
query = new QueryType(Arrays.asList(TypeNames.RECORD_QNAME), new ElementSetNameType(ElementSetType.FULL), null, constraint);
dist = new DistributedSearchType(0);
request = new GetRecordsType("CSW", "2.0.2", ResultType.RESULTS, null, null, null, 1, 20, query, dist);
postRequestObject(conec, request);
result = unmarshallResponse(conec);
assertTrue(result instanceof GetRecordsResponseType);
grResult = (GetRecordsResponseType) result;
assertEquals(1, grResult.getSearchResults().getAny().size());
}
@Test
@Order(order=7)
public void testDescribeRecords() throws Exception {
/**
* Dublin core
*/
URL getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2&typename=csw:Record");
// Try to marshall something from the response returned by the server.
Object obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj.getClass(), obj instanceof DescribeRecordResponseType);
DescribeRecordResponseType result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 1);
assertEquals(result.getSchemaComponent().get(0).getTargetNamespace(), "http://www.opengis.net/cat/csw/2.0.2");
getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2&typename=csw:Record&namespace=xmlns(csw=http://www.opengis.net/cat/csw/2.0.2)");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj.getClass(), obj instanceof DescribeRecordResponseType);
result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 1);
assertEquals(result.getSchemaComponent().get(0).getTargetNamespace(), "http://www.opengis.net/cat/csw/2.0.2");
getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2&typename=csw:Record&namespace=xmlns(csw=http://www.opengis.net/cat/csw/3.8)");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj.getClass(), obj instanceof DescribeRecordResponseType);
result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 0);
/**
* GMD
*/
getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2&typename=gmd:MD_Metadata");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj.getClass(), obj instanceof DescribeRecordResponseType);
result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 1);
assertEquals(result.getSchemaComponent().get(0).getTargetNamespace(), "http://www.isotc211.org/2005/gmd");
getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2&typename=gmd:MD_Metadata&namespace=xmlns(gmd=http://www.isotc211.org/2005/gmd)");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj.getClass(), obj instanceof DescribeRecordResponseType);
result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 1);
assertEquals(result.getSchemaComponent().get(0).getTargetNamespace(), "http://www.isotc211.org/2005/gmd");
getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2&typename=gmd:MD_Metadata&namespace=xmlns(gmd=http://www.isotc211.org/2005/wrong)");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
assertTrue("was:" + obj.getClass(), obj instanceof DescribeRecordResponseType);
result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 0);
/**
* ALL
*/
getCapsUrl = new URL(getDefaultURL() + "service=CSW&request=DescribeRecord&version=2.0.2");
// Try to marshall something from the response returned by the server.
obj = unmarshallResponse(getCapsUrl);
result = (DescribeRecordResponseType) obj;
assertEquals(result.getSchemaComponent().size(), 4);
assertEquals(result.getSchemaComponent().get(0).getTargetNamespace(), "http://www.opengis.net/cat/csw/2.0.2");
assertEquals(result.getSchemaComponent().get(1).getTargetNamespace(), "http://www.isotc211.org/2005/gmd");
assertEquals(result.getSchemaComponent().get(2).getTargetNamespace(), "urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0");
assertEquals(result.getSchemaComponent().get(3).getTargetNamespace(), "urn:oasis:names:tc:ebxml-regrep:rim:xsd:2.5");
}
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();
}
}