From 318be5853eb5d2a602cdb36920b37c383e830888 Mon Sep 17 00:00:00 2001 From: Alessio Fabiani Date: Wed, 7 Sep 2016 11:08:24 +0200 Subject: [PATCH] Add the Importer REST APIs to the GeoServer Manager (#198) * Pull Request for Issue #148 * Enabled check for Importer Test Case * Fixed Importer Test Case * fixed importer to execute the import contextually * - add missing maven repo * - align and update version --- pom.xml | 60 ++++ .../rest/GeoServerRESTPublisher.java | 61 ++++ .../geoserver/rest/HTTPUtils.java | 95 +++++- .../manager/GeoServerRESTImporterManager.java | 321 ++++++++++++++++++ .../publisher/GeoserverRESTImporterTest.java | 97 ++++++ 5 files changed, 633 insertions(+), 1 deletion(-) create mode 100644 src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImporterManager.java create mode 100644 src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTImporterTest.java diff --git a/pom.xml b/pom.xml index 5cd8d12..f31b4b0 100644 --- a/pom.xml +++ b/pom.xml @@ -108,6 +108,53 @@ http://build.geo-solutions.it/jenkins/view/GeoServer-manager/ + + + boundless + Boundless Maven Repository + https://repo.boundlessgeo.com/main/ + + + + + true + + + true + + + + + osgeo + Open Source Geospatial Foundation Repository + http://download.osgeo.org/webdav/geotools/ + + false + + + + + maven-restlet + Restlet Maven Repository + http://maven.restlet.org + + false + + + + + geosolutions + geosolutions repository + http://maven.geo-solutions.it/ + + true + + + true + + + + http://maven.geo-solutions.it @@ -237,6 +284,19 @@ 1.1 + + net.sf.json-lib + json-lib + 2.4 + jdk15 + + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.restlet + 1.1.10_3 + + org.slf4j slf4j-api diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java index 17a85ba..c68c533 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java +++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java @@ -42,6 +42,7 @@ import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder; import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredGridCoverageReaderManager; import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredGridCoverageReaderManager.ConfigureCoveragesOption; import it.geosolutions.geoserver.rest.manager.GeoServerRESTStyleManager; +import it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager; import java.io.File; import java.io.FileNotFoundException; @@ -58,6 +59,8 @@ import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import net.sf.json.JSONObject; + /** * Connect to a GeoServer instance to publish or modify its contents via REST API. *

@@ -91,6 +94,9 @@ public class GeoServerRESTPublisher { private final GeoServerRESTStyleManager styleManager; + + private final GeoServerRESTImporterManager importerManager; + /** * Creates a GeoServerRESTPublisher to connect against a GeoServer instance with the given URL and user credentials. * @@ -110,6 +116,7 @@ public class GeoServerRESTPublisher { LOGGER.error("Bad URL: Calls to GeoServer are going to fail" , ex); } styleManager = new GeoServerRESTStyleManager(url, username, password); + importerManager = new GeoServerRESTImporterManager(url, username, password); } // ========================================================================== @@ -3145,4 +3152,58 @@ public class GeoServerRESTPublisher { } + /** + * Refers to {@link it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager#postNewImport() postNewImport} method + * + * @throws Exception + */ + public int postNewImport() throws Exception { + return importerManager.postNewImport(); + } + + /** + * Refers to {@link it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager#postNewTaskAsMultiPartForm(int, String) postNewTaskAsMultiPartForm} method + * + * @throws Exception + */ + public int postNewTaskAsMultiPartForm(int i, String data) throws Exception { + return importerManager.postNewTaskAsMultiPartForm(i, data); + } + + /** + * Refers to {@link it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager#getTask(int, int) getTask} method + * + * @throws Exception + */ + public JSONObject getTask(int i, int t) throws Exception { + return importerManager.getTask(i, t); + } + + /** + * Refers to {@link it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager#putTask(int, int, String) putTask} method + * + * @throws Exception + */ + public void putTask(int i, int t, String json) throws Exception { + importerManager.putTask(i, t, json); + } + + /** + * Refers to {@link it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager#putTaskLayer(int, int, String) putTaskLayer} method + * + * @throws Exception + */ + public void putTaskLayer(int i, int t, String json) throws Exception { + importerManager.putTaskLayer(i, t, json); + } + + /** + * Refers to {@link it.geosolutions.geoserver.rest.manager.GeoServerRESTImporterManager#postImport(int) postImport} method + * + * @throws Exception + */ + public void postImport(int i) throws Exception { + importerManager.postImport(i); + } + } diff --git a/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java b/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java index f3cc6e6..d885dd0 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java +++ b/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java @@ -25,6 +25,7 @@ package it.geosolutions.geoserver.rest; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -33,6 +34,11 @@ import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import net.sf.json.JSON; +import net.sf.json.JSONSerializer; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; @@ -48,6 +54,9 @@ import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.methods.multipart.FilePart; +import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; +import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -117,6 +126,22 @@ public class HTTPUtils { return null; } + /** + * Executes a request using the GET method and parses the result as a json object. + * + * @param path The path to request. + * + * @return The result parsed as json. + */ + public static JSON getAsJSON(String url, String username, String pw) throws Exception { + String response = get(url, username, pw); + return json(response); + } + + public static JSON json(String content) { + return JSONSerializer.toJSON(content); + } + /** * PUTs a File to the given URL.
* Basic auth is used if both username and pw are not null. @@ -175,6 +200,23 @@ public class HTTPUtils { return put(url, content, "text/xml", username, pw); } + /** + * PUTs a String representing an JSON Object to the given URL.
+ * Basic auth is used if both username and pw are not null. + * + * @param url The URL where to connect to. + * @param content The JSON Object to be sent as a String. + * @param username Basic auth credential. No basic auth if null. + * @param pw Basic auth credential. No basic auth if null. + * @return The HTTP response as a String if the HTTP response code was 200 + * (OK). + * @throws MalformedURLException + * @return the HTTP response or null on errors. + */ + public static String putJson(String url, String content, String username, String pw) { + return put(url, content, "application/json", username, pw); + } + /** * Performs a PUT to the given URL.
* Basic auth is used if both username and pw are not null. @@ -233,6 +275,38 @@ public class HTTPUtils { } } + /** + * POSTs a list of files as attachments to the given URL.
+ * Basic auth is used if both username and pw are not null. + * + * @param url The URL where to connect to. + * @param dir The folder containing the attachments. + * @param username Basic auth credential. No basic auth if null. + * @param pw Basic auth credential. No basic auth if null. + * @return The HTTP response as a String if the HTTP response code was 200 + * (OK). + * @throws MalformedURLException + * @return the HTTP response or null on errors. + */ + public static String postMultipartForm(String url, File dir, String username, String pw) { + try { + List parts = new ArrayList(); + for (File f : dir.listFiles()) { + parts.add(new FilePart(f.getName(), f)); + } + MultipartRequestEntity multipart = new MultipartRequestEntity( + parts.toArray(new Part[parts.size()]), new PostMethod().getParams()); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + multipart.writeRequest(bout); + + return post(url, multipart, username, pw); + } catch (Exception ex) { + LOGGER.error("Cannot POST " + url, ex); + return null; + } + } + /** * POSTs a String representing an XML document to the given URL.
* Basic auth is used if both username and pw are not null. @@ -250,6 +324,23 @@ public class HTTPUtils { return post(url, content, "text/xml", username, pw); } + /** + * POSTs a String representing an JSON Object to the given URL.
+ * Basic auth is used if both username and pw are not null. + * + * @param url The URL where to connect to. + * @param content The JSON content to be sent as a String. + * @param username Basic auth credential. No basic auth if null. + * @param pw Basic auth credential. No basic auth if null. + * @return The HTTP response as a String if the HTTP response code was 200 + * (OK). + * @throws MalformedURLException + * @return the HTTP response or null on errors. + */ + public static String postJson(String url, String content, String username, String pw) { + return post(url, content, "application/json", username, pw); + } + /** * Performs a POST to the given URL.
* Basic auth is used if both username and pw are not null. @@ -293,6 +384,7 @@ public class HTTPUtils { httpMethod.setRequestEntity(requestEntity); int status = client.executeMethod(httpMethod); + InputStream responseBody; switch (status) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_CREATED: @@ -303,9 +395,10 @@ public class HTTPUtils { LOGGER.info("HTTP " + httpMethod.getStatusText() + ": " + response); return response; default: + responseBody = httpMethod.getResponseBodyAsStream(); LOGGER.warn("Bad response: code[" + status + "]" + " msg[" + httpMethod.getStatusText() + "]" + " url[" + url + "]" + " method[" + httpMethod.getClass().getSimpleName() - + "]: " + IOUtils.toString(httpMethod.getResponseBodyAsStream())); + + "]: " + (responseBody != null ? IOUtils.toString(responseBody) : "")); return null; } } catch (ConnectException e) { diff --git a/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImporterManager.java b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImporterManager.java new file mode 100644 index 0000000..ccf39e1 --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImporterManager.java @@ -0,0 +1,321 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package it.geosolutions.geoserver.rest.manager; + +import it.geosolutions.geoserver.rest.HTTPUtils; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import net.sf.json.JSON; +import net.sf.json.JSONObject; + +import org.restlet.data.MediaType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Alessio Fabiani, GeoSolutions S.A.S. + * + */ +public class GeoServerRESTImporterManager extends GeoServerRESTAbstractManager { + + private final static Logger LOGGER = LoggerFactory.getLogger(GeoServerRESTImporterManager.class); + + /** + * Default constructor. + * + * @param restURL GeoServer REST API endpoint + * @param username GeoServer REST API authorized username + * @param password GeoServer REST API password for the former username + */ + public GeoServerRESTImporterManager(URL restURL, String username, String password) + throws IllegalArgumentException { + super(restURL, username, password); + } + + /** + * Retrieves the Import JSON Object given its identifier + * + * @param imp int: Import context number ID + */ + public JSONObject getImport(int imp) throws Exception { + JSON json = HTTPUtils.getAsJSON(String.format(buildUrl()+"/%d", imp), gsuser , gspass); + return ((JSONObject)json).getJSONObject("import"); + } + + /** + * Retrieves the Import Task JSON Object given its identifier and task number + * + * @param imp int: Import context number ID + * @param task int: Task number + */ + public JSONObject getTask(int imp, int task) throws Exception { + JSON json = HTTPUtils.getAsJSON(String.format(buildUrl()+"/%d/tasks/%d?expand=all", imp, task), gsuser , gspass); + return ((JSONObject)json).getJSONObject("task"); + } + + /** + * Example usage: + *

+     *  // Creates a new Importer Context and gets back the ID
+     *  int i = postNewImport();
+     *  
+     *  // Attaches to the new Importer Context a Task pointing to a shapefile's zip archive
+     *  int t = postNewTaskAsMultiPartForm(i, "/path_to/shape/archsites_no_crs.zip");
+     *
+     *  // Check that the Task was actually created and that the CRS has not recognized in this case
+     *  JSONObject task = getTask(i, t);
+     *  assertEquals("NO_CRS", task.getString("state"));
+     *  
+     *  // Prepare the JSON String instructing the Task about the SRS to use
+     *  String json = 
+     *  "{" +
+     *    "\"task\": {" +
+     *      "\"layer\": {" +
+     *              "\"srs\": \"EPSG:4326\"" + 
+     *       "}" +
+     *     "}" + 
+     *  "}";
+     *  
+     *  // Performing the Task update
+     *  putTask(i, t, json);
+     *
+     *  // Double check that the Task is in the READY state
+     *  task = getTask(i, t);
+     *  assertEquals("READY", task.getString("state"));
+     *  assertEquals("gs_archsites", task.getJSONObject("layer").getJSONObject("style").getString("name"));
+     *  
+     *  // Prepare the JSON String instructing the Task avout the SLD to use for the new Layer
+     *  json = 
+     *  "{" +
+     *    "\"task\": {" +
+     *      "\"layer\": {" +
+     *        "\"style\": {" +
+     *              "\"name\": \"point\"" + 
+     *           "}" +
+     *         "}" +
+     *     "}" + 
+     *  "}";
+     *  
+     *  // Performing the Task update
+     *  putTask(i, t,json);
+     *
+     *  // Double check that the Task is in the READY state and that the Style has been correctly updated
+     *  task = getTask(i, t);
+     *  assertEquals("READY", task.getString("state"));
+     *  assertEquals("point", task.getJSONObject("layer").getJSONObject("style").getString("name"));
+     *  
+     *  // Finally starts the Import ...
+     *  postImport(i);
+     * 
+ * + * @param imp int: Import context number ID + * @param task int: Task number + * @param json String: JSON containing the Task properties to be updated + * @throws Exception + */ + public void putTask(int imp, int task, final String json) throws Exception { + //HTTPUtils.putJson(String.format(buildUrl()+"/%d/tasks/%d", imp, task), json, gsuser, gspass); + HTTPUtils.put(String.format(buildUrl()+"/%d/tasks/%d", imp, task), json, "text/plain", gsuser, gspass); + } + + /** + * Just update the Layers properties associated to a Task (t) in the Importer Context (i). + * + * e.g.: + *
+     * putTaskLayer(i, t, "{\"title\":\"Archsites\", \"abstract\":\"Archeological Sites\"}");
+     * 
+ * + * @param imp int: Import context number ID + * @param task int: Task number + * @param json String: JSON containing the Layer properties to be updated + * @throws Exception + */ + public void putTaskLayer(int imp, int task, final String json) throws Exception { + HTTPUtils.putJson(String.format(buildUrl()+"/%d/tasks/%d/layer", imp, task), json, gsuser, gspass); + } + + /** + * Just update the Layers properties associated to a Task (t) in the Importer Context (i). + * + * e.g.: + *
+     * putTaskLayer(i, t, "{\"title\":\"Archsites\", \"abstract\":\"Archeological Sites\"}");
+     * 
+ * + * @param imp int: Import context number ID + * @param task int: Task number + * @param json String: JSON containing the Layer properties to be updated + * @throws Exception + */ + public void postTaskTransform(int imp, int task, final String json) throws Exception { + HTTPUtils.postJson(String.format(buildUrl()+"/%d/tasks/%d/transforms", imp, task), json, gsuser, gspass); + } + + /** + * Creates an empty Importer Context. + * + * @return The new Importer Context ID + * @throws Exception + */ + public int postNewImport() throws Exception { + return postNewImport(null); + } + + /** + * e.g.: + *
+     * String body = 
+     *         "{" + 
+     *              "\"import\": { " + 
+     *                  "\"data\": {" +
+     *                     "\"type\": \"mosaic\", " + 
+     *                     "\"time\": {" +
+     *                        " \"mode\": \"auto\"" + 
+     *                     "}" + 
+     *                   "}" +
+     *              "}" + 
+     *         "}";
+     * 
+ * + * @param body JSON String representing the Importer Context definition + * @return The new Importer Context ID + * @throws Exception + */ + public int postNewImport(String body) throws Exception { + String resp = body == null ? HTTPUtils.post(buildUrl(), "", "text/plain", gsuser, gspass) + : HTTPUtils.postJson(buildUrl(), body, gsuser, gspass); + + JSONObject json = (JSONObject) HTTPUtils.json(resp); + JSONObject imprt = json.getJSONObject("import"); + return imprt.getInt("id"); + } + + /** + * Actually starts the READY State Import. + * + * @param imp int: Import context number ID + * @throws Exception + */ + public void postImport(int imp) throws Exception { + HTTPUtils.post(buildUrl()+"/" + imp + "?exec=true", "", "text/plain", gsuser, gspass); + } + + /** + * + * @param imp int: Import context number ID + * @param data + * @return + * @throws Exception + */ + public int postNewTaskAsMultiPartForm(int imp, String data) throws Exception { + String resp = HTTPUtils.postMultipartForm(buildUrl()+"/" + imp + "/tasks", unpack(data), gsuser, gspass); + + JSONObject json = (JSONObject) HTTPUtils.json(resp); + + JSONObject task = json.getJSONObject("task"); + return task.getInt("id"); + } + + /** + * Allows to attach a new zip file to an existing Importer Context. + * + * @param imp int: Import context number ID + * @param path + * @return + * @throws Exception + */ + public int putNewTask(int imp, String path) throws Exception { + File zip = new File(path); + + String resp = HTTPUtils.put(buildUrl()+"/" + imp + "/tasks/" + zip.getName(), zip, MediaType.APPLICATION_ZIP.toString(), gsuser, gspass); + + JSONObject json = (JSONObject) HTTPUtils.json(resp); + + JSONObject task = json.getJSONObject("task"); + return task.getInt("id"); + } + + //========================================================================= + // Util methods + //========================================================================= + + /** + * Creates the base REST URL for the imports + */ + protected String buildUrl() { + StringBuilder sUrl = new StringBuilder(gsBaseUrl.toString()).append("/rest/imports"); + + return sUrl.toString(); + } + + /** + * Creates a temporary file + * + * @return Path to the temporary file + * @throws Exception + */ + public static File tmpDir() throws Exception { + File dir = File.createTempFile("importer", "data", new File("target")); + dir.delete(); + dir.mkdirs(); + return dir; + } + + /** + * Expands a zip archive into the temporary folder. + * + * @param path The absolute path to the source zip file + * @return Path to the temporary folder containing the expanded files + * @throws Exception + */ + public static File unpack(String path) throws Exception { + return unpack(path, tmpDir()); + } + + /** + * Expands a zip archive into the target folder. + * + * @param path The absolute path to the source zip file + * @param dir Full path of the target folder where to expand the archive + * @return Path to the temporary folder containing the expanded files + * @throws Exception + */ + public static File unpack(String path, File dir) throws Exception { + + File file = new File(path); + + //new VFSWorker().extractTo(file, dir); + if (!file.delete()) { + // fail early as tests will expect it's deleted + throw new IOException("deletion failed during extraction"); + } + + return dir; + } +} diff --git a/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTImporterTest.java b/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTImporterTest.java new file mode 100644 index 0000000..bcb962a --- /dev/null +++ b/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTImporterTest.java @@ -0,0 +1,97 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package it.geosolutions.geoserver.rest.publisher; + +import static org.junit.Assert.assertEquals; +import it.geosolutions.geoserver.rest.GeoserverRESTTest; +import net.sf.json.JSONObject; + +import org.junit.After; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; + +/** + * Testcase for publishing layers on geoserver. + * We need a running GeoServer to properly run the tests. + * If such geoserver instance cannot be contacted, tests will be skipped. + * + * @author Alessio Fabiani, GeoSolutions S.A.S. + * + */ +public class GeoserverRESTImporterTest extends GeoserverRESTTest { + + private final static Logger LOGGER = LoggerFactory.getLogger(GeoserverRESTImporterTest.class); + + @After + public void cleanUp() { + } + + @Test + public void testShapeFileImport() throws Exception { + if (!enabled()) + return; + + // Creates a new Importer Context and gets back the ID + int i = publisher.postNewImport(); + + // Attaches to the new Importer Context a Task pointing to a shapefile's zip archive + String data = new ClassPathResource("testdata/test_noepsg.zip").getFile().getAbsolutePath(); + int t = publisher.postNewTaskAsMultiPartForm(i, data); + + // Check that the Task was actually created and that the CRS has not recognized in this case + JSONObject task = publisher.getTask(i, t); + //assertEquals("NO_CRS", task.getString("state")); + assertEquals("READY", task.getString("state")); + + // Prepare the JSON String instructing the Task about the SRS to use + String json = "{\"layer\":{\"srs\":\"EPSG:26713\"}}"; + + // Performing the Task update + publisher.putTaskLayer(i, t, json); + + // Double check that the Task is in the READY state + task = publisher.getTask(i, t); + assertEquals("READY", task.getString("state")); + assertEquals("nurc_10m_populated_places", task.getJSONObject("layer").getJSONObject("style").getString("name")); + + // Prepare the JSON String instructing the Task avout the SLD to use for the new Layer + json = "{\"layer\":{\"style\":{\"name\": \"point\"}}}"; + + // Performing the Task update + publisher.putTaskLayer(i, t,json); + + // Double check that the Task is in the READY state and that the Style has been correctly updated + task = publisher.getTask(i, t); + assertEquals("READY", task.getString("state")); + assertEquals("point", task.getJSONObject("layer").getJSONObject("style").getString("name")); + + // Finally starts the Import ... + publisher.postImport(i); + } + +}