From: Richard Millet Date: Wed, 20 Jun 2012 20:54:49 +0000 (-0700) Subject: CSPACE-4789: Added support for a query param impTimout that specifies a timeout perio... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=d1c8f34156d5879718eff95cea8cb5964bd2924a;p=tmp%2Fjakarta-migration.git CSPACE-4789: Added support for a query param impTimout that specifies a timeout period in seconds -the default is 600 --- diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/xml-replay-master.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/xml-replay-master.xml index 5f166ffae..afd1e00a2 100644 --- a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/xml-replay-master.xml +++ b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/xml-replay-master.xml @@ -33,32 +33,25 @@ File below this line have been ported. --> - - - - diff --git a/services/client/src/main/java/org/collectionspace/services/client/IClientQueryParams.java b/services/client/src/main/java/org/collectionspace/services/client/IClientQueryParams.java index 5b7077b7a..40a67a8b8 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/IClientQueryParams.java +++ b/services/client/src/main/java/org/collectionspace/services/client/IClientQueryParams.java @@ -31,5 +31,6 @@ public interface IClientQueryParams { public static final String PAGE_SIZE_PARAM = "pgSz"; public static final String START_PAGE_PARAM = "pgNum"; public static final String SORT_BY_PARAM = "sortBy"; + public static final String IMPORT_TIMEOUT_PARAM = "impTimout"; } diff --git a/services/imports/service/src/main/java/org/collectionspace/services/imports/ImportsResource.java b/services/imports/service/src/main/java/org/collectionspace/services/imports/ImportsResource.java index 64dc39b01..158efbbf2 100644 --- a/services/imports/service/src/main/java/org/collectionspace/services/imports/ImportsResource.java +++ b/services/imports/service/src/main/java/org/collectionspace/services/imports/ImportsResource.java @@ -24,6 +24,7 @@ package org.collectionspace.services.imports; import org.collectionspace.authentication.AuthN; +import org.collectionspace.services.client.IClientQueryParams; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl; @@ -56,7 +57,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriInfo; import java.io.ByteArrayInputStream; @@ -73,303 +74,400 @@ import java.util.Map; * @author Laramie Crocker */ @Path(ImportsResource.SERVICE_PATH) -@Produces({"application/xml"}) -@Consumes({"application/xml"}) -public class ImportsResource extends AbstractCollectionSpaceResourceImpl { - - public static final String SERVICE_NAME = "imports"; - public static final String SERVICE_PATH = "/" + SERVICE_NAME; - - /* - * ASSUMPTION: All Nuxeo services of a given tenancy store their stuff in the same repository domain under - * the "workspaces" directory. - * - * Using the tenant ID of the currently authenticated user, this method returns the repository domain name of the - * current tenancy. - */ - private static String getWorkspaces() throws ConfigurationException { - String result = null; - - TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader(); - TenantBindingType tenantBinding = tReader.getTenantBinding(AuthN.get().getCurrentTenantId()); - List repositoryDomainList = tenantBinding.getRepositoryDomain(); - if (repositoryDomainList.size() == 1) { - String domainName = repositoryDomainList.get(0).getStorageName().trim(); - result = "/" + domainName + "/" + NuxeoUtils.Workspaces; - } else { - throw new ConfigurationException("Tenant bindings contains 0 or more than 1 repository domains."); - } - - return result; - } - - @Override - public String getServiceName(){ - return SERVICE_NAME; - } - - @Override - protected String getVersionString() { - final String lastChangeRevision = "$LastChangedRevision: 2108 $"; - return lastChangeRevision; - } - - @Override - public Class getCommonPartClass() { - return ImportsCommon.class; - } - - @Override - public ServiceContextFactory getServiceContextFactory() { - return MultipartServiceContextFactory.get(); - } - - private static String _templateDir = null; - public static String getTemplateDir(){ - if (_templateDir == null){ - TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader(); - _templateDir = tReader.getResourcesDir()+File.separator+"templates"; - } - return _templateDir; - } - - @POST - public Response create(@Context UriInfo ui, String xmlPayload) { - try { - return this.create(xmlPayload); - } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.CREATE_FAILED); - } - } - /** you can test this with something like: - * curl -X POST http://localhost:8180/cspace-services/imports -i -u "Admin@collectionspace.org:Administrator" -H "Content-Type: application/xml" -T in.xml - * -T /src/trunk/services/imports/service/src/main/resources/templates/authority-request.xml - */ - @POST - @Consumes("application/xml") - @Produces("application/xml") - public javax.ws.rs.core.Response create(String xmlPayload) { - String result; - javax.ws.rs.core.Response.ResponseBuilder rb; - try { - //InputSource inputSource = payloadToInputSource(xmlPayload); - //result = createFromInputSource(inputSource); - String inputFilename = payloadToFilename(xmlPayload); - result = createFromFilename(inputFilename); - rb = javax.ws.rs.core.Response.ok(); - } catch (Exception e) { - result = Tools.errorToString(e, true); - rb = javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR); - } - rb.entity(result); - return rb.build(); - } - - public static String createFromInputSource(InputSource inputSource) throws Exception { - String tenantId = AuthN.get().getCurrentTenantId(); - // We must expand the request and wrap it with all kinds of Nuxeo baggage, which expandXmlPayloadToDir knows how to do. - String outputDir = FileTools.createTmpDir("imports-").getCanonicalPath(); - File outpd = new File(outputDir); - outpd.mkdirs(); - expandXmlPayloadToDir(tenantId, inputSource, getTemplateDir(), outpd.getCanonicalPath()); - - // Next, call the nuxeo import service, pointing it to our local directory that has the expanded request. - ImportCommand importCommand = new ImportCommand(); -// String destWorkspaces = "/default-domain/workspaces"; - String destWorkspaces = getWorkspaces(); - String result = ""; - try { - String report = "NORESULTS"; - report = importCommand.run(outputDir, destWorkspaces); - result = "SUCCESS"+report+""; - } catch (Exception e){ - result = "ERROR"+Tools.errorToString(e, true)+""; - } - return result; - } - - public static String createFromFilename(String filename) throws Exception { - String tenantId = AuthN.get().getCurrentTenantId(); - // We must expand the request and wrap it with all kinds of Nuxeo baggage, which expandXmlPayloadToDir knows how to do. - String outputDir = FileTools.createTmpDir("imports-").getCanonicalPath(); - File outpd = new File(outputDir); - outpd.mkdirs(); - expandXmlPayloadToDir(tenantId, filename, getTemplateDir(), outpd.getCanonicalPath()); - - // Next, call the nuxeo import service, pointing it to our local directory that has the expanded request. - ImportCommand importCommand = new ImportCommand(); -// String destWorkspaces = "/default-domain/workspaces"; - String destWorkspaces = getWorkspaces(); - String result = ""; - try { - String report = "NORESULTS"; - report = importCommand.run(outputDir, destWorkspaces); - result = "SUCCESS"+report+""; - } catch (Exception e){ - result = "ERROR"+Tools.errorToString(e, true)+""; - } - return result; - } - - - /** @param xmlPayload A request file has a specific format, you can look at: - * trunk/services/imports/service/src/test/resources/requests/authority-request.xml - */ - public static InputSource payloadToInputSource(String xmlPayload) throws Exception { - xmlPayload = encodeAmpersands(xmlPayload); - String requestDir = FileTools.createTmpDir("imports-request-").getCanonicalPath(); - File requestFile = - FileTools.saveFile(requestDir, "request.xml", xmlPayload, FileTools.FORCE_CREATE_PARENT_DIRS, FileTools.UTF8_ENCODING); - if (requestFile == null){ - throw new FileNotFoundException("Could not create file in requestDir: "+requestDir); - } - String requestFilename = requestFile.getCanonicalPath(); - InputSource inputSource = new InputSource(requestFilename); - System.out.println("############## REQUEST_FILENAME: "+requestFilename); - return inputSource; - } - - public static String payloadToFilename(String xmlPayload) throws Exception { - xmlPayload = encodeAmpersands(xmlPayload); - String requestDir = FileTools.createTmpDir("imports-request-").getCanonicalPath(); - File requestFile = - FileTools.saveFile(requestDir, "request.xml", xmlPayload, FileTools.FORCE_CREATE_PARENT_DIRS, FileTools.UTF8_ENCODING); - if (requestFile == null){ - throw new FileNotFoundException("Could not create file in requestDir: "+requestDir); - } - String requestFilename = requestFile.getCanonicalPath(); - System.out.println("############## REQUEST_FILENAME: "+requestFilename); - return requestFilename; - } - - /** - * Encodes each ampersand ('&') in the incoming XML payload by replacing - * it with the predefined XML entity for an ampersand ('&'). - * - * This is a workaround for the issue described in CSPACE-3911. Its - * intended effect is to have these added ampersand XML entities being - * resolved to 'bare' ampersands during the initial parse, thus preserving - * any XML entities in the payload, which will then be resolved correctly - * during the second parse. - * - * (This is not designed to compensate for instances where the incoming - * XML payload contains 'bare' ampersands - that is, used in any other - * context than as the initial characters in XML entities. In those cases, - * the payload may not be a legal XML document.) - * - * @param xmlPayload - * @return The original XML payload, with each ampersand replaced by - * the predefined XML entity for an ampersand. - */ - private static String encodeAmpersands(String xmlPayload) { - return xmlPayload.replace("&", "&"); - } - - public static void expandXmlPayloadToDir(String tenantId, String inputFilename, String templateDir, String outputDir) throws Exception { - System.out.println("############## TEMPLATE_DIR: "+templateDir); - System.out.println("############## OUTPUT_DIR:"+outputDir); - File file = new File(inputFilename); - FileInputStream is = new FileInputStream(file); - InputSource inputSource = new InputSource(is); - TemplateExpander.expandInputSource(tenantId, templateDir, outputDir, inputSource, "/imports/import"); - } - - /** This method may be called statically from outside this class; there is a test call in - * org.collectionspace.services.test.ImportsServiceTest - * - * @param inputSource A wrapper around a request file, either a local file or a stream; - * the file has a specific format, you can look at: - * trunk/services/imports/service/src/test/resources/requests/authority-request.xml - * @param templateDir The local directory where templates are to be found at runtime. - * @param outputDir The local directory where expanded files and directories are found, ready to be passed to the Nuxeo importer. - */ - public static void expandXmlPayloadToDir(String tenantId, InputSource inputSource, String templateDir, String outputDir) throws Exception { - System.out.println("############## TEMPLATE_DIR: "+templateDir); - System.out.println("############## OUTPUT_DIR:"+outputDir); - TemplateExpander.expandInputSource(tenantId, templateDir, outputDir, inputSource, "/imports/import"); - //TemplateExpander.expandInputSource(templateDir, outputDir, inputFilename, "/imports/import"); - } - - /** you can test like this: - * curl -F "file=@out.zip;type=application/zip" --basic -u "Admin@collectionspace.org:Administrator" http://localhost:8280/cspace-services/imports - */ - @POST - @Consumes("multipart/form-data") - @Produces("application/xml") - public javax.ws.rs.core.Response acceptUpload(@Context HttpServletRequest req, - MultipartFormDataInput partFormData) { - javax.ws.rs.core.Response response = null; - StringBuffer resultBuf = new StringBuffer(); - try { - InputStream fileStream = null; - String preamble = partFormData.getPreamble(); - System.out.println("Preamble type is:" + preamble); - Map> partsMap = partFormData.getFormDataMap(); - List fileParts = partsMap.get("file"); - for (InputPart part : fileParts){ - String mediaType = part.getMediaType().toString(); - System.out.println("Media type is:" + mediaType); - if (mediaType.equalsIgnoreCase(MediaType.APPLICATION_XML) || mediaType.equalsIgnoreCase(MediaType.TEXT_XML)){ - // FIXME For an alternate approach, potentially preferable, see: - // http://stackoverflow.com/questions/4586222/right-way-of-formatting-an-input-stream - String str = encodeAmpersands(part.getBodyAsString()); - InputStream stream = new ByteArrayInputStream(str.getBytes("UTF8")); - InputSource inputSource = new InputSource(stream); - // InputSource inputSource = new InputSource(part.getBody(InputStream.class, null)); - String result = createFromInputSource(inputSource); - resultBuf.append(result); - continue; - } - if (mediaType.equalsIgnoreCase("application/zip")){ - fileStream = part.getBody(InputStream.class, null); - - File zipfile = FileUtils.createTmpFile(fileStream, getServiceName() + "_"); - String zipfileName = zipfile.getCanonicalPath(); - System.out.println("Imports zip file saved to:" + zipfileName); - - String baseOutputDir = FileTools.createTmpDir("imports-").getCanonicalPath(); - File indir = new File(baseOutputDir+"/in"); - indir.mkdir(); - ZipTools.unzip(zipfileName, indir.getCanonicalPath()); - String result = "\r\nZipfile " + zipfileName + "extracted to: " + indir.getCanonicalPath()+""; - System.out.println(result); - - long start = System.currentTimeMillis(); - //TODO: now call import service... - resultBuf.append(result); - continue; - } - } - javax.ws.rs.core.Response.ResponseBuilder rb = javax.ws.rs.core.Response.ok(); - rb.entity(resultBuf.toString()); - response = rb.build(); - } catch (Exception e) { - throw bigReThrow(e, ServiceMessages.CREATE_FAILED); - } - return response; - } - - String page = "\n" - + "\n" - + " \n" - + " CollectionSpace Import\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "
\n" - + " Choose a file to import:" - + " \n" - + "
\n" - + " \n" - + "
\n" - + " \n" - + "\n"; - @GET - @Produces("text/html") +@Produces({ "application/xml" }) +@Consumes({ "application/xml" }) +public class ImportsResource extends AbstractCollectionSpaceResourceImpl { + + public static final String SERVICE_NAME = "imports"; + public static final String SERVICE_PATH = "/" + SERVICE_NAME; + private static final int DEFAULT_TX_TIMOUT = 600; // timeout period in + // seconds + + /* + * ASSUMPTION: All Nuxeo services of a given tenancy store their stuff in + * the same repository domain under the "workspaces" directory. + * + * Using the tenant ID of the currently authenticated user, this method + * returns the repository domain name of the current tenancy. + */ + private static String getWorkspaces() throws ConfigurationException { + String result = null; + + TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance() + .getTenantBindingConfigReader(); + TenantBindingType tenantBinding = tReader.getTenantBinding(AuthN.get() + .getCurrentTenantId()); + List repositoryDomainList = tenantBinding + .getRepositoryDomain(); + if (repositoryDomainList.size() == 1) { + String domainName = repositoryDomainList.get(0).getStorageName() + .trim(); + result = "/" + domainName + "/" + NuxeoUtils.Workspaces; + } else { + throw new ConfigurationException( + "Tenant bindings contains 0 or more than 1 repository domains."); + } + + return result; + } + + @Override + public String getServiceName() { + return SERVICE_NAME; + } + + @Override + protected String getVersionString() { + final String lastChangeRevision = "$LastChangedRevision: 2108 $"; + return lastChangeRevision; + } + + @Override + public Class getCommonPartClass() { + return ImportsCommon.class; + } + + @Override + public ServiceContextFactory getServiceContextFactory() { + return MultipartServiceContextFactory.get(); + } + + private static String _templateDir = null; + + public static String getTemplateDir() { + if (_templateDir == null) { + TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance() + .getTenantBindingConfigReader(); + _templateDir = tReader.getResourcesDir() + File.separator + + "templates"; + } + return _templateDir; + } + + // @POST + // public Response create(@Context UriInfo ui, String xmlPayload) { + // try { + // return this.create(xmlPayload); + // } catch (Exception e) { + // throw bigReThrow(e, ServiceMessages.CREATE_FAILED); + // } + // } + + private int getTimeoutParam(UriInfo ui) { + int result = DEFAULT_TX_TIMOUT; + + MultivaluedMap queryParams = ui.getQueryParameters(); + if (queryParams != null) { + String timeoutString = queryParams + .getFirst(IClientQueryParams.IMPORT_TIMEOUT_PARAM); + if (timeoutString != null) + try { + result = Integer.parseInt(timeoutString); + } catch (NumberFormatException e) { + logger.warn( + "Timeout period parameter could not be parsed. The characters in the parameter string must all be decimal digits. The Import service will use the default timeout period instead.", + e); + } + } + + return result; + } + + /** + * you can test this with something like: curl -X POST + * http://localhost:8180/cspace-services/imports -i -u + * "Admin@collectionspace.org:Administrator" -H + * "Content-Type: application/xml" -T in.xml -T + * /src/trunk/services/imports/service + * /src/main/resources/templates/authority-request.xml + */ + @POST + @Consumes("application/xml") + @Produces("application/xml") + public javax.ws.rs.core.Response create(@Context UriInfo ui, + String xmlPayload) { + String result = null; + javax.ws.rs.core.Response.ResponseBuilder rb; + try { + int timeout = getTimeoutParam(ui); + // InputSource inputSource = payloadToInputSource(xmlPayload); + // result = createFromInputSource(inputSource); + String inputFilename = payloadToFilename(xmlPayload); + result = createFromFilename(inputFilename, timeout); + rb = javax.ws.rs.core.Response.ok(); + } catch (Exception e) { + result = Tools.errorToString(e, true); + rb = javax.ws.rs.core.Response + .status(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR); + } + rb.entity(result); + return rb.build(); + } + + public static String createFromInputSource(InputSource inputSource, + int timeOut) throws Exception { + String tenantId = AuthN.get().getCurrentTenantId(); + // We must expand the request and wrap it with all kinds of Nuxeo + // baggage, which expandXmlPayloadToDir knows how to do. + String outputDir = FileTools.createTmpDir("imports-") + .getCanonicalPath(); + File outpd = new File(outputDir); + outpd.mkdirs(); + expandXmlPayloadToDir(tenantId, inputSource, getTemplateDir(), + outpd.getCanonicalPath()); + + // Next, call the nuxeo import service, pointing it to our local + // directory that has the expanded request. + ImportCommand importCommand = new ImportCommand(); + // String destWorkspaces = "/default-domain/workspaces"; + String destWorkspaces = getWorkspaces(); + String result = ""; + try { + String report = "NORESULTS"; + report = importCommand.run(outputDir, destWorkspaces, timeOut); + result = "SUCCESS" + + report + ""; + } catch (Exception e) { + result = "ERROR" + + Tools.errorToString(e, true) + ""; + } + return result; + } + + public static String createFromFilename(String filename, int timeOut) + throws Exception { + String tenantId = AuthN.get().getCurrentTenantId(); + // We must expand the request and wrap it with all kinds of Nuxeo + // baggage, which expandXmlPayloadToDir knows how to do. + String outputDir = FileTools.createTmpDir("imports-") + .getCanonicalPath(); + File outpd = new File(outputDir); + outpd.mkdirs(); + expandXmlPayloadToDir(tenantId, filename, getTemplateDir(), + outpd.getCanonicalPath()); + + // Next, call the nuxeo import service, pointing it to our local + // directory that has the expanded request. + ImportCommand importCommand = new ImportCommand(); + // String destWorkspaces = "/default-domain/workspaces"; + String destWorkspaces = getWorkspaces(); + String result = ""; + try { + String report = "NORESULTS"; + report = importCommand.run(outputDir, destWorkspaces, timeOut); + result = "SUCCESS" + + report + ""; + } catch (Exception e) { + result = "ERROR" + + Tools.errorToString(e, true) + ""; + } + return result; + } + + /** + * @param xmlPayload + * A request file has a specific format, you can look at: + * trunk/services + * /imports/service/src/test/resources/requests/authority + * -request.xml + */ + public static InputSource payloadToInputSource(String xmlPayload) + throws Exception { + xmlPayload = encodeAmpersands(xmlPayload); + String requestDir = FileTools.createTmpDir("imports-request-") + .getCanonicalPath(); + File requestFile = FileTools.saveFile(requestDir, "request.xml", + xmlPayload, FileTools.FORCE_CREATE_PARENT_DIRS, + FileTools.UTF8_ENCODING); + if (requestFile == null) { + throw new FileNotFoundException( + "Could not create file in requestDir: " + requestDir); + } + String requestFilename = requestFile.getCanonicalPath(); + InputSource inputSource = new InputSource(requestFilename); + System.out.println("############## REQUEST_FILENAME: " + + requestFilename); + return inputSource; + } + + public static String payloadToFilename(String xmlPayload) throws Exception { + xmlPayload = encodeAmpersands(xmlPayload); + String requestDir = FileTools.createTmpDir("imports-request-") + .getCanonicalPath(); + File requestFile = FileTools.saveFile(requestDir, "request.xml", + xmlPayload, FileTools.FORCE_CREATE_PARENT_DIRS, + FileTools.UTF8_ENCODING); + if (requestFile == null) { + throw new FileNotFoundException( + "Could not create file in requestDir: " + requestDir); + } + String requestFilename = requestFile.getCanonicalPath(); + System.out.println("############## REQUEST_FILENAME: " + + requestFilename); + return requestFilename; + } + + /** + * Encodes each ampersand ('&') in the incoming XML payload by replacing it + * with the predefined XML entity for an ampersand ('&'). + * + * This is a workaround for the issue described in CSPACE-3911. Its intended + * effect is to have these added ampersand XML entities being resolved to + * 'bare' ampersands during the initial parse, thus preserving any XML + * entities in the payload, which will then be resolved correctly during the + * second parse. + * + * (This is not designed to compensate for instances where the incoming XML + * payload contains 'bare' ampersands - that is, used in any other context + * than as the initial characters in XML entities. In those cases, the + * payload may not be a legal XML document.) + * + * @param xmlPayload + * @return The original XML payload, with each ampersand replaced by the + * predefined XML entity for an ampersand. + */ + private static String encodeAmpersands(String xmlPayload) { + return xmlPayload.replace("&", "&"); + } + + public static void expandXmlPayloadToDir(String tenantId, + String inputFilename, String templateDir, String outputDir) + throws Exception { + System.out.println("############## TEMPLATE_DIR: " + templateDir); + System.out.println("############## OUTPUT_DIR:" + outputDir); + File file = new File(inputFilename); + FileInputStream is = new FileInputStream(file); + InputSource inputSource = new InputSource(is); + TemplateExpander.expandInputSource(tenantId, templateDir, outputDir, + inputSource, "/imports/import"); + } + + /** + * This method may be called statically from outside this class; there is a + * test call in org.collectionspace.services.test.ImportsServiceTest + * + * @param inputSource + * A wrapper around a request file, either a local file or a + * stream; the file has a specific format, you can look at: + * trunk/services/imports/service/src/test/resources/requests/ + * authority-request.xml + * @param templateDir + * The local directory where templates are to be found at + * runtime. + * @param outputDir + * The local directory where expanded files and directories are + * found, ready to be passed to the Nuxeo importer. + */ + public static void expandXmlPayloadToDir(String tenantId, + InputSource inputSource, String templateDir, String outputDir) + throws Exception { + System.out.println("############## TEMPLATE_DIR: " + templateDir); + System.out.println("############## OUTPUT_DIR:" + outputDir); + TemplateExpander.expandInputSource(tenantId, templateDir, outputDir, + inputSource, "/imports/import"); + // TemplateExpander.expandInputSource(templateDir, outputDir, + // inputFilename, "/imports/import"); + } + + /** + * you can test like this: curl -F "file=@out.zip;type=application/zip" + * --basic -u "admin@core.collectionspace.org:Administrator" + * http://localhost:8180/cspace-services/imports + */ + @POST + @Consumes("multipart/form-data") + @Produces("application/xml") + public javax.ws.rs.core.Response acceptUpload(@Context UriInfo ui, + @Context HttpServletRequest req, MultipartFormDataInput partFormData) { + javax.ws.rs.core.Response response = null; + StringBuffer resultBuf = new StringBuffer(); + try { + InputStream fileStream = null; + String preamble = partFormData.getPreamble(); + System.out.println("Preamble type is:" + preamble); + Map> partsMap = partFormData + .getFormDataMap(); + List fileParts = partsMap.get("file"); + int timeout = this.getTimeoutParam(ui); + for (InputPart part : fileParts) { + String mediaType = part.getMediaType().toString(); + System.out.println("Media type is:" + mediaType); + if (mediaType.equalsIgnoreCase(MediaType.APPLICATION_XML) + || mediaType.equalsIgnoreCase(MediaType.TEXT_XML)) { + // FIXME For an alternate approach, potentially preferable, + // see: + // http://stackoverflow.com/questions/4586222/right-way-of-formatting-an-input-stream + String str = encodeAmpersands(part.getBodyAsString()); + InputStream stream = new ByteArrayInputStream( + str.getBytes("UTF8")); + InputSource inputSource = new InputSource(stream); + // InputSource inputSource = new + // InputSource(part.getBody(InputStream.class, null)); + String result = createFromInputSource(inputSource, timeout); + resultBuf.append(result); + continue; + } + + // + // This code was never finished to support the import of a zipped directory + // + if (mediaType.equalsIgnoreCase("application/zip")) { + logger.error("The Import service does not yet support .zip files."); //We should also send back a meaningful error message and status code here. + + fileStream = part.getBody(InputStream.class, null); + + File zipfile = FileUtils.createTmpFile(fileStream, + getServiceName() + "_"); + String zipfileName = zipfile.getCanonicalPath(); + System.out.println("Imports zip file saved to:" + + zipfileName); + + String baseOutputDir = FileTools.createTmpDir("imports-") + .getCanonicalPath(); + File indir = new File(baseOutputDir + "/in"); + indir.mkdir(); + ZipTools.unzip(zipfileName, indir.getCanonicalPath()); + String result = "\r\nZipfile " + zipfileName + + "extracted to: " + indir.getCanonicalPath() + + ""; + System.out.println(result); + + long start = System.currentTimeMillis(); + // TODO: now call import service... + resultBuf.append(result); + continue; + } + } + javax.ws.rs.core.Response.ResponseBuilder rb = javax.ws.rs.core.Response + .ok(); + rb.entity(resultBuf.toString()); + response = rb.build(); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.CREATE_FAILED); + } + return response; + } + + String page = "\n" + + "\n" + + " \n" + + " CollectionSpace Import\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " Choose a file to import:" + + " \n" + + "
\n" + + " \n" + + "
\n" + " \n" + "\n"; + + @GET + @Produces("text/html") public String getInputForm(@QueryParam("form") String form) { - return page; + return page; } } diff --git a/services/imports/service/src/main/java/org/collectionspace/services/imports/nuxeo/ImportCommand.java b/services/imports/service/src/main/java/org/collectionspace/services/imports/nuxeo/ImportCommand.java index faeddfecf..186625c52 100644 --- a/services/imports/service/src/main/java/org/collectionspace/services/imports/nuxeo/ImportCommand.java +++ b/services/imports/service/src/main/java/org/collectionspace/services/imports/nuxeo/ImportCommand.java @@ -23,13 +23,12 @@ import org.nuxeo.ecm.core.io.impl.plugins.DocumentModelWriter; // based loosely on package org.nuxeo.ecm.shell.commands.io.ImportCommand; public class ImportCommand { private static final Log logger = LogFactory.getLog(ImportCommand.class); - private static final int DEFAULT_TX_TIMOUT = 600; //timeout period in seconds - public String run(String src, String dest) throws Exception { + public String run(String src, String dest, int timeOut) throws Exception { File file = new File(src); ///cspace way of configuring client and auth: NuxeoClientEmbedded client = NuxeoConnectorEmbedded.getInstance().getClient(); - RepositoryInstance repoSession = client.openRepository(DEFAULT_TX_TIMOUT); + RepositoryInstance repoSession = client.openRepository(timeOut); try { String msg = String.format("Start of import is Local time: %tT", Calendar.getInstance()); logger.debug(msg); diff --git a/services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java b/services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java index c6f6d6057..7d1eb9523 100644 --- a/services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java +++ b/services/query/service/src/main/java/org/collectionspace/services/query/QueryResource.java @@ -27,15 +27,9 @@ import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; import javax.ws.rs.PathParam; import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; -import javax.ws.rs.core.UriInfo; //import javax.xml.bind.JAXBContext; //import javax.xml.bind.Marshaller;