diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java index 3804042..cd26a99 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java +++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java @@ -29,14 +29,8 @@ import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore; import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList; import it.geosolutions.geoserver.rest.decoder.RESTStyleList; import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem; -import it.geosolutions.geoserver.rest.encoder.GSBackupEncoder; -import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder; -import it.geosolutions.geoserver.rest.encoder.GSLayerGroupEncoder; -import it.geosolutions.geoserver.rest.encoder.GSNamespaceEncoder; -import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder; -import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder; +import it.geosolutions.geoserver.rest.encoder.*; import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy; -import it.geosolutions.geoserver.rest.encoder.GSWorkspaceEncoder; import it.geosolutions.geoserver.rest.encoder.coverage.GSCoverageEncoder; import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder; import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredGridCoverageReaderManager; @@ -579,6 +573,7 @@ public class GeoServerRESTPublisher { * * * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it @@ -592,8 +587,11 @@ public class GeoServerRESTPublisher { * Vector based data sources. Can be a file in the case of a Shapefile, a database connection in the case of PostGIS, or a server in the case * of a remote Web Feature Service. */ - DATASTORES; - + DATASTORES, + /** + * Remote Web Map Service data source + */ + WMSSTORES; /** * Get the type name of a StoreType with the specified format. * @@ -628,6 +626,8 @@ public class GeoServerRESTPublisher { return "coverages"; // Format case DATASTORES: return "featureTypes"; + case WMSSTORES: + return "wmslayers"; default: return "coverages"; } @@ -645,6 +645,8 @@ public class GeoServerRESTPublisher { return "coverageStore"; // Format case DATASTORES: return "dataStore"; + case WMSSTORES: + return "wmsstores"; default: return "coverageStore"; } @@ -1020,6 +1022,66 @@ public class GeoServerRESTPublisher { return published && configured; } + /** + * Publish and configure a new layer from an existing WMS DataStore. + * + * @param workspace Workspace name where DataStore is. + * @param storename DataStore name. + * @param lte WMSLayer configuration details using a {@link GSWMSLayerEncoder}. + * @return {@code true} if layer is successfully created. + */ + public boolean publishWMSLayer(final String workspace, final String storename, + final GSWMSLayerEncoder lte, final GSLayerEncoder layerEncoder) { + /* + * This is the equivalent call with cUrl: + * + * {@code curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' \ -d + * "easia_gaul_1_aggrEPSG:4326true" \ + * http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/ wmsstores/pg_kids/wmslayers } + * + * and a PUT to
restURL + "/rest/layers/" workspace + : + layerName + */ + String ftypeXml = lte.toString(); + StringBuilder postUrl = new StringBuilder(restURL).append("/rest/workspaces/") + .append(workspace).append("/wmsstores/").append(storename).append("/wmslayers"); + + final String layername = lte.getName(); + if (layername == null || layername.isEmpty()) { + if (LOGGER.isErrorEnabled()) + LOGGER.error("GSWMSLayerEncoder has no valid name associated, try using GSWMSLayerEncoder.setName(String)"); + return false; + } + + String configuredResult = HTTPUtils.postXml(postUrl.toString(), ftypeXml, this.gsuser, + this.gspass); + boolean published = configuredResult != null; + boolean configured = false; + + if (!published) { + LOGGER.warn("Error in publishing (" + configuredResult + ") " + workspace + ":" + + storename + "/" + layername); + } else { + LOGGER.info("WMS layer successfully added (layer:" + layername + ")"); + + if (layerEncoder == null) { + if (LOGGER.isErrorEnabled()) + LOGGER.error("GSLayerEncoder is null: Unable to find the defaultStyle for this layer"); + return false; + } + + configured = configureLayer(workspace, layername, layerEncoder); + + if (!configured) { + LOGGER.warn("Error in configuring (" + configuredResult + ") " + workspace + ":" + + storename + "/" + layername); + } else { + LOGGER.info("WMS layer successfully configured (layer:" + layername + ")"); + } + } + + return published && configured; + } + // ========================================================================== // === SHAPEFILES // ========================================================================== @@ -2595,6 +2657,79 @@ public class GeoServerRESTPublisher { return sendResult != null; } + /** + * Configure an existing coverage in a given workspace and coverage store + * + * @param ce contains the coverage name to configure and the configuration to apply + * @param wsname the workspace to search for existent coverage + * @param csname the coverage store to search for existent coverage + * @return true if success + */ + public boolean configureWmsLayer(final GSCoverageEncoder ce, final String wsname, + final String wmsStoreName) { + return configureWmsLayer(ce, wsname, wmsStoreName, ce.getName()); + } + + private boolean configureWmsLayer(GSCoverageEncoder ce, String wsname, String wmsStoreName, String layerName) { + if (wsname == null) { + if (LOGGER.isErrorEnabled()) + LOGGER.error("Unable to configure a wmsstore with no name try using GSCoverageEncoder.setName(String)"); + return false; + } + // retrieve coverage name + GeoServerRESTReader reader; + try { + reader = new GeoServerRESTReader(restURL, gsuser, gspass); + } catch (MalformedURLException e) { + if (LOGGER.isErrorEnabled()) + LOGGER.error(e.getLocalizedMessage(), e); + return false; + } + + // optimized search, left the old code for reference + RESTCoverage coverage = reader.getCoverage(wsname, wmsStoreName, layerName); +// final RESTCoverageList covList = reader.getCoverages(wsname, csname); +// if (covList==null||covList.isEmpty()) { +// if (LOGGER.isErrorEnabled()) +// LOGGER.error("No coverages found in new coveragestore " + csname); +// return false; +// } +// final Iterator it = covList.iterator(); +// while (it.hasNext()) { +// NameLinkElem nameElem = it.next(); +// if (nameElem.getName().equals(coverageName)) { +// found = true; +// break; +// } +// } + // if no coverage to configure is found return false + if (coverage==null) { + if (LOGGER.isErrorEnabled()) + LOGGER.error("No layers found in new coveragestore " + wmsStoreName + " called " + + layerName); + return false; + } + + // configure the selected coverage + final String url = restURL + "/rest/workspaces/" + wsname + "/wmsstores/" + wmsStoreName + + "/wmslayers/" + layerName + ".xml"; + + final String xmlBody = ce.toString(); + final String sendResult = HTTPUtils.putXml(url, xmlBody, gsuser, gspass); + if (sendResult != null) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Wms layer successfully configured " + wsname + ":" + wmsStoreName + ":" + + layerName); + } + } else { + if (LOGGER.isWarnEnabled()) + LOGGER.warn("Error configuring coverage " + wsname + ":" + wmsStoreName + ":" + layerName + + " (" + sendResult + ")"); + } + + return sendResult != null; + } + /** * @deprecated use {@link #createCoverage(String, String, GSCoverageEncoder)} */ diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSWMSLayerEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSWMSLayerEncoder.java new file mode 100644 index 0000000..0b438e1 --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSWMSLayerEncoder.java @@ -0,0 +1,103 @@ +package it.geosolutions.geoserver.rest.encoder; + +import it.geosolutions.geoserver.rest.encoder.feature.FeatureTypeAttribute; +import it.geosolutions.geoserver.rest.encoder.feature.GSAttributeEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.GSFeatureDimensionInfoEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.GSVirtualTableEncoder; +import org.jdom.Element; + +/** + * Created by drakiko on 02/09/2015. + */ +public class GSWMSLayerEncoder extends GSResourceEncoder { + + public final static String ATTRIBUTES = "attributes"; + + final private Element attributes = new Element(ATTRIBUTES); + + public GSWMSLayerEncoder() { + super("wmsLayer"); + } + + + /** + * @deprecated Use {@link GSResourceEncoder#addMetadataDimension(String, GSDimensionInfoEncoder)} this method will be removed soon + * @param key + * @param dimensionInfo + * + */ + protected void addMetadata(String key, GSFeatureDimensionInfoEncoder dimensionInfo) { + super.addMetadata(key, dimensionInfo); + } + + + /** + * @deprecated Use {@link GSResourceEncoder#setMetadataDimension(String, GSDimensionInfoEncoder)} this method will be removed soon + * @param key + * @param dimensionInfo + * + */ + public void setMetadata(String key, GSFeatureDimensionInfoEncoder dimensionInfo) { + super.setMetadata(key, dimensionInfo); + } + + /** + * Add a VirtualTable (SQL View feature type) + * + * @param virtualtable + */ + protected void addMetadataVirtualTable( + final GSVirtualTableEncoder virtualtable) { + super.addMetadata("JDBC_VIRTUAL_TABLE", virtualtable); + } + + /** + * Set a VirtualTable (SQL View feature type) + * + * @param virtualtable + */ + public void setMetadataVirtualTable(final GSVirtualTableEncoder virtualtable) { + super.setMetadata("JDBC_VIRTUAL_TABLE", virtualtable); + } + + /** + * Deletes the VirtualTable metadata + * + * @return true if deleted, false otherwise + */ + public boolean delMetadataVirtualTable(){ + return super.delMetadata("JDB_VIRTUAL_TABLE"); + } + + /** + * delete a keyword from the list + * + * @param keyword + * @return true if something is removed, false otherwise + */ + public boolean delAttribute(final String keyword) { + final Element el = new Element("string"); + el.setText(keyword); + return (attributes.removeContent(GSAttributeEncoder.getFilterByName(keyword))).size() == 0 ? false + : true; + } + + /** + * @param attribute the attribute to add + */ + protected void addAttribute(GSAttributeEncoder attribute) { + attributes.addContent(attribute.getRoot()); + } + + /** + * @param attribute the attribute to set (overriding an attribute with the same name if present) + */ + public void setAttribute(GSAttributeEncoder attribute) { + delAttribute(attribute.getAttribute(FeatureTypeAttribute.name)); + addAttribute(attribute); + } + + + +}