/* * 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.coverage.ws; import org.constellation.configuration.ConfigurationException; import org.constellation.test.utils.SpringTestRunner; import org.constellation.ws.CstlServiceException; import org.constellation.ws.MimeType; import org.geotoolkit.gml.xml.v311.DirectPositionType; import org.geotoolkit.gml.xml.v311.EnvelopeType; import org.geotoolkit.gml.xml.v311.GridLimitsType; import org.geotoolkit.gml.xml.v311.GridType; import org.geotoolkit.gml.xml.v311.TimePositionType; import org.geotoolkit.wcs.xml.DescribeCoverage; import org.geotoolkit.wcs.xml.DescribeCoverageResponse; import org.geotoolkit.wcs.xml.GetCapabilities; import org.geotoolkit.wcs.xml.GetCapabilitiesResponse; import org.geotoolkit.wcs.xml.GetCoverage; import org.geotoolkit.wcs.xml.v100.CoverageDescription; import org.geotoolkit.wcs.xml.v100.CoverageOfferingBriefType; import org.geotoolkit.wcs.xml.v100.CoverageOfferingType; import org.geotoolkit.wcs.xml.v100.DescribeCoverageType; import org.geotoolkit.wcs.xml.v100.DomainSubsetType; import org.geotoolkit.wcs.xml.v100.GetCapabilitiesType; import org.geotoolkit.wcs.xml.v100.GetCoverageType; import org.geotoolkit.wcs.xml.v100.OutputType; import org.geotoolkit.wcs.xml.v100.SpatialDomainType; import org.geotoolkit.wcs.xml.v100.SpatialSubsetType; import org.geotoolkit.wcs.xml.v100.TimeSequenceType; import org.geotoolkit.wcs.xml.v100.WCSCapabilitiesType; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import java.awt.image.RenderedImage; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.imageio.ImageIO; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.spi.ImageWriterSpi; import javax.inject.Inject; import javax.xml.namespace.QName; import org.apache.sis.util.logging.Logging; import org.constellation.admin.SpringHelper; import org.constellation.api.ProviderType; import org.constellation.business.IDataBusiness; import org.constellation.business.ILayerBusiness; import org.constellation.business.IProviderBusiness; import org.constellation.business.IServiceBusiness; import org.constellation.configuration.ConfigDirectory; import org.constellation.configuration.LayerContext; import org.constellation.provider.DataProviders; import org.constellation.provider.ProviderFactory; import static org.constellation.provider.coveragesql.CoverageSQLProviderService.NAMESPACE_DESCRIPTOR; import org.constellation.ws.embedded.AbstractGrizzlyServer; import org.geotoolkit.image.io.plugin.WorldFileImageReader; import org.geotoolkit.image.jai.Registry; import static org.geotoolkit.utility.parameter.ParametersExt.getOrCreateGroup; import static org.geotoolkit.utility.parameter.ParametersExt.getOrCreateValue; import org.junit.AfterClass; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.BeforeClass; import org.opengis.parameter.ParameterValueGroup; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.test.context.ActiveProfiles; /** * Testing class for WCS requests. * * @version $Id$ * @author Cédric Briançon (Geomatys) * * @since 0.5 */ @RunWith(SpringTestRunner.class) @ContextConfiguration("classpath:/cstl/spring/test-context.xml") @ActiveProfiles({"standard"}) public class WCSWorkerOutputTest implements ApplicationContextAware { private static final Logger LOGGER = Logging.getLogger("org.constellation.coverage.ws"); private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * The layer to test. */ private static final String LAYER_TEST = "SSTMDE200305"; private static WCSWorker WORKER; @Inject private IServiceBusiness serviceBusiness; @Inject private ILayerBusiness layerBusiness; @Inject private IProviderBusiness providerBusiness; @Inject private IDataBusiness dataBusiness; private static boolean initialized = false; @BeforeClass public static void initTestDir() { ConfigDirectory.setupTestEnvironement("WCSWorkerOutputTest"); } /** * Initialisation of the worker and the PostGRID data provider before launching * the different tests. */ @PostConstruct public void setUpClass() { SpringHelper.setApplicationContext(applicationContext); if (!initialized) { try { layerBusiness.removeAll(); serviceBusiness.deleteAll(); dataBusiness.deleteAll(); providerBusiness.removeAll(); // coverage-sql datastore final File rootDir = AbstractGrizzlyServer.initDataDirectory(); final ProviderFactory covFilefactory = DataProviders.getInstance().getFactory("coverage-store"); final ParameterValueGroup sourceCF = covFilefactory.getProviderDescriptor().createValue(); getOrCreateValue(sourceCF, "id").setValue("coverageTestSrc"); getOrCreateValue(sourceCF, "load_all").setValue(true); final ParameterValueGroup choice3 = getOrCreateGroup(sourceCF, "choice"); final ParameterValueGroup srcCFConfig = getOrCreateGroup(choice3, "FileCoverageStoreParameters"); getOrCreateValue(srcCFConfig, "path").setValue(new URL("file:" + rootDir.getAbsolutePath() + "/org/constellation/data/SSTMDE200305.png")); getOrCreateValue(srcCFConfig, "type").setValue("AUTO"); getOrCreateValue(srcCFConfig, NAMESPACE_DESCRIPTOR.getName().getCode()).setValue("no namespace"); providerBusiness.storeProvider("coverageTestSrc", null, ProviderType.LAYER, "coverage-store", sourceCF); dataBusiness.create(new QName("SSTMDE200305"), "coverageTestSrc", "COVERAGE", false, true, null, null); final LayerContext config = new LayerContext(); config.getCustomParameters().put("shiroAccessible", "false"); serviceBusiness.create("wcs", "default", config, null); layerBusiness.add("SSTMDE200305", null, "coverageTestSrc", null, "default", "wcs", null); serviceBusiness.create("wcs", "test", config, null); layerBusiness.add("SSTMDE200305", null, "coverageTestSrc", null, "test", "wcs", null); DataProviders.getInstance().reload(); WORKER = new DefaultWCSWorker("default"); // Default instanciation of the worker' servlet context and uri context. WORKER.setServiceUrl("http://localhost:9090"); initialized = true; WorldFileImageReader.Spi.registerDefaults(null); //reset values, only allow pure java readers for(String jn : ImageIO.getReaderFormatNames()){ Registry.setNativeCodecAllowed(jn, ImageReaderSpi.class, false); } //reset values, only allow pure java writers for(String jn : ImageIO.getWriterFormatNames()){ Registry.setNativeCodecAllowed(jn, ImageWriterSpi.class, false); } } catch (Exception ex) { LOGGER.log(Level.SEVERE, null, ex); } } } @AfterClass public static void tearDownClass() throws Exception { try { final ILayerBusiness layerBean = SpringHelper.getBean(ILayerBusiness.class); if (layerBean != null) { layerBean.removeAll(); } final IServiceBusiness service = SpringHelper.getBean(IServiceBusiness.class); if (service != null) { service.deleteAll(); } final IDataBusiness dataBean = SpringHelper.getBean(IDataBusiness.class); if (dataBean != null) { dataBean.deleteAll(); } final IProviderBusiness provider = SpringHelper.getBean(IProviderBusiness.class); if (provider != null) { provider.removeAll(); } } catch (ConfigurationException ex) { Logger.getAnonymousLogger().log(Level.WARNING, ex.getMessage()); } ConfigDirectory.shutdownTestEnvironement("WCSWorkerOutputTest"); File derbyLog = new File("derby.log"); if (derbyLog.exists()) { derbyLog.delete(); } } /** * Ensures that a PostGRID layer preconfigured is found in the GetCapabilities document * returned by the {@link WCSWorker}. * * @throws JAXBException * @throws CstlServiceException */ @Test public void testGetCapabilities() throws JAXBException, CstlServiceException { GetCapabilities request = new GetCapabilitiesType("1.0.0", "WCS", null, null); GetCapabilitiesResponse response = WORKER.getCapabilities(request); assertNotNull(response); assertTrue(response instanceof WCSCapabilitiesType); WCSCapabilitiesType getCaps = (WCSCapabilitiesType) response; // Verifies that the test layer is present into the GetCapabilities response. boolean find = false; final List<CoverageOfferingBriefType> offerings = getCaps.getContentMetadata().getCoverageOfferingBrief(); assertFalse(offerings.isEmpty()); for (CoverageOfferingBriefType offering : offerings) { for (JAXBElement<String> string : offering.getRest()) { if (string.getName().getLocalPart().equalsIgnoreCase("name") && string.getValue().equals(LAYER_TEST)) { find = true; } } } // Not found in the list of coverage offerings, there is a mistake here. if (!find) { fail("Unable to find the layer "+ LAYER_TEST +" in the GetCapabilities document."); } request = new GetCapabilitiesType("1.0.0", "WCS", "/WCS_Capabilities/Capability", null); getCaps = (WCSCapabilitiesType) WORKER.getCapabilities(request); assertNotNull(getCaps.getCapability()); assertNull(getCaps.getContentMetadata()); assertNull(getCaps.getService()); request = new GetCapabilitiesType("1.0.0", "WCS", "/WCS_Capabilities/Service", null); getCaps = (WCSCapabilitiesType) WORKER.getCapabilities(request); assertNull(getCaps.getCapability()); assertNull(getCaps.getContentMetadata()); assertNotNull(getCaps.getService()); request = new GetCapabilitiesType("1.0.0", "WCS", "/WCS_Capabilities/ContentMetadata", null); getCaps = (WCSCapabilitiesType) WORKER.getCapabilities(request); assertNull(getCaps.getCapability()); assertNotNull(getCaps.getContentMetadata()); assertNull(getCaps.getService()); } /** * Ensures that a PostGRID layer preconfigured can be requested with a DescribeCoverage request, * and that the output document contains all data information. * * @throws JAXBException * @throws CstlServiceException */ @Test public void testDescribeCoverage() throws JAXBException, CstlServiceException { final DescribeCoverage request = new DescribeCoverageType(LAYER_TEST); final DescribeCoverageResponse response = WORKER.describeCoverage(request); assertNotNull(response); assertTrue(response instanceof CoverageDescription); final CoverageDescription descCov = (CoverageDescription) response; // Verifies that the test layer is present into the DescribeCoverage response. for (CoverageOfferingType offering : descCov.getCoverageOffering()) { for (JAXBElement<String> string : offering.getRest()) { if (string.getName().getLocalPart().equalsIgnoreCase("name") && string.getValue().equals(LAYER_TEST)) { final SpatialDomainType spatialDomain = (SpatialDomainType) offering.getDomainSet() .getContent().get(0).getValue(); final TimeSequenceType temporalDomain = (TimeSequenceType) offering.getDomainSet() .getContent().get(1).getValue(); // Builds expected spatial domain final List<DirectPositionType> pos = new ArrayList<>(); pos.add(new DirectPositionType(-180.0, -90.0)); pos.add(new DirectPositionType(180.0, 90.0)); final EnvelopeType expectedEnvelope = new EnvelopeType(pos, "urn:ogc:def:crs:EPSG::4326"); // Builds expected temporal domain final List<TimePositionType> expectedTimes = Collections.singletonList(new TimePositionType("2003-05-16T00:00:00Z")); // Do assertions assertEquals(expectedEnvelope, spatialDomain.getEnvelope()); // assertEquals(expectedTimes, temporalDomain.getTimePositionOrTimePeriod()); /* * All tests have succeed on that specific layer, we can now stop this test. */ return; } } } fail("Unable to find the layer "+ LAYER_TEST +" in the DescribeCoverage document."); } /** * Ensures that a PostGRID layer preconfigured can be requested with a GetCoverage request. * * TODO: do a checksum on the output image. * * @throws JAXBException * @throws CstlServiceException */ @Test public void testGetCoverage() throws JAXBException, CstlServiceException { // Builds the GetCoverage request final List<String> axis = new ArrayList<>(); axis.add("width"); axis.add("height"); final int[] low = new int[2]; low[0] = 0; low[1] = 0; final int[] high = new int[2]; high[0] = 1024; high[1] = 512; final GridLimitsType limits = new GridLimitsType(low, high); final GridType grid = new GridType(limits, axis); final List<DirectPositionType> pos = new ArrayList<>(); pos.add(new DirectPositionType(-180.0, -90.0)); pos.add(new DirectPositionType(180.0, 90.0)); final EnvelopeType envelope = new EnvelopeType(pos, "CRS:84"); final DomainSubsetType domain = new DomainSubsetType(null, new SpatialSubsetType(envelope, grid)); GetCoverage request = new GetCoverageType(LAYER_TEST, domain, null, null, new OutputType(MimeType.IMAGE_PNG, "CRS:84")); // Finally execute the request on the worker. final RenderedImage image = (RenderedImage) WORKER.getCoverage(request); // Test on the returned image. assertEquals(image.getWidth(), 1024); assertEquals(image.getHeight(), 512); // Test the checksum of the image, if the image is indexed (and its values of type byte). // TODO: the image should have indexed colors. Find the origin of the conversion from // indexed color to RGB (int values). // assertEquals(Commons.checksum(image), 3183786073L); request = new GetCoverageType(LAYER_TEST, domain, null, "WCS_INTERPLATION_METHOD_INVALID", new OutputType(MimeType.IMAGE_PNG, "CRS:84")); boolean exLaunched = false; try { WORKER.getCoverage(request); } catch (CstlServiceException ex) { exLaunched = true; } assertTrue(exLaunched); } }