diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java index 813c46d..895fb30 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java +++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java @@ -26,10 +26,11 @@ package it.geosolutions.geoserver.rest; import it.geosolutions.geoserver.rest.decoder.RESTCoverageList; import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore; +import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem; import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder; import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder; -import it.geosolutions.geoserver.rest.encoder.GSWorkspaceEncoder; 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; @@ -38,825 +39,1320 @@ import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; +import java.util.Iterator; import org.apache.commons.io.FilenameUtils; import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.apache.log4j.Priority; /** * Connect to a GeoServer instance to publish or modify data. *
* There are no modifiable instance fields, so all the calls are thread-safe. - * + * * @author ETj (etj at geo-solutions.it) */ public class GeoServerRESTPublisher { - private static final Logger LOGGER = Logger.getLogger(GeoServerRESTPublisher.class); - private final String restURL; - private final String gsuser; - private final String gspass; + private static final Logger LOGGER = Logger + .getLogger(GeoServerRESTPublisher.class); + private final String restURL; + private final String gsuser; + private final String gspass; - /** - * Creates a GeoServerRESTPublisher for a given GeoServer instance - * with the given auth credentials. - * - * @param restURL the base GeoServer URL (e.g.: http://localhost:8080/geoserver) - * @param username username auth credential - * @param password password auth credential - */ - public GeoServerRESTPublisher(String restURL, String username, String password) { - this.restURL = HTTPUtils.decurtSlash(restURL); - this.gsuser = username; - this.gspass = password; - } + /** + * Creates a GeoServerRESTPublisher for a given GeoServer instance + * with the given auth credentials. + * + * @param restURL + * the base GeoServer URL (e.g.: + * http://localhost:8080/geoserver) + * @param username + * username auth credential + * @param password + * password auth credential + */ + public GeoServerRESTPublisher(String restURL, String username, + String password) { + this.restURL = HTTPUtils.decurtSlash(restURL); + this.gsuser = username; + this.gspass = password; + } - //========================================================================== - //=== WORKSPACES - //========================================================================== + // ========================================================================== + // === WORKSPACES + // ========================================================================== - /** - * Create a new Workspace - * - * @param workspace The name of the new workspace. - * - *
- * This is the equivalent call with cUrl: - *
{@code curl -u admin:geoserver -XPOST \
- * -H 'Content-type: text/xml' \
- * -d "$WORKSPACE " \
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces
- * }
- */
- public boolean createWorkspace(final String workspace) {
- final String sUrl = restURL + "/rest/workspaces";
- final GSWorkspaceEncoder wsenc = new GSWorkspaceEncoder(workspace);
- final String wsxml = wsenc.toString();
- final String result = HTTPUtils.postXml(sUrl, wsxml, gsuser, gspass);
- return result != null;
- }
+ /**
+ * Create a new Workspace
+ *
+ * @param workspace
+ * The name of the new workspace.
+ *
+ * + * This is the equivalent call with cUrl: + * + *
+ * {@code curl -u admin:geoserver -XPOST \
+ * -H 'Content-type: text/xml' \
+ * -d "$WORKSPACE " \
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces
+ * }
+ *
+ */
+ public boolean createWorkspace(final String workspace) {
+ final String sUrl = restURL + "/rest/workspaces";
+ final GSWorkspaceEncoder wsenc = new GSWorkspaceEncoder(workspace);
+ final String wsxml = wsenc.toString();
+ final String result = HTTPUtils.postXml(sUrl, wsxml, gsuser, gspass);
+ return result != null;
+ }
- //==========================================================================
- //=== STYLES
- //==========================================================================
+ // ==========================================================================
+ // === STYLES
+ // ==========================================================================
- /**
- * Store and publish an SLD.
- * - * This is the equivalent call with cUrl: - *
- * {@code curl -u admin:geoserver -XPOST \
- * -H 'Content-type: application/vnd.ogc.sld+xml' \
- * -d @$FULLSLD \
- * http://$GSIP:$GSPORT/$SERVLET/rest/styles}
- *
- * @param sldBody the SLD document as an XML String.
- *
- * @return true if the operation completed successfully.
- */
- public boolean publishStyle(String sldBody) {
- String sUrl = restURL + "/rest/styles";
- String result = HTTPUtils.post(sUrl, sldBody, "application/vnd.ogc.sld+xml", gsuser, gspass);
- return result != null;
- }
+ /**
+ * Store and publish an SLD.
+ * + * This is the equivalent call with cUrl: + * + *
+ * {@code curl -u admin:geoserver -XPOST \
+ * -H 'Content-type: application/vnd.ogc.sld+xml' \
+ * -d @$FULLSLD \
+ * http://$GSIP:$GSPORT/$SERVLET/rest/styles}
+ *
+ *
+ * @param sldBody
+ * the SLD document as an XML String.
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean publishStyle(String sldBody) {
+ String sUrl = restURL + "/rest/styles";
+ String result = HTTPUtils.post(sUrl, sldBody,
+ "application/vnd.ogc.sld+xml", gsuser, gspass);
+ return result != null;
+ }
- /**
- * Store and publish an SLD.
- *
- * @param sldFile the File containing the SLD document.
- *
- * @return true if the operation completed successfully.
- */
- public boolean publishStyle(File sldFile) {
- return publishStyle(sldFile, null);
- }
+ /**
+ * Store and publish an SLD.
+ *
+ * @param sldFile
+ * the File containing the SLD document.
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean publishStyle(File sldFile) {
+ return publishStyle(sldFile, null);
+ }
- /**
- * Store and publish an SLD, assigning it a name.
- *
- * @param sldFile the File containing the SLD document.
- * @param name the Style name.
- *
- * @return true if the operation completed successfully.
- */
- public boolean publishStyle(File sldFile, String name) {
- String sUrl = restURL + "/rest/styles";
- if (name != null) {
- sUrl += "?name=" + encode(name);
- }
- LOGGER.debug("POSTing new style " + name + " to " + sUrl);
- String result = HTTPUtils.post(sUrl, sldFile, "application/vnd.ogc.sld+xml", gsuser, gspass);
- return result != null;
- }
+ /**
+ * Store and publish an SLD, assigning it a name.
+ *
+ * @param sldFile
+ * the File containing the SLD document.
+ * @param name
+ * the Style name.
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean publishStyle(File sldFile, String name) {
+ String sUrl = restURL + "/rest/styles";
+ if (name != null) {
+ sUrl += "?name=" + encode(name);
+ }
+ LOGGER.debug("POSTing new style " + name + " to " + sUrl);
+ String result = HTTPUtils.post(sUrl, sldFile,
+ "application/vnd.ogc.sld+xml", gsuser, gspass);
+ return result != null;
+ }
- /**
- * Remove a Style.
- * - * The Style will be unpublished and the related SLD file will be removed. - * - * @param styleName the name of the Style to remove. - * - * @return true if the operation completed successfully. - */ - public boolean removeStyle(String styleName) { - styleName = styleName.replaceAll(":", "_"); // ??? - styleName = encode(styleName); // spaces may - String sUrl = restURL + "/rest/styles/" + styleName + "?purge=true"; - return HTTPUtils.delete(sUrl, gsuser, gspass); - } + /** + * Remove a Style. + *
+ * The Style will be unpublished and the related SLD file will be removed.
+ *
+ * @param styleName
+ * the name of the Style to remove.
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean removeStyle(String styleName) {
+ styleName = styleName.replaceAll(":", "_"); // ???
+ styleName = encode(styleName); // spaces may
+ String sUrl = restURL + "/rest/styles/" + styleName + "?purge=true";
+ return HTTPUtils.delete(sUrl, gsuser, gspass);
+ }
- //==========================================================================
- //=== DATASTORE
- //==========================================================================
+ // ==========================================================================
+ // === DATASTORE
+ // ==========================================================================
- /**
- * Create a PostGIS datastore.
- *
- * @param workspace Name of the workspace to contain the database. This will also be the prefix of any layer names created from tables in the database.
- * @param datastoreEncoder the set of parameters to be set to the datastore (including connection params)
- *
- * @return true if the PostGIS datastore has been successfully created, false otherwise
- */
- public boolean createPostGISDatastore(String workspace, GSPostGISDatastoreEncoder datastoreEncoder) {
- String sUrl = restURL + "/rest/workspaces/" + workspace + "/datastores/";
- String xml = datastoreEncoder.toString();
- String result = HTTPUtils.postXml(sUrl, xml, gsuser, gspass);
- return result != null;
- }
+ /**
+ * Create a PostGIS datastore.
+ *
+ * @param workspace
+ * Name of the workspace to contain the database. This will also
+ * be the prefix of any layer names created from tables in the
+ * database.
+ * @param datastoreEncoder
+ * the set of parameters to be set to the datastore (including
+ * connection params)
+ *
+ * @return true if the PostGIS datastore has been successfully
+ * created, false otherwise
+ */
+ public boolean createPostGISDatastore(String workspace,
+ GSPostGISDatastoreEncoder datastoreEncoder) {
+ String sUrl = restURL + "/rest/workspaces/" + workspace
+ + "/datastores/";
+ String xml = datastoreEncoder.toString();
+ String result = HTTPUtils.postXml(sUrl, xml, gsuser, gspass);
+ return result != null;
+ }
- //==========================================================================
- //=== SHAPEFILES
- //==========================================================================
+ // ==========================================================================
+ // === SHAPEFILES
+ // ==========================================================================
- /**
- * Publish a zipped shapefile.
- *
The CRS will be forced to EPSG:4326.
- *
- * @param workspace
- * @param storename
- * @param layername
- * @param zipFile
- * @return true if the operation completed successfully.
- * @throws FileNotFoundException
- */
- public boolean publishShp(String workspace, String storename, String layername, File zipFile) throws FileNotFoundException {
- return publishShp(workspace, storename, layername, zipFile, "EPSG:4326");
- }
+ /**
+ * Publish a zipped shapefile.
+ * The CRS will be forced to EPSG:4326.
+ *
+ * @param workspace
+ * @param storename
+ * @param layername
+ * @param zipFile
+ * @return true if the operation completed successfully.
+ * @throws FileNotFoundException
+ */
+ public boolean publishShp(String workspace, String storename,
+ String layername, File zipFile) throws FileNotFoundException {
+ return publishShp(workspace, storename, layername, zipFile, "EPSG:4326");
+ }
- /**
- * Publish a zipped shapefile.
- *
- * @param workspace
- * @param storename
- * @param layerName
- * @param nativeCrs
- * @param defaultStyle may be null
- * @return true if the operation completed successfully.
- * @throws FileNotFoundException
- */
- public boolean publishShp(String workspace, String storename, String layerName, File zipFile, String nativeCrs, String defaultStyle) throws FileNotFoundException {
- boolean sent = publishShp(workspace, storename, layerName, zipFile, nativeCrs);
- if (sent) {
+ /**
+ * Publish a zipped shapefile.
+ *
+ * @param workspace
+ * @param storename
+ * @param layerName
+ * @param nativeCrs
+ * @param defaultStyle
+ * may be null
+ * @return true if the operation completed successfully.
+ * @throws FileNotFoundException
+ */
+ public boolean publishShp(String workspace, String storename,
+ String layerName, File zipFile, String nativeCrs,
+ String defaultStyle) throws FileNotFoundException {
+ boolean sent = publishShp(workspace, storename, layerName, zipFile,
+ nativeCrs);
+ if (sent) {
- try {
- GSLayerEncoder layerEncoder = new GSLayerEncoder();
- layerEncoder.addDefaultStyle(defaultStyle);
- configureLayer(workspace, layerName, layerEncoder);
- } catch (Exception e) {
- LOGGER.warn("Error in publishing shapefile " + e.getMessage(), e);
- sent = false;
- }
- }
+ try {
+ GSLayerEncoder layerEncoder = new GSLayerEncoder();
+ layerEncoder.addDefaultStyle(defaultStyle);
+ configureLayer(workspace, layerName, layerEncoder);
+ } catch (Exception e) {
+ LOGGER.warn("Error in publishing shapefile " + e.getMessage(),
+ e);
+ sent = false;
+ }
+ }
- return sent;
- }
+ return sent;
+ }
- /**
- * Publish a zipped shapefile.
- *
- *
These are the equivalent calls with cUrl: - *
{@code
- *curl -u admin:geoserver -XPUT -H 'Content-type: application/zip' \
- * --data-binary @$ZIPFILE \
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/datastores/$STORENAME/file.shp
- *
- *curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' \
- * -d "$BARE EPSG:4326 true " \
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/datastores/$STORENAME/featuretypes/$LAYERNAME
- * }
- *
- * @return true if the operation completed successfully.
- */
- public boolean publishShp(String workspace, String storename, String layername, File zipFile, String srs) throws FileNotFoundException {
- // build full URL
- StringBuilder sbUrl = new StringBuilder(restURL)
- .append("/rest/workspaces/").append(workspace)
- .append("/datastores/").append(storename)
- .append("/file.shp?");
-// if (workspace != null) {
-// sbUrl.append("namespace=").append(workspace);
-// }
-// sbUrl.append("&SRS=4326&SRSHandling=Force"); // hack
+ /**
+ * Publish a zipped shapefile.
+ *
+ * + * These are the equivalent calls with cUrl: + * + *
+ * {@code
+ * curl -u admin:geoserver -XPUT -H 'Content-type: application/zip' \
+ * --data-binary @$ZIPFILE \
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/datastores/$STORENAME/file.shp
+ *
+ * curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' \
+ * -d "$BARE EPSG:4326 true " \
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/datastores/$STORENAME/featuretypes/$LAYERNAME
+ * }
+ *
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean publishShp(String workspace, String storename,
+ String layername, File zipFile, String srs)
+ throws FileNotFoundException {
+ // build full URL
+ StringBuilder sbUrl = new StringBuilder(restURL)
+ .append("/rest/workspaces/").append(workspace)
+ .append("/datastores/").append(storename).append("/file.shp?");
+ // if (workspace != null) {
+ // sbUrl.append("namespace=").append(workspace);
+ // }
+ // sbUrl.append("&SRS=4326&SRSHandling=Force"); // hack
- String sentResult = HTTPUtils.put(sbUrl.toString(), zipFile, "application/zip", gsuser, gspass);
- boolean shpSent = sentResult != null;
+ String sentResult = HTTPUtils.put(sbUrl.toString(), zipFile,
+ "application/zip", gsuser, gspass);
+ boolean shpSent = sentResult != null;
- if (shpSent) {
- LOGGER.info("Zipfile successfully uploaded (layer:" + layername + " zip:" + zipFile + ")");
+ if (shpSent) {
+ LOGGER.info("Zipfile successfully uploaded (layer:" + layername
+ + " zip:" + zipFile + ")");
- StringBuilder postUrl = new StringBuilder(restURL)
- .append("/rest/workspaces/").append(workspace)
- .append("/datastores/").append(storename)
- .append("/featuretypes/").append(layername);
+ StringBuilder postUrl = new StringBuilder(restURL)
+ .append("/rest/workspaces/").append(workspace)
+ .append("/datastores/").append(storename)
+ .append("/featuretypes/").append(layername);
- GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder();
- fte.addName(layername);
- fte.addSRS(srs);
- fte.addProjectionPolicy(ProjectionPolicy.REPROJECT_TO_DECLARED);
+ GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder();
+ fte.addName(layername);
+ fte.addSRS(srs);
+ fte.addProjectionPolicy(ProjectionPolicy.REPROJECT_TO_DECLARED);
- String configuredResult = HTTPUtils.putXml(postUrl.toString(), fte.toString(), this.gsuser, this.gspass);
- boolean shpConfigured = configuredResult != null;
+ String configuredResult = HTTPUtils.putXml(postUrl.toString(),
+ fte.toString(), this.gsuser, this.gspass);
+ boolean shpConfigured = configuredResult != null;
- if (!shpConfigured) {
- LOGGER.warn("Error in configuring " + workspace + ":" + storename + "/" + layername + " -- Zipfile was uploaded successfully: " + zipFile);
- } else {
- LOGGER.info("Shapefile successfully configured (layer:" + layername + ")");
- }
+ if (!shpConfigured) {
+ LOGGER.warn("Error in configuring " + workspace + ":"
+ + storename + "/" + layername
+ + " -- Zipfile was uploaded successfully: " + zipFile);
+ } else {
+ LOGGER.info("Shapefile successfully configured (layer:"
+ + layername + ")");
+ }
- return shpConfigured;
+ return shpConfigured;
- } else {
- LOGGER.warn("Error in sending zipfile " + workspace + ":" + storename + "/" + layername + " " + zipFile);
- return false;
- }
+ } else {
+ LOGGER.warn("Error in sending zipfile " + workspace + ":"
+ + storename + "/" + layername + " " + zipFile);
+ return false;
+ }
- }
+ }
- /**
- * Publish a table in a PostGis store as a new layer.
- *
- * This is the equivalent call with cUrl: - *
{@code curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' \
- * -d "easia_gaul_1_aggr EPSG:4326 true " \
- * http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/datastores/pg_kids/featuretypes
- * }
- *
- * and a PUT to
- * + * This is the equivalent call with cUrl: + * + *
+ * {@code curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' \
+ * -d "easia_gaul_1_aggr EPSG:4326 true " \
+ * http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/datastores/pg_kids/featuretypes
+ * }
+ *
+ *
+ * and a PUT to + * This is the equivalent call with cUrl: + * + *
+ * {@code
+ * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$FULLPATH" \
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$STORENAME/external.geotiff
+ * }
+ *
+ *
+ * @return true if the operation completed successfully.
+ * @deprecated UNTESTED
+ */
+ public boolean publishGeoTIFF(String workspace, String storeName,
+ File geotiff) throws FileNotFoundException {
+ String sUrl = restURL + "/rest/workspaces/" + workspace
+ + "/coveragestores/" + storeName + "/geotiff";
+ String sendResult = HTTPUtils
+ .put(sUrl, geotiff, "text", gsuser, gspass); // CHECKME: text?!?
+ boolean sent = sendResult != null;
+ return sent;
+ }
+
+ /**
+ * Publish a GeoTiff already in a filesystem readable by GeoServer.
+ *
+ * @param workspace
+ * an existing workspace
+ * @param storeName
+ * the coverageStore to be created
+ * @param geotiff
+ * the geoTiff to be published
+ *
+ * @return a PublishedCoverage, or null on errors
+ * @throws FileNotFoundException
+ */
+ public RESTCoverageStore publishExternalGeoTIFF(String workspace,
+ String storeName, File geotiff, String srs, String defaultStyle)
+ throws FileNotFoundException {
+ // create store
+ String sUrl = restURL + "/rest/workspaces/" + workspace
+ + "/coveragestores/" + storeName + "/external.geotiff";
+ String sendResult = HTTPUtils.put(sUrl, geotiff.toURI().toString(),
+ "text/plain", gsuser, gspass);
+ RESTCoverageStore store = RESTCoverageStore.build(sendResult);
+
+ if (store != null) {
+ try {
+ // retrieve coverage name
+ GeoServerRESTReader reader = new GeoServerRESTReader(restURL,
+ gsuser, gspass);
+ RESTCoverageList covList = reader.getCoverages(workspace,
+ storeName);
+ if (covList.isEmpty()) {
+ LOGGER.error("No coverages found in new coveragestore "
+ + storeName);
+ return null;
+ }
+ final String coverageName = covList.get(0).getName();
+
+ // config coverage props (srs)
+ GSCoverageEncoder coverageEncoder = new GSCoverageEncoder();
+ coverageEncoder.addName(FilenameUtils.getBaseName(geotiff
+ .getName()));
+ coverageEncoder.addSRS(srs);
+ coverageEncoder
+ .addProjectionPolicy(ProjectionPolicy.REPROJECT_TO_DECLARED);
+ configureCoverage(coverageEncoder, workspace, storeName,
+ coverageName);
+
+ // config layer props (style, ...)
+ GSLayerEncoder layerEncoder = new GSLayerEncoder();
+ layerEncoder.addDefaultStyle(defaultStyle);
+ configureLayer(workspace, coverageName, layerEncoder);
+
+ } catch (Exception e) {
+ LOGGER.warn(
+ "Could not configure external GEOTiff:" + storeName, e);
+ store = null; // TODO: should we remove the configured pc?
+ }
+ }
+
+ return store;
+ }
+
+ // ==========================================================================
+ // === MOSAIC
+ // ==========================================================================
+
+ /**
+ * Publish a Mosaic from a filesystem currently readable by GeoServer.
+ *
+ *
+ * Sample cUrl usage:
+ * <>
+ * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
+ *
+ * @param workspace
+ * an existing workspace
+ * @param storeName
+ * the name of the coverageStore to be created
+ * @param mosaicDir
+ * the directory where the raster images are located
+ * @param configure
+ * a specify if a coverage should be configured
+ * @return true if the operation completed successfully.
+ * @throws FileNotFoundException
+ */
+ public RESTCoverageStore createExternaMosaicDatastore(String workspace,
+ String storeName, File mosaicDir, ParameterConfigure configure,
+ ParameterUpdate update) throws FileNotFoundException {
+ if (!mosaicDir.isDirectory()) {
+ throw new IllegalArgumentException("Not a directory '" + mosaicDir
+ + "'");
+ }
+ String sUrl = restURL + "/rest/workspaces/" + workspace
+ + "/coveragestores/" + storeName
+ + "/external.imagemosaic?configure=" + configure.toString()
+ + "&update=" + update.toString();
+ String sendResult = HTTPUtils.put(sUrl, mosaicDir.toURI().toString(),
+ "text/plain", gsuser, gspass);
+ return RESTCoverageStore.build(sendResult);
+ }
+
+ /**
+ * @deprecated provided for backward compatibility use {@link
+ * createExternaMosaicDatastore(String workspace, String
+ * storeName, File mosaicDir, CoverageConfigure configure)}
+ * @param workspace
+ * @param storeName
+ * @param mosaicDir
+ * @return
+ * @throws FileNotFoundException
+ */
+ public RESTCoverageStore configureExternaMosaicDatastore(String workspace,
+ String storeName, File mosaicDir) throws FileNotFoundException {
+ return createExternaMosaicDatastore(workspace, storeName, mosaicDir,
+ ParameterConfigure.FIRST, ParameterUpdate.APPEND);
+ }
+
+ /**
+ * Publish a Mosaic already in a filesystem readable by GeoServer.
+ *
+ *
+ * Sample cUrl usage:
+ * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
+ *
+ * @param workspace
+ * an existing workspace
+ * @param storeName
+ * the name of the coverageStore to be created
+ * @param mosaicDir
+ * the directory where the raster images are located
+ * @param srs
+ * the coverage declared SRS
+ * @param defaultStyle
+ * may be null
+ *
+ * @return true if the operation completed successfully.
+ *
+ * @throws FileNotFoundException
+ */
+ public RESTCoverageStore publishExternalMosaic(String workspace,
+ String storeName, File mosaicDir, String srs, String defaultStyle)
+ throws FileNotFoundException {
+ GSCoverageEncoder coverageEncoder = new GSCoverageEncoder();
+ coverageEncoder.addSRS(srs);
+ coverageEncoder.addName(FilenameUtils.getBaseName(mosaicDir.getName()));
+ GSLayerEncoder layerEncoder = new GSLayerEncoder();
+ layerEncoder.addDefaultStyle(defaultStyle);
+
+ return publishExternalMosaic(workspace, storeName, mosaicDir,
+ coverageEncoder, layerEncoder);
+ }
+
+ /**
+ * Publish a Mosaic already in a filesystem readable by GeoServer.
+ *
+ *
+ * Sample cUrl usage:
+ * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
+ *
+ * @param workspace
+ * an existing workspace
+ * @param storeName
+ * the name of the coverageStore to be created
+ * @param mosaicDir
+ * the directory where the raster images are located
+ * @param coverageEncoder
+ * the set of parameters to be set to the coverage (bbox, srs,
+ * ...)
+ * @param layerEncoder
+ * the set of parameters to be set to the layer (defaultstyle,
+ * wmspath, ...)
+ *
+ * @return the created RESTCoverageStore
+ * @deprecated this is keep only for backward compatibility use
+ * createExternalMosaic and getCoverageStore separately
+ *
+ * @throws FileNotFoundException
+ */
+ public RESTCoverageStore publishExternalMosaic(String workspace,
+ String storeName, File mosaicDir,
+ GSCoverageEncoder coverageEncoder, GSLayerEncoder layerEncoder)
+ throws FileNotFoundException {
+
+ if (!createExternalMosaic(workspace, storeName, mosaicDir,
+ coverageEncoder, layerEncoder)) {
+ return null;
+ }
+
+ GeoServerRESTReader reader;
+ try {
+ reader = new GeoServerRESTReader(restURL, gsuser, gspass);
+ } catch (MalformedURLException e1) {
+ LOGGER.warn("Could not configure external Mosaic:" + storeName, e1);
+ return null;
+ }
+
+ final RESTCoverageStore store = reader.getCoverageStore(workspace,
+ storeName);
+
+ if (store == null) {
+ LOGGER.warn("Unable to get the store" + workspace + ":" + storeName
+ + " from the targhet geoserver.");
+ return null;
+ }
+
+ return store;
+ }
+
+ /**
+ * Publish a Mosaic already in a filesystem readable by GeoServer.
+ *
+ *
+ * Sample cUrl usage:
+ * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
+ * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
+ *
+ * @param workspace
+ * an existing workspace
+ * @param storeName
+ * the name of the coverageStore to be created
+ * @param mosaicDir
+ * the directory where the raster images are located
+ * @param coverageEncoder
+ * the set of parameters to be set to the coverage (bbox, srs,
+ * ...)
+ * @param layerEncoder
+ * the set of parameters to be set to the layer (defaultstyle,
+ * wmspath, ...)
+ *
+ * @return true if the operation completed successfully.
+ *
+ * @throws FileNotFoundException
+ */
+ public boolean createExternalMosaic(String workspace, String storeName,
+ File mosaicDir, GSCoverageEncoder coverageEncoder,
+ GSLayerEncoder layerEncoder) throws FileNotFoundException {
+
+ RESTCoverageStore store = createExternaMosaicDatastore(workspace,
+ storeName, mosaicDir, ParameterConfigure.NONE,
+ ParameterUpdate.OVERWRITE);
+
+ // override name to match the FIRST configured coverage
+ final String coverageStoreName = FilenameUtils.getBaseName(mosaicDir
+ .getName());
+
+ if (coverageEncoder == null) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("no coverageEncoder provided for " + workspace
+ + ":" + storeName);
+ }
+
+ coverageEncoder = new GSCoverageEncoder();
+ coverageEncoder.setName(coverageStoreName);
+ }
+
+ if (layerEncoder == null) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("no layerEncoder provided for " + workspace + ":"
+ + storeName);
+ }
+ layerEncoder = new GSLayerEncoder();
+ }
+
+ if (store != null) {
+ try {
+ // override name
+ coverageEncoder.setName(coverageStoreName);
+
+ if (!createCoverage(coverageEncoder, workspace, storeName)) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error("Unable to create a coverage for the store:"
+ + storeName);
+ return false;
+ }
+ if (!configureLayer(workspace, coverageStoreName, layerEncoder)) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error("Unable to configure the Layer for the coverage:"
+ + coverageStoreName);
+ return false;
+ }
+
+ } catch (Exception e) {
+ if (LOGGER.isEnabledFor(Level.WARN))
+ LOGGER.warn("Could not configure external mosaic:"
+ + storeName, e);
+ store = null; // TODO: should we remove the configured store?
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ // ==========================================================================
+ // === COVERAGES
+ // ==========================================================================
+
+ /**
+ * Remove the Coverage configuration from GeoServer.
+ * First, the associated layer is removed, then the Coverage configuration
+ * itself.
+ *
+ * CHECKME Maybe the coveragestore has to be removed as well. + * + *
+ * REST URL:
+ * http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/coveragestores/gbRESTtestStore/coverages/resttestdem.xml
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean unpublishCoverage(String workspace, String storename,
+ String layerName) {
+ try {
+ final String fqLayerName;
+
+ // this null check is here only for backward compatibility.
+ // workspace
+ // shall be mandatory.
+ if (workspace == null) {
+
+ fqLayerName = layerName;
+
+ if (LOGGER.isEnabledFor(Level.WARN)) {
+ LOGGER.warn("Null workspace while configuring layer : "
+ + layerName + " -- This behavior is deprecated.");
+ }
+ } else {
+ fqLayerName = workspace + ":" + layerName;
+ }
+ // delete related layer
+ URL deleteLayerUrl = new URL(restURL + "/rest/layers/"
+ + fqLayerName);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Going to delete " + "/rest/layers/" + fqLayerName);
+ }
+ boolean layerDeleted = HTTPUtils.delete(
+ deleteLayerUrl.toExternalForm(), gsuser, gspass);
+ if (!layerDeleted) {
+ LOGGER.warn("Could not delete layer '" + fqLayerName + "'");
+ return false;
+ }
+ // delete the coverage
+ URL deleteCovUrl = new URL(restURL + "/rest/workspaces/"
+ + workspace + "/coveragestores/" + storename
+ + "/coverages/" + layerName);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Going to delete " + "/rest/workspaces/"
+ + workspace + "/coveragestores/" + storename
+ + "/coverages/" + layerName);
+ }
+ boolean covDeleted = HTTPUtils.delete(
+ deleteCovUrl.toExternalForm(), gsuser, gspass);
+ if (!covDeleted) {
+ LOGGER.warn("Could not delete coverage " + workspace + ":"
+ + storename + "/" + layerName
+ + ", but layer was deleted.");
+ } else {
+ LOGGER.info("Coverage successfully deleted " + workspace + ":"
+ + storename + "/" + layerName);
+ }
+ return covDeleted;
+
+ // the covstore is still there: should we delete it?
+
+ } catch (MalformedURLException ex) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error(ex);
+ return false;
+ }
+ }
+
+ // ==========================================================================
+ // === FEATURETYPES
+ // ==========================================================================
+
+ /**
+ * Removes the featuretype and the associated layer. This is the equivalent call with cUrl:
- * Sample cUrl usage: Sample cUrl usage: Sample cUrl usage:
- * CHECKME Maybe the coveragestore has to be removed as well.
- *
- * REST URL:
- * http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/coveragestores/gbRESTtestStore/coverages/resttestdem.xml
- *
- * @return true if the operation completed successfully.
- */
- public boolean unpublishCoverage(String workspace, String storename, String layername) {
- try {
- // delete related layer
- URL deleteLayerUrl = new URL(restURL + "/rest/layers/" + layername);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Going to delete " + "/rest/layers/" + layername);
- }
- boolean layerDeleted = HTTPUtils.delete(deleteLayerUrl.toExternalForm(), gsuser, gspass);
- if (!layerDeleted) {
- LOGGER.warn("Could not delete layer '" + layername + "'");
- return false;
- }
- // delete the coverage
- URL deleteCovUrl = new URL(restURL + "/rest/workspaces/" + workspace + "/coveragestores/" + storename + "/coverages/" + layername);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Going to delete " + "/rest/workspaces/" + workspace + "/coveragestores/" + storename + "/coverages/" + layername);
- }
- boolean covDeleted = HTTPUtils.delete(deleteCovUrl.toExternalForm(), gsuser, gspass);
- if (!covDeleted) {
- LOGGER.warn("Could not delete coverage " + workspace + ":" + storename + "/" + layername + ", but layer was deleted.");
- } else {
- LOGGER.info("Coverage successfully deleted " + workspace + ":" + storename + "/" + layername);
- }
- return covDeleted;
-
- // the covstore is still there: should we delete it?
-
- } catch (MalformedURLException ex) {
- LOGGER.error(ex);
- return false;
- }
- }
-
- //==========================================================================
- //=== FEATURETYPES
- //==========================================================================
-
- /**
- * Removes the featuretype and the associated layer.
- *
+ * You may also want to {@link #removeDatastore(String, String) remove the
+ * datastore}.
+ *
+ * @return true if the operation completed successfully.
+ */
+ public boolean unpublishFeatureType(String workspace, String storename,
+ String layerName) {
+ try {
+
+ final String fqLayerName;
+ // this null check is here only for backward compatibility.
+ // workspace
+ // shall be mandatory.
+ if (workspace == null) {
+
+ fqLayerName = layerName;
+
+ if (LOGGER.isEnabledFor(Level.WARN)) {
+ LOGGER.warn("Null workspace while configuring layer : "
+ + layerName + " -- This behavior is deprecated.");
+ }
+ } else {
+ fqLayerName = workspace + ":" + layerName;
+ }
+ // delete related layer
+ URL deleteLayerUrl = new URL(restURL + "/rest/layers/"
+ + fqLayerName);
+ boolean layerDeleted = HTTPUtils.delete(
+ deleteLayerUrl.toExternalForm(), gsuser, gspass);
+ if (!layerDeleted) {
+ LOGGER.warn("Could not delete layer '" + fqLayerName + "'");
+ return false;
+ }
+ // delete the coverage
+ URL deleteFtUrl = new URL(restURL + "/rest/workspaces/" + workspace
+ + "/datastores/" + storename + "/featuretypes/" + layerName);
+ boolean ftDeleted = HTTPUtils.delete(deleteFtUrl.toExternalForm(),
+ gsuser, gspass);
+ if (!ftDeleted) {
+ LOGGER.warn("Could not delete featuretype " + workspace + ":"
+ + storename + "/" + layerName
+ + ", but layer was deleted.");
+ } else {
+ LOGGER.info("FeatureType successfully deleted " + workspace
+ + ":" + storename + "/" + layerName);
+ }
+
+ return ftDeleted;
+
+ // the store is still there: should we delete it?
+
+ } catch (MalformedURLException ex) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error(ex);
+ return false;
+ }
+ }
+
+ /**
+ * Remove recursively a given Datastore in a given Workspace.
+ *
+ * @param workspace
+ * The name of the workspace
+ * @param storename
+ * The name of the Datastore to remove.
+ * @return true if the datastore was successfully removed.
+ */
+ public boolean removeDatastore(String workspace, String storename) {
+ return removeDatastore(workspace, storename, true);
+ }
+
+ /**
+ * Remove a given Datastore in a given Workspace.
+ *
+ * @param workspace
+ * The name of the workspace
+ * @param storename
+ * The name of the Datastore to remove.
+ * @param recurse
+ * if remove should be performed recursively
+ * @return true if the datastore was successfully removed.
+ */
+ public boolean removeDatastore(String workspace, String storename,
+ final boolean recurse) {
+ try {
+ final StringBuilder url = new StringBuilder(restURL);
+ // restURL + "/rest/workspaces/" + workspace + "/datastores/" +
+ // storename
+ url.append("/rest/workspaces/").append(workspace)
+ .append("/datastores/").append(storename);
+ if (recurse)
+ url.append("?recurse=true");
+ final URL deleteStore = new URL(url.toString());
+
+ boolean deleted = HTTPUtils.delete(deleteStore.toExternalForm(),
+ gsuser, gspass);
+ if (!deleted) {
+ LOGGER.warn("Could not delete datastore " + workspace + ":"
+ + storename);
+ } else {
+ LOGGER.info("Datastore successfully deleted " + workspace + ":"
+ + storename);
+ }
+
+ return deleted;
+ } catch (MalformedURLException ex) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error(ex);
+ return false;
+ }
+ }
+
+ /**
+ * Remove recursively a given CoverageStore in a given Workspace.
+ *
+ * @param workspace
+ * The name of the workspace
+ * @param storename
+ * The name of the CoverageStore to remove.
+ * @return true if the CoverageStore was successfully removed.
+ */
+ public boolean removeCoverageStore(String workspace, String storename) {
+ return removeCoverageStore(workspace, storename, true);
+ }
+
+ /**
+ * Remove a given CoverageStore in a given Workspace.
+ *
+ * @param workspace
+ * The name of the workspace
+ * @param storename
+ * The name of the CoverageStore to remove.
+ * @param recurse
+ * if remove should be performed recursively
+ * @return true if the CoverageStore was successfully removed.
+ */
+ public boolean removeCoverageStore(final String workspace,
+ final String storename, final boolean recurse) {
+ try {
+ final StringBuilder url = new StringBuilder(restURL);
+ // restURL + "/rest/workspaces/" + workspace + "/datastores/" +
+ // storename
+ url.append("/rest/workspaces/").append(workspace)
+ .append("/coveragestores/").append(storename);
+ if (recurse)
+ url.append("?recurse=true");
+ final URL deleteStore = new URL(url.toString());
+
+ boolean deleted = HTTPUtils.delete(deleteStore.toExternalForm(),
+ gsuser, gspass);
+ if (!deleted) {
+ LOGGER.warn("Could not delete CoverageStore " + workspace + ":"
+ + storename);
+ } else {
+ LOGGER.info("CoverageStore successfully deleted " + workspace
+ + ":" + storename);
+ }
+ return deleted;
+
+ } catch (MalformedURLException ex) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error(ex);
+ return false;
+ }
+ }
+
+ /**
+ * Remove a given Workspace.
+ *
+ * @param workspace
+ * The name of the workspace
+ * @return true if the WorkSpace was successfully removed.
+ */
+ public boolean removeWorkspace(String workspace) {
+ workspace = sanitize(workspace);
+ try {
+ URL deleteUrl = new URL(restURL + "/rest/workspaces/" + workspace);
+ boolean deleted = HTTPUtils.delete(deleteUrl.toExternalForm(),
+ gsuser, gspass);
+ if (!deleted) {
+ LOGGER.warn("Could not delete Workspace " + workspace);
+ } else {
+ LOGGER.info("Workspace successfully deleted " + workspace);
+ }
+
+ return deleted;
+ } catch (MalformedURLException ex) {
+ LOGGER.error(ex);
+ return false;
+ }
+ }
+
+ /**
+ * reload the target geoserver configuration
+ *
+ * @return true if success
+ *
+ * @see http
+ * ://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html
+ */
+ public boolean reload() {
+ String sUrl = restURL + "/rest/reload";
+ String result = HTTPUtils.post(sUrl, "", "text/plain", gsuser, gspass);
+ return result != null;
+ }
+
+ /**
+ * reset the target geoserver configuration
+ *
+ * @return true if success
+ *
+ * @see http
+ * ://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html
+ */
+ public boolean reset() {
+ String sUrl = restURL + "/rest/reset";
+ String result = HTTPUtils.post(sUrl, "", "text/plain", gsuser, gspass);
+ return result != null;
+ }
+
+ public boolean removeLayerGroup(String name) {
+ try {
+ URL deleteUrl = new URL(restURL + "/rest/layergroups/" + name);
+ boolean deleted = HTTPUtils.delete(deleteUrl.toExternalForm(),
+ gsuser, gspass);
+ if (!deleted) {
+ LOGGER.warn("Could not delete layergroup " + name);
+ } else {
+ if (LOGGER.isInfoEnabled())
+ LOGGER.info("Layergroup successfully deleted: " + name);
+ }
+
+ return deleted;
+ } catch (MalformedURLException ex) {
+ LOGGER.error(ex);
+ return false;
+ }
+ }
+
+ // ==========================================================================
+ // ===
+ // ==========================================================================
+
+ /**
+ * @deprecated please use {@link configureLayer(String workspace, String
+ * layerName, GSLayerEncoder layer) }
+ */
+ public boolean configureLayer(final GSLayerEncoder layer,
+ final String layerName) {
+ return configureLayer(null, layerName, layer);
+ }
+
+ /**
+ * remove a generic given layer from a given workspace
+ *
+ * @param workspace
+ * @param layerName
+ * @return true if success
+ */
+ public boolean removeLayer(final String workspace, final String layerName) {
+
+ final String fqLayerName;
+
+ // this null check is here only for backward compatibility. workspace
+ // shall be mandatory.
+ if (workspace == null) {
+
+ fqLayerName = layerName;
+
+ if (LOGGER.isEnabledFor(Level.WARN)) {
+ LOGGER.warn("Null workspace while removing layer : "
+ + layerName + " -- This behavior is deprecated.");
+ }
+ } else {
+ fqLayerName = workspace + ":" + layerName;
+ }
+ if (layerName == null) {
+ if (LOGGER.isEnabledFor(Level.ERROR)) {
+ LOGGER.error("Null layerName : " + layerName);
+ }
+ return false;
+ }
+
+ final String url = restURL + "/rest/layers/" + fqLayerName;
+
+ boolean result = HTTPUtils.delete(url, gsuser, gspass);
+ if (result) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Layer successfully removed: " + fqLayerName);
+ }
+ } else {
+ if (LOGGER.isEnabledFor(Level.WARN))
+ LOGGER.warn("Error removing layer " + fqLayerName);
+ }
+
+ return result;
+ }
+
+ /**
+ * Allows to configure some layer attributes such and DefaultStyle TODO
+ * WmsPath
+ */
+ public boolean configureLayer(final String workspace,
+ final String layerName, final GSLayerEncoder layer) {
+
+ // TODO: check this usecase, layer should always be defined
+ if (layer.isEmpty()) {
+ if (LOGGER.isEnabledFor(Level.WARN))
+ LOGGER.warn("Null layer name while configuring layer -- This behavior is suspicious.");
+ return true;
+ }
+
+ final String fqLayerName;
+
+ // this null check is here only for backward compatibility. workspace
+ // shall be mandatory.
+ if (workspace == null) {
+
+ fqLayerName = layerName;
+
+ if (LOGGER.isEnabledFor(Level.WARN)) {
+ LOGGER.warn("Null workspace while configuring layer : "
+ + layerName + " -- This behavior is deprecated.");
+ }
+ } else {
+ fqLayerName = workspace + ":" + layerName;
+ }
+
+ final String url = restURL + "/rest/layers/" + fqLayerName;
+
+ String layerXml = layer.toString();
+ String sendResult = HTTPUtils.putXml(url, layerXml, gsuser, gspass);
+ if (sendResult != null) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Layer successfully configured: " + fqLayerName);
+ }
+ } else {
+ if (LOGGER.isEnabledFor(Level.WARN))
+ LOGGER.warn("Error configuring layer " + fqLayerName + " ("
+ + sendResult + ")");
+ }
+
+ return sendResult != null;
+ }
+
+ /**
+ * Configure an existent 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
+ */
+ public boolean configureCoverage(final GSCoverageEncoder ce,
+ final String wsname, final String csname) {
+ final String cname = ce.getName();
+ if (cname == null) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error("Unable to configure a coverage 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.isEnabledFor(Level.ERROR))
+ LOGGER.error(e);
+ return false;
+ }
+ final RESTCoverageList covList = reader.getCoverages(wsname, csname);
+ if (covList.isEmpty()) {
+ if (LOGGER.isEnabledFor(Level.ERROR))
+ LOGGER.error("No coverages found in new coveragestore "
+ + csname);
+ return false;
+ }
+ final Iterator{@code
- *curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$FULLPATH" \
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$STORENAME/external.geotiff
- * }
- *
- * @return true if the operation completed successfully.
- * @deprecated UNTESTED
- */
- public boolean publishGeoTIFF(String workspace, String storeName, File geotiff) throws FileNotFoundException {
- String sUrl = restURL + "/rest/workspaces/" + workspace + "/coveragestores/" + storeName + "/geotiff";
- String sendResult = HTTPUtils.put(sUrl, geotiff, "text", gsuser, gspass); // CHECKME: text?!?
- boolean sent = sendResult != null;
- return sent;
- }
-
- /**
- * Publish a GeoTiff already in a filesystem readable by GeoServer.
- *
- * @param workspace an existing workspace
- * @param storeName the coverageStore to be created
- * @param geotiff the geoTiff to be published
- *
- * @return a PublishedCoverage, or null on errors
- * @throws FileNotFoundException
- */
- public RESTCoverageStore publishExternalGeoTIFF(String workspace, String storeName, File geotiff, String srs, String defaultStyle) throws FileNotFoundException {
- // create store
- String sUrl = restURL + "/rest/workspaces/" + workspace + "/coveragestores/" + storeName + "/external.geotiff";
- String sendResult = HTTPUtils.put(sUrl, geotiff.toURI().toString(), "text/plain", gsuser, gspass);
- RESTCoverageStore store = RESTCoverageStore.build(sendResult);
-
- if (store != null) {
- try {
-// // retrieve coverage name
- GeoServerRESTReader reader = new GeoServerRESTReader(restURL, gsuser, gspass);
- RESTCoverageList covList = reader.getCoverages(workspace, storeName);
- if (covList.isEmpty()) {
- LOGGER.error("No coverages found in new coveragestore " + storeName);
- return null;
- }
- final String coverageName = covList.get(0).getName();
-
- // config coverage props (srs)
- GSCoverageEncoder coverageEncoder = new GSCoverageEncoder();
- coverageEncoder.addName(FilenameUtils.getBaseName(geotiff.getName()));
- coverageEncoder.addSRS(srs);
- coverageEncoder.addProjectionPolicy(ProjectionPolicy.REPROJECT_TO_DECLARED);
- configureCoverage(coverageEncoder, workspace, storeName, coverageName);
-
- // config layer props (style, ...)
- GSLayerEncoder layerEncoder = new GSLayerEncoder();
- layerEncoder.addDefaultStyle(defaultStyle);
- configureLayer(workspace, coverageName, layerEncoder);
-
- } catch (Exception e) {
- LOGGER.warn("Could not configure external GEOTiff:" + storeName, e);
- store = null; // TODO: should we remove the configured pc?
- }
- }
-
- return store;
- }
-
- //==========================================================================
- //=== MOSAIC
- //==========================================================================
-
- /**
- * Publish a Mosaic already in a filesystem readable by GeoServer.
- *
- *
- * <>
- * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
- *
- * @param workspace an existing workspace
- * @param storeName the name of the coverageStore to be created
- * @param mosaicDir the directory where the raster images are located
- * @return true if the operation completed successfully.
- * @throws FileNotFoundException
- */
- public RESTCoverageStore configureExternaMosaicDatastore(String workspace, String storeName, File mosaicDir) throws FileNotFoundException {
- if (!mosaicDir.isDirectory()) {
- throw new IllegalArgumentException("Not a directory '" + mosaicDir + "'");
- }
- String sUrl = restURL + "/rest/workspaces/" + workspace + "/coveragestores/" + storeName + "/external.imagemosaic";
- String sendResult = HTTPUtils.put(sUrl, mosaicDir.toURI().toString(), "text/plain", gsuser, gspass);
- return RESTCoverageStore.build(sendResult);
- }
-
- /**
- * Publish a Mosaic already in a filesystem readable by GeoServer.
- *
- *
- * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
- *
- * @param workspace an existing workspace
- * @param storeName the name of the coverageStore to be created
- * @param mosaicDir the directory where the raster images are located
- * @param srs the coverage declared SRS
- * @param defaultStyle may be null
- *
- * @return true if the operation completed successfully.
- *
- * @throws FileNotFoundException
- */
- public RESTCoverageStore publishExternalMosaic(String workspace, String storeName, File mosaicDir, String srs, String defaultStyle) throws FileNotFoundException {
- GSCoverageEncoder coverageEncoder = new GSCoverageEncoder();
- coverageEncoder.addSRS(srs);
- coverageEncoder.addName(FilenameUtils.getBaseName(mosaicDir.getName()));
- GSLayerEncoder layerEncoder = new GSLayerEncoder();
- layerEncoder.addDefaultStyle(defaultStyle);
-
- return publishExternalMosaic(workspace, storeName, mosaicDir, coverageEncoder, layerEncoder);
- }
-
- /**
- * Publish a Mosaic already in a filesystem readable by GeoServer.
- *
- *
- * curl -u admin:geoserver -XPUT -H 'Content-type: text' -d "file:$ABSPORTDIR"
- * http://$GSIP:$GSPORT/$SERVLET/rest/workspaces/$WORKSPACE/coveragestores/$BAREDIR/external.imagemosaic
- *
- * @param workspace an existing workspace
- * @param storeName the name of the coverageStore to be created
- * @param mosaicDir the directory where the raster images are located
- * @param coverageEncoder the set of parameters to be set to the coverage (bbox, srs, ...)
- * @param layerEncoder the set of parameters to be set to the layer (defaultstyle, wmspath, ...)
- *
- * @return true if the operation completed successfully.
- *
- * @throws FileNotFoundException
- */
- public RESTCoverageStore publishExternalMosaic(String workspace, String storeName, File mosaicDir, GSCoverageEncoder coverageEncoder, GSLayerEncoder layerEncoder) throws FileNotFoundException {
- RESTCoverageStore store = configureExternaMosaicDatastore(workspace, storeName, mosaicDir);
-
- if (coverageEncoder == null) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("no coverageEncoder provided for " + workspace + ":" + storeName);
- }
- coverageEncoder = new GSCoverageEncoder();
- }
-
- if (layerEncoder == null) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("no layerEncoder provided for " + workspace + ":" + storeName);
- }
- layerEncoder = new GSLayerEncoder();
- }
-
- if (store != null) {
- try {
-// // retrieve coverage name
- GeoServerRESTReader reader = new GeoServerRESTReader(restURL, gsuser, gspass);
- RESTCoverageList covList = reader.getCoverages(store.getWorkspaceName(), storeName);
- if (covList.isEmpty()) {
- LOGGER.error("No coverages found in new coveragestore " + storeName);
- return null;
- }
- String coverageName = covList.get(0).getName();
-coverageEncoder.setName(FilenameUtils.getBaseName(mosaicDir.getName()));
- configureCoverage(coverageEncoder, workspace, storeName, coverageName);
-
- configureLayer(workspace, storeName, layerEncoder);
-
- } catch (Exception e) {
- if (LOGGER.isEnabledFor(Level.WARN))
- LOGGER.warn("Could not configure external mosaic:" + storeName, e);
- store = null; // TODO: should we remove the configured store?
- }
- }
-
- return store;
- }
-
- //==========================================================================
- //=== COVERAGES
- //==========================================================================
-
- /**
- * Remove the Coverage configuration from GeoServer.
- *
- * First, the associated layer is removed, then the Coverage configuration itself.
- *
You may also want to {@link #removeDatastore(String, String) remove the datastore}.
- *
- * @return true if the operation completed successfully.
- */
- public boolean unpublishFeatureType(String workspace, String storename, String layername) {
- try {
- // delete related layer
- URL deleteLayerUrl = new URL(restURL + "/rest/layers/" + layername);
- boolean layerDeleted = HTTPUtils.delete(deleteLayerUrl.toExternalForm(), gsuser, gspass);
- if (!layerDeleted) {
- LOGGER.warn("Could not delete layer '" + layername + "'");
- return false;
- }
- // delete the coverage
- URL deleteFtUrl = new URL(restURL + "/rest/workspaces/" + workspace + "/datastores/" + storename + "/featuretypes/" + layername);
- boolean ftDeleted = HTTPUtils.delete(deleteFtUrl.toExternalForm(), gsuser, gspass);
- if (!ftDeleted) {
- LOGGER.warn("Could not delete featuretype " + workspace + ":" + storename + "/" + layername + ", but layer was deleted.");
- } else {
- LOGGER.info("FeatureType successfully deleted " + workspace + ":" + storename + "/" + layername);
- }
-
- return ftDeleted;
-
- // the store is still there: should we delete it?
-
- } catch (MalformedURLException ex) {
- LOGGER.error(ex);
- return false;
- }
- }
-
- /**
- * Remove a given Datastore in a given Workspace.
- *
- * @param workspace The name of the workspace
- * @param storename The name of the Datastore to remove.
- * @return true if the datastore was successfully removed.
- */
- public boolean removeDatastore(String workspace, String storename) {
- try {
- URL deleteStore = new URL(restURL + "/rest/workspaces/" + workspace + "/datastores/" + storename);
- boolean deleted = HTTPUtils.delete(deleteStore.toExternalForm(), gsuser, gspass);
- if (!deleted) {
- LOGGER.warn("Could not delete datastore " + workspace + ":" + storename);
- } else {
- LOGGER.info("Datastore successfully deleted " + workspace + ":" + storename);
- }
-
- return deleted;
- } catch (MalformedURLException ex) {
- LOGGER.error(ex);
- return false;
- }
- }
-
- /**
- * Remove a given CoverageStore in a given Workspace.
- *
- * @param workspace The name of the workspace
- * @param storename The name of the CoverageStore to remove.
- * @return true if the CoverageStore was successfully removed.
- */
- public boolean removeCoverageStore(String workspace, String storename) {
- try {
- URL deleteStore = new URL(restURL + "/rest/workspaces/" + workspace + "/coveragestores/" + storename);
- boolean deleted = HTTPUtils.delete(deleteStore.toExternalForm(), gsuser, gspass);
- if (!deleted) {
- LOGGER.warn("Could not delete CoverageStore " + workspace + ":" + storename);
- } else {
- LOGGER.info("CoverageStore successfully deleted " + workspace + ":" + storename);
- }
-
- return deleted;
- } catch (MalformedURLException ex) {
- LOGGER.error(ex);
- return false;
- }
- }
-
- /**
- * Remove a given Workspace.
- *
- * @param workspace The name of the workspace
- * @return true if the WorkSpace was successfully removed.
- */
- public boolean removeWorkspace(String workspace) {
- workspace = sanitize(workspace);
- try {
- URL deleteUrl = new URL(restURL + "/rest/workspaces/" + workspace);
- boolean deleted = HTTPUtils.delete(deleteUrl.toExternalForm(), gsuser, gspass);
- if (!deleted) {
- LOGGER.warn("Could not delete Workspace " + workspace);
- } else {
- LOGGER.info("Workspace successfully deleted " + workspace);
- }
-
- return deleted;
- } catch (MalformedURLException ex) {
- LOGGER.error(ex);
- return false;
- }
- }
-
- /**
- * reload the target geoserver configuration
- * @return true if success
- *
- * @see http://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html
- */
- public boolean reload() {
- String sUrl = restURL + "/rest/reload";
- String result = HTTPUtils.post(sUrl, "", "text/plain", gsuser, gspass);
- return result != null;
- }
-
- /**
- * reset the target geoserver configuration
- * @return true if success
- *
- * @see http://docs.geoserver.org/stable/en/user/restconfig/rest-config-api.html
- */
- public boolean reset() {
- String sUrl = restURL + "/rest/reset";
- String result = HTTPUtils.post(sUrl, "", "text/plain", gsuser, gspass);
- return result != null;
- }
-
- public boolean removeLayerGroup(String name) {
- try {
- URL deleteUrl = new URL(restURL + "/rest/layergroups/" + name);
- boolean deleted = HTTPUtils.delete(deleteUrl.toExternalForm(), gsuser, gspass);
- if (!deleted) {
- LOGGER.warn("Could not delete layergroup " + name);
- } else {
- if (LOGGER.isInfoEnabled())
- LOGGER.info("Layergroup successfully deleted: " + name);
- }
-
- return deleted;
- } catch (MalformedURLException ex) {
- LOGGER.error(ex);
- return false;
- }
- }
-
- //==========================================================================
- //===
- //==========================================================================
-
- /**
- * @deprecated please use {@link configureLayer(String workspace, String layerName, GSLayerEncoder layer) }
- */
- public boolean configureLayer(final GSLayerEncoder layer, final String layerName)
- {
- return configureLayer(null, layerName, layer);
- }
-
- public boolean removeLayer(final String workspace, final String layerName) {
-
- final String fqLayerName;
-
- // this null check is here only for backward compatibility. workspace shall be mandatory.
- if(workspace == null) {
-
- fqLayerName = layerName;
-
- if (LOGGER.isEnabledFor(Level.WARN)){
- LOGGER.warn("Null workspace while removing layer : " + layerName + " -- This behavior is deprecated.");
- }
- } else {
- fqLayerName = workspace + ":" + layerName;
- }
- if (layerName==null) {
- if (LOGGER.isEnabledFor(Level.ERROR)){
- LOGGER.error("Null layerName : " + layerName);
- }
- return false;
- }
-
- final String url = restURL + "/rest/layers/" + fqLayerName;
-
- boolean result=HTTPUtils.delete(url, gsuser, gspass);
- if (result) {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info("Layer successfully removed: " + fqLayerName);
- }
- } else {
- if (LOGGER.isEnabledFor(Level.WARN))
- LOGGER.warn("Error removing layer " + fqLayerName);
- }
-
- return result;
- }
-
- /**
- * Allows to configure some layer attributes such as WmsPath and DefaultStyle
- *
- */
- public boolean configureLayer(final String workspace, final String layerName, final GSLayerEncoder layer) {
-
- // TODO: check this usecase, layer should always be defined
- if (layer.isEmpty()) {
- if (LOGGER.isEnabledFor(Level.WARN))
- LOGGER.warn("Null layer name while configuring layer -- This behavior is suspicious.");
- return true;
- }
-
- final String fqLayerName;
-
- // this null check is here only for backward compatibility. workspace shall be mandatory.
- if(workspace == null) {
-
- fqLayerName = layerName;
-
- if (LOGGER.isEnabledFor(Level.WARN)){
- LOGGER.warn("Null workspace while configuring layer : " + layerName + " -- This behavior is deprecated.");
- }
- } else {
- fqLayerName = workspace + ":" + layerName;
- }
-
- final String url = restURL + "/rest/layers/" + fqLayerName;
-
- String layerXml = layer.toString();
- String sendResult = HTTPUtils.putXml(url, layerXml, gsuser, gspass);
- if (sendResult != null) {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info("Layer successfully configured: " + fqLayerName);
- }
- } else {
- if (LOGGER.isEnabledFor(Level.WARN))
- LOGGER.warn("Error configuring layer " + fqLayerName + " (" + sendResult + ")");
- }
-
- return sendResult != null;
- }
-
- /**
- * Allows to configure some coverage's attributes
- *
- */
- protected boolean configureCoverage(final GSCoverageEncoder ce, String wsname, String csname, String cname) {
-
- final String url = restURL + "/rest/workspaces/" + wsname + "/coveragestores/" + csname + "/coverages/" + cname + ".xml";
-
- String xmlBody = ce.toString();
- String sendResult = HTTPUtils.putXml(url, xmlBody, gsuser, gspass);
- if (sendResult != null) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Coverage successfully configured " + wsname + ":" + csname + ":" + cname);
- }
- } else {
- if (LOGGER.isEnabledFor(Level.WARN))
- LOGGER.warn("Error configuring coverage " + wsname + ":" + csname + ":" + cname + " (" + sendResult + ")");
- }
-
- return sendResult != null;
- }
-
- /**
- *
- */
- protected String sanitize(String s) {
- if (s.indexOf(".") != -1) {
- return s + ".DUMMY";
- }
- return s;
- }
-
- protected String encode(String s) {
-// try {
-// return URLEncoder.encode(s,"UTF-8");
-// } catch (UnsupportedEncodingException e) {
-// LOGGER.warn("Error encoding :"+s+" with UTF-8: "+e.getLocalizedMessage());
- return URLEncoder.encode(s);
-// }
- }
+ protected String encode(String s) {
+ // try {
+ // return URLEncoder.encode(s,"UTF-8");
+ // } catch (UnsupportedEncodingException e) {
+ // LOGGER.warn("Error encoding :"+s+" with UTF-8: "+e.getLocalizedMessage());
+ return URLEncoder.encode(s);
+ // }
+ }
}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java
index 69b2863..04b8316 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java
@@ -68,7 +68,9 @@ public class RESTCoverageStore {
public static RESTCoverageStore build(String response) {
if(response == null)
return null;
-
+ if(response.isEmpty())
+ return new RESTCoverageStore(new Element("coverageStore")); // TODO check how to response
+
Element pb = JDOMBuilder.buildElement(response);
if(pb != null)
return new RESTCoverageStore(pb);
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java
index 07b3b04..ee7920c 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java
@@ -48,10 +48,11 @@ import org.jdom.filter.Filter;
*/
public abstract class GSResourceEncoder
* This method will be set as protected in the next release
- *
+ *
* @param minx
* @param maxy
* @param maxx
* @param miny
* @param crs
*/
- public void addLatLonBoundingBox(double minx, double maxy, double maxx,
- double miny, final String crs) {
+ public void addLatLonBoundingBox(double minx, double miny, double maxx,
+ double maxy, final String crs) {
add(LATLONBBMINX, String.valueOf(minx));
+ add(LATLONBBMINY, String.valueOf(miny));
add(LATLONBBMAXY, String.valueOf(maxy));
add(LATLONBBMAXX, String.valueOf(maxx));
- add(LATLONBBMINY, String.valueOf(miny));
add(LATLONBBCRS, crs);
}
- public void setLatLonBoundingBox(double minx, double maxy, double maxx,
- double miny, final String crs) {
+ public void setLatLonBoundingBox(double minx, double miny, double maxx,
+ double maxy, final String crs) {
set(LATLONBBMINX, String.valueOf(minx));
set(LATLONBBMAXY, String.valueOf(maxy));
set(LATLONBBMAXX, String.valueOf(maxx));
set(LATLONBBMINY, String.valueOf(miny));
set(LATLONBBCRS, crs);
}
-
- private final static String NATIVEBBMINX="nativeBoundingBox/minx";
- private final static String NATIVEBBMAXX="nativeBoundingBox/maxx";
- private final static String NATIVEBBMINY="nativeBoundingBox/miny";
- private final static String NATIVEBBMAXY="nativeBoundingBox/maxy";
- private final static String NATIVEBBCRS="nativeBoundingBox/crs";
-
+
+ private final static String NATIVEBBMINX = "nativeBoundingBox/minx";
+ private final static String NATIVEBBMAXX = "nativeBoundingBox/maxx";
+ private final static String NATIVEBBMINY = "nativeBoundingBox/miny";
+ private final static String NATIVEBBMAXY = "nativeBoundingBox/maxy";
+ private final static String NATIVEBBCRS = "nativeBoundingBox/crs";
+
/**
* @deprecated use the setSRS.
* This method will be set as protected in the next release
- *
+ *
* @param minx
* @param maxy
* @param maxx
* @param miny
* @param crs
*/
- public void addNativeBoundingBox(double minx, double maxy, double maxx,
- double miny, final String crs) {
+ public void addNativeBoundingBox(double minx, double miny, double maxx,
+ double maxy, final String crs) {
add(NATIVEBBMINX, String.valueOf(minx));
add(NATIVEBBMAXY, String.valueOf(maxy));
add(NATIVEBBMAXX, String.valueOf(maxx));
add(NATIVEBBMINY, String.valueOf(miny));
add(NATIVEBBCRS, crs);
}
-
- public void setNativeBoundingBox(double minx, double maxy, double maxx,
- double miny, final String crs) {
+
+ public void setNativeBoundingBox(double minx, double miny, double maxx,
+ double maxy, final String crs) {
set(NATIVEBBMINX, String.valueOf(minx));
set(NATIVEBBMAXY, String.valueOf(maxy));
set(NATIVEBBMAXX, String.valueOf(maxx));
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/coverage/GSImageMosaicEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/coverage/GSImageMosaicEncoder.java
index 0c1cfc0..f016d43 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/encoder/coverage/GSImageMosaicEncoder.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/coverage/GSImageMosaicEncoder.java
@@ -110,10 +110,10 @@ public class GSImageMosaicEncoder extends GSCoverageEncoder {
* @param val
*/
public void addFilter(final String val){
- final Element param=new Element(ENTRY);
- param.addContent(new Element(STRING).setText(filter));
- param.addContent(new Element(STRING).setText(val));
- parameters.add(null,param);
+ final List