diff --git a/src/restconfig/src/main/java/org/geoserver/catalog/rest/DataStoreFileResource.java b/src/restconfig/src/main/java/org/geoserver/catalog/rest/DataStoreFileResource.java index b81695fa64d..16e96477979 100644 --- a/src/restconfig/src/main/java/org/geoserver/catalog/rest/DataStoreFileResource.java +++ b/src/restconfig/src/main/java/org/geoserver/catalog/rest/DataStoreFileResource.java @@ -26,6 +26,8 @@ import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.NamespaceInfo; +import org.geoserver.catalog.ResourcePool; +import org.geoserver.platform.GeoServerResourceLoader; import org.geoserver.platform.resource.Resource; import org.geoserver.platform.resource.Resources; import org.geoserver.platform.resource.Resource.Type; @@ -150,23 +152,36 @@ public void handleGet() { if (info == null) { throw new RestletException("No such datastore " + datastore, Status.CLIENT_ERROR_NOT_FOUND); } - - Map params = info.getConnectionParameters(); + ResourcePool rp = info.getCatalog().getResourcePool(); + GeoServerResourceLoader resourceLoader = info.getCatalog().getResourceLoader(); + Map rawParamValues = info.getConnectionParameters(); + Map paramValues = rp.getParams(rawParamValues, resourceLoader); File directory = null; - for (Map.Entry e : params.entrySet()) { - if (e.getValue() instanceof File) { - directory = (File) e.getValue(); - } - else if (e.getValue() instanceof URL) { - directory = new File(((URL)e.getValue()).getFile()); - } - if (directory != null && !"directory".equals(e.getKey())) { - directory = directory.getParentFile(); - } - - if (directory != null) { - break; + try { + DataAccessFactory factory = rp.getDataStoreFactory(info); + for (Param param : factory.getParametersInfo()) { + if(File.class.isAssignableFrom(param.getType())) { + Object result = param.lookUp(paramValues); + if(result instanceof File) { + directory = (File) result; + } + } else if(URL.class.isAssignableFrom(param.getType())) { + Object result = param.lookUp(paramValues); + if(result instanceof URL) { + directory = new File(((URL)result).getFile()); + } + } + + if (directory != null && !"directory".equals(param.key)) { + directory = directory.getParentFile(); + } + + if (directory != null) { + break; + } } + } catch(Exception e) { + throw new RestletException( "Failed to lookup source directory for store " + datastore, Status.CLIENT_ERROR_NOT_FOUND, e); } if ( directory == null || !directory.exists() || !directory.isDirectory() ) { @@ -204,6 +219,9 @@ protected void write(Object object, OutputStream out) zout.close(); } }; + Form headers = RESTUtils.getHeaders(getResponse()); + headers.add("Content-type", "application/zip"); + headers.add("Content-disposition", "attachment; filename=" + info.getName() + ".zip"); getResponse().setEntity( fmt.toRepresentation( directory ) ); } diff --git a/src/restconfig/src/test/java/org/geoserver/catalog/rest/DataStoreFileUploadTest.java b/src/restconfig/src/test/java/org/geoserver/catalog/rest/DataStoreFileUploadTest.java index 0e36515793d..ab176f63af7 100644 --- a/src/restconfig/src/test/java/org/geoserver/catalog/rest/DataStoreFileUploadTest.java +++ b/src/restconfig/src/test/java/org/geoserver/catalog/rest/DataStoreFileUploadTest.java @@ -5,7 +5,12 @@ */ package org.geoserver.catalog.rest; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; @@ -18,7 +23,9 @@ import java.net.URL; import java.nio.charset.Charset; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; @@ -45,12 +52,12 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import org.springframework.mock.web.MockHttpServletResponse; +import org.terracotta.context.query.Matchers; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.springframework.mock.web.MockHttpServletResponse; - public class DataStoreFileUploadTest extends CatalogRESTTestSupport { @Override @@ -218,6 +225,24 @@ public void testShapeFileUploadExternal() throws Exception { dom = getAsDOM("wfs?request=getfeature&typename=gs:pds"); assertFeatures(dom); + + // try to download it again after a full reload from disk (GEOS-4616) + getGeoServer().reload(); + + resp = getAsServletResponse("/rest/workspaces/gs/datastores/pds/file.shp"); + assertEquals( 200, resp.getStatus() ); + assertEquals( "application/zip", resp.getContentType() ); + + Set entryNames = new HashSet<>(); + try(ByteArrayInputStream bin = getBinaryInputStream(resp); ZipInputStream zin = new ZipInputStream( bin )) { + ZipEntry entry; + while((entry= zin.getNextEntry()) != null) { + entryNames.add(entry.getName()); + } + } + assertTrue(entryNames.contains("pds.shp")); + assertTrue(entryNames.contains("pds.shx")); + assertTrue(entryNames.contains("pds.dbf")); } finally { FileUtils.deleteQuietly(f); } @@ -314,7 +339,7 @@ public void testShapefileUploadMultiple() throws Exception { } @Test - public void testGet() throws Exception { + public void testGetProperties() throws Exception { MockHttpServletResponse resp = getAsServletResponse("/rest/workspaces/gs/datastores/pds/file.properties"); assertEquals( 404, resp.getStatus() );