/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2013-2016 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.client; import java.io.IOException; import java.util.List; import java.util.Map; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; import javax.xml.bind.JAXBElement; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; import org.constellation.ServiceDef; import org.constellation.configuration.AbstractConfigurationObject; import org.constellation.configuration.Instance; import org.constellation.configuration.InstanceReport; import org.constellation.configuration.LayerContext; import org.constellation.configuration.ProcessContext; import org.constellation.configuration.SOSConfiguration; import org.constellation.configuration.ServiceReport; import org.constellation.configuration.WebdavContext; import org.constellation.dto.Details; import org.constellation.dto.SimpleValue; import org.constellation.generic.database.Automatic; /** * */ public class ServicesAPI { /** * Client used to communicate with the Constellation server. */ private final ConstellationClient client; /** * * @param client the client to use */ ServicesAPI(final ConstellationClient client) { this.client = client; } /** * Return a complete URL for the specified service (wms, wfs, csw,...) and * instance identifier. * * @param service The service name (wms, wfs, csw,...). * @param instanceId The instance identifier. * @return A complete URL for the specified service. */ public String getInstanceURL(final String service, final String instanceId) { return client.getUrl() + service.toLowerCase() + '/' + instanceId; } /** * path : /1/OGC/{spec}/{id}/start<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.start<br> * <br> * Starts a service instance. * * @param serviceType the service type * @param identifier the service identifier * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void start(final ServiceDef.Specification serviceType, final String identifier) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier + "/start"; client.post(path, MediaType.APPLICATION_XML_TYPE, "").ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}/{lang}<br> * method : GET<br> * java : org.constellation.rest.api.OGCServicesRest.getInstance<br> */ public void getInstance(){ throw new UnsupportedOperationException("Not supported yet"); } /** * path : /1/OGC/{spec}/{id}<br> * method : GET<br> * java : org.constellation.rest.api.OGCServicesRest.getInstance<br> * <br> * Queries a service instance. * * @param serviceType the service type * @param identifier the service identifier * @return a {@link Instance} instance * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws java.io.IOException on HTTP communication error or response entity parsing error */ public Instance getInstance(final ServiceDef.Specification serviceType, final String identifier) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); GenericType<JAXBElement<Instance>> planetType = new GenericType<JAXBElement<Instance>>() { }; final String path = "api/1/OGC/" + serviceType + "/" + identifier; return client.getWebTarget().path(path).request().accept(MediaType.APPLICATION_XML_TYPE).get(planetType).getValue(); } /** * path : /1/OGC/{spec}/{id}/stop<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.stop<br> * <br> * Stops a service instance. * * @param serviceType the service type * @param identifier the service identifier * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void stop(final ServiceDef.Specification serviceType, final String identifier) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier + "/stop"; client.post(path, MediaType.APPLICATION_XML_TYPE, null).ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}<br> * method : DELETE<br> * java : org.constellation.rest.api.OGCServicesRest.delete<br> * <br> * Deletes a service instance. * * @param serviceType the service type * @param identifier the service identifier * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void delete(final ServiceDef.Specification serviceType, final String identifier) throws IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier; client.delete(path, MediaType.APPLICATION_XML_TYPE).ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}/rename<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.rename<br> * <br> * Renames a service instance. * * @param serviceType the service type * @param identifier the service identifier * @param newIdentifier the new service identifier * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void rename(final ServiceDef.Specification serviceType, final String identifier, final String newIdentifier) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier + "/rename"; client.post(path, MediaType.APPLICATION_XML_TYPE, new SimpleValue(newIdentifier)).ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}/config<br> * method : GET<br> * java : org.constellation.rest.api.OGCServicesRest.getConfiguration<br> * <br> * Queries a service instance configuration. * * @param serviceType the service type * @param identifier the service identifier * @return the instance configuration for this service. * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws java.io.IOException on HTTP communication error or response entity parsing error */ public Object getConfiguration(final ServiceDef.Specification serviceType, final String identifier) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier + "/config"; final Class classBinding; if (ServiceDef.Specification.CSW.equals(serviceType)) { classBinding = Automatic.class; } else if (ServiceDef.Specification.WMS.equals(serviceType) || ServiceDef.Specification.WMTS.equals(serviceType) || ServiceDef.Specification.WFS.equals(serviceType) || ServiceDef.Specification.WCS.equals(serviceType)) { classBinding = LayerContext.class; } else if (ServiceDef.Specification.WPS.equals(serviceType)) { classBinding = ProcessContext.class; } else if (ServiceDef.Specification.SOS.equals(serviceType)) { classBinding = SOSConfiguration.class; } else if (ServiceDef.Specification.WEBDAV.equals(serviceType)) { classBinding = WebdavContext.class; } else { throw new IOException("Invalid specification chosen to get instance configuration "+ serviceType); } return client.get(path, MediaType.APPLICATION_XML_TYPE).getEntity(classBinding); } /** * path : /1/OGC/{spec}/all<br> * method : GET<br> * java : org.constellation.rest.api.OGCServicesRest.getInstances<br> * <br> * Queries the list of created services matching with the specified type * (even if not running). * * @param serviceType the service type * @return an {@link InstanceReport} instance * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error or response entity parsing error */ public InstanceReport getInstances(final ServiceDef.Specification serviceType) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); final String path = "OGC/" + serviceType + "/all"; return client.get(path, MediaType.APPLICATION_XML_TYPE).getEntity(InstanceReport.class); } /** * path : /1/OGC/{spec}/{id}/restart<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.restart<br> * <br> * Restarts a service instance. * * @param serviceType the service type * @param identifier the service identifier * @param stopFirst the restart options * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void restart(final ServiceDef.Specification serviceType, final String identifier, final Boolean stopFirst) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier + "/restart"; client.post(path, MediaType.APPLICATION_XML_TYPE, new SimpleValue(stopFirst)).ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}/config<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.setConfiguration<br> * <br> * Sets the service configuration.. * * @param serviceType the service type * @param identifier the service identifier * @param config configuration object for the service * * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws java.io.IOException on HTTP communication error or response entity parsing error */ public void setConfiguration(final ServiceDef.Specification serviceType, final String identifier, final AbstractConfigurationObject config) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); ensureNonNull("config", config); final String path = "OGC/" + serviceType + "/" + identifier + "/config"; client.post(path, MediaType.APPLICATION_XML_TYPE, config).ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}/config<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.setConfigurationJson<br> */ public void setConfigurationJson(){ throw new UnsupportedOperationException("Not supported yet"); } /** * path : /1/OGC/{spec}/list<br> * method : GET<br> * java : org.constellation.rest.api.OGCServicesRest.listService<br> */ public void listService(){ throw new UnsupportedOperationException("Not supported yet"); } public Map<String, List<String>> listAllServices() throws IOException { final String path = "OGC/whatever/list"; return client.get(path, MediaType.APPLICATION_XML_TYPE).getEntity(ServiceReport.class).getAvailableServices(); } /** * path : /1/OGC/{spec}/domain/{domainId}<br> * method : PUT<br> * java : org.constellation.rest.api.OGCServicesRest.addInstance<br> * <br> * Create a new service instance. * * @param serviceType the service type * @param metadata the service metadata * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void addInstance(final ServiceDef.Specification serviceType, final Details metadata) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("metadata", metadata); final String domain = "0";// TODO final String path = "OGC/" + serviceType + "/domain/" + domain; client.put(path, MediaType.APPLICATION_XML_TYPE, metadata).ensure2xxStatus(); } /** * path : /1/OGC/{spec}/{id}/metadata/{lang}<br> * method : GET<br> * java : org.constellation.rest.api.OGCServicesRest.getDetails<br> * <br> * Queries a service instance metadata. * * @param serviceType the service type * @param identifier the service identifier * @return a {@link org.constellation.dto.Details} instance * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error or response entity parsing error */ public Details getMetadata(final ServiceDef.Specification serviceType, final String identifier) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("identifier", identifier); final String path = "OGC/" + serviceType + "/" + identifier + "/metadata"; return client.get(path, MediaType.APPLICATION_XML_TYPE).getEntity(Details.class); } /** * path : /1/OGC/{spec}/{id}/metadata<br> * method : POST<br> * java : org.constellation.rest.api.OGCServicesRest.setDetails<br> * <br> * Updates a service instance metadata. * * @param serviceType the service type * @param identifier the service identifier * @param metadata the service metadata * @throws HttpResponseException if the response does not have a {@code 2xx} status code * @throws IOException on HTTP communication error */ public void setDetails(final ServiceDef.Specification serviceType, final String identifier, final Details metadata) throws HttpResponseException, IOException { ensureNonNull("serviceType", serviceType); ensureNonNull("metadata", metadata); final String path = "OGC/" + serviceType + "/" + identifier + "/metadata"; client.post(path, MediaType.APPLICATION_XML_TYPE, metadata).ensure2xxStatus(); } }