From 44dd5750650b46d9979b4e06e4cc76c0b0003f4f Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 7 May 2009 13:38:50 +0000 Subject: [PATCH] Attachments management git-svn-id: https://svn.argeo.org/slc/trunk@2416 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../META-INF/MANIFEST.MF | 3 +- .../org.argeo.slc.demo.basic/conf/basic.xml | 25 +++++++ .../org.argeo.slc.demo.basic/conf/osgi.xml | 4 +- .../argeo/slc/services/ServiceMsgHandler.java | 4 ++ .../impl/test/TestManagerServiceImpl.java | 14 +++- .../slc/services/test/TestManagerService.java | 3 + .../mvc/attachment/GetAttachmentHandler.java | 35 ++++++++++ .../argeo/slc/jms/JmsAttachmentListener.java | 48 +++++++++++++ .../argeo/slc/jms/JmsAttachmentUploader.java | 67 +++++++++++++++++++ .../slc/jms/JmsTreeTestResultListener.java | 44 ++++++------ .../org/argeo/slc/activemq/destinations.xml | 27 +++++--- runtime/org.argeo.slc.support.castor/pom.xml | 1 + .../org/argeo/slc/castor/attachment.xml | 16 +++++ .../resources/org/argeo/slc/castor/msg.xml | 9 +++ .../resources/org/argeo/slc/castor/spring.xml | 3 + .../resources/org/argeo/slc/castor/test.xml | 31 +++++---- .../test/tree/TreeTestResultDaoHibernate.java | 17 +++++ .../attachment/SimpleAttachment.hbm.xml | 12 ++++ .../hibernate/spring/applicationContext.xml | 3 + .../test/tree/TreeTestResult.hbm.xml | 23 ++++--- .../argeo/slc/core/attachment/Attachment.java | 9 +++ .../core/attachment/AttachmentUploader.java | 7 ++ .../core/attachment/AttachmentsEnabled.java | 5 ++ .../core/attachment/AttachmentsStorage.java | 12 ++++ .../attachment/FileAttachmentsStorage.java | 61 +++++++++++++++++ .../slc/core/attachment/SimpleAttachment.java | 49 ++++++++++++++ .../execution/tasks/UploadAttachments.java | 42 ++++++++++++ .../slc/core/test/tree/TreeTestResult.java | 25 ++++++- .../test/tree/TreeTestResultListener.java | 10 +++ .../core/test/tree/TreeTestResultLogger.java | 12 +++- .../slc/dao/test/tree/TreeTestResultDao.java | 3 + .../AddTreeTestResultAttachmentRequest.java | 25 +++++++ .../argeo/slc/core/execution/tasks/core.xml | 2 + .../META-INF/spring/jms.xml | 11 ++- .../META-INF/spring/osgi.xml | 6 +- .../META-INF/spring/jms-osgi.xml | 2 + .../META-INF/spring/jms.xml | 11 +++ .../META-INF/spring/services-osgi.xml | 2 + .../META-INF/spring/services.xml | 3 + .../org.argeo.slc.webapp.war/WEB-INF/osgi.xml | 6 +- .../WEB-INF/slc-service-servlet.xml | 5 ++ 41 files changed, 628 insertions(+), 69 deletions(-) create mode 100644 runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java create mode 100644 runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java create mode 100644 runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java create mode 100644 runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml create mode 100644 runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/attachment/SimpleAttachment.hbm.xml create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java diff --git a/demo/site/org.argeo.slc.demo.basic/META-INF/MANIFEST.MF b/demo/site/org.argeo.slc.demo.basic/META-INF/MANIFEST.MF index a3488c6ab..1c72039db 100644 --- a/demo/site/org.argeo.slc.demo.basic/META-INF/MANIFEST.MF +++ b/demo/site/org.argeo.slc.demo.basic/META-INF/MANIFEST.MF @@ -15,4 +15,5 @@ Import-Package: org.springframework.aop, org.springframework.aop.framework, org.springframework.aop.scope, - org.springframework.beans.factory.config + org.springframework.beans.factory.config, + org.springframework.core.io diff --git a/demo/site/org.argeo.slc.demo.basic/conf/basic.xml b/demo/site/org.argeo.slc.demo.basic/conf/basic.xml index efc83dc81..acaee0cb9 100644 --- a/demo/site/org.argeo.slc.demo.basic/conf/basic.xml +++ b/demo/site/org.argeo.slc.demo.basic/conf/basic.xml @@ -54,6 +54,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml b/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml index 050e4c771..a759f5b5c 100644 --- a/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml +++ b/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml @@ -9,5 +9,7 @@ - + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/ServiceMsgHandler.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/ServiceMsgHandler.java index 87579ea0f..4bf96d6c1 100644 --- a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/ServiceMsgHandler.java +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/ServiceMsgHandler.java @@ -3,6 +3,7 @@ package org.argeo.slc.services; import org.argeo.slc.SlcException; import org.argeo.slc.msg.MsgHandler; import org.argeo.slc.msg.process.SlcExecutionStatusRequest; +import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest; import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; import org.argeo.slc.msg.test.tree.ResultPartRequest; @@ -27,6 +28,9 @@ public class ServiceMsgHandler implements MsgHandler { else if (msg instanceof CloseTreeTestResultRequest) testManagerService .closeTreeTestResult((CloseTreeTestResultRequest) msg); + else if (msg instanceof AddTreeTestResultAttachmentRequest) + testManagerService + .addAttachment((AddTreeTestResultAttachmentRequest) msg); else throw new SlcException("Unrecognized message type " + msg); return null; diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/test/TestManagerServiceImpl.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/test/TestManagerServiceImpl.java index a70adc852..7ccc35d11 100644 --- a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/test/TestManagerServiceImpl.java +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/test/TestManagerServiceImpl.java @@ -8,6 +8,7 @@ import org.argeo.slc.dao.process.SlcExecutionDao; import org.argeo.slc.dao.test.TestRunDescriptorDao; import org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao; import org.argeo.slc.dao.test.tree.TreeTestResultDao; +import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest; import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; import org.argeo.slc.msg.test.tree.ResultPartRequest; @@ -56,7 +57,7 @@ public class TestManagerServiceImpl implements TestManagerService { .getTestResultUuid()); } } else { - log + log .trace("ResultUUID=" + testRunDescriptor.getTestResultUuid()); addResultToCollection("default", testRunDescriptor @@ -102,7 +103,7 @@ public class TestManagerServiceImpl implements TestManagerService { } public void addResultPart(ResultPartRequest msg) { -// registerTestRunDescriptor(msg.getTestRunDescriptor()); + // registerTestRunDescriptor(msg.getTestRunDescriptor()); if (log.isTraceEnabled()) log.trace("Adding result part to test result #" @@ -122,4 +123,13 @@ public class TestManagerServiceImpl implements TestManagerService { treeTestResultDao.close(msg.getResultUuid(), msg.getCloseDate()); } + public void addAttachment(AddTreeTestResultAttachmentRequest msg) { + if (log.isTraceEnabled()) + log.trace("Adding attachment " + msg.getAttachment() + + " to result #" + msg.getResultUuid()); + treeTestResultDao.addAttachment(msg.getResultUuid(), msg + .getAttachment()); + + } + } diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/test/TestManagerService.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/test/TestManagerService.java index 1a54884e2..a286e91a7 100644 --- a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/test/TestManagerService.java +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/test/TestManagerService.java @@ -1,5 +1,6 @@ package org.argeo.slc.services.test; +import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest; import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; import org.argeo.slc.msg.test.tree.ResultPartRequest; @@ -21,5 +22,7 @@ public interface TestManagerService { public void addResultPart(ResultPartRequest msg); + public void addAttachment(AddTreeTestResultAttachmentRequest msg); + public void closeTreeTestResult(CloseTreeTestResultRequest msg); } diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java new file mode 100644 index 000000000..77a21ae31 --- /dev/null +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java @@ -0,0 +1,35 @@ +package org.argeo.slc.web.mvc.attachment; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.argeo.slc.core.attachment.AttachmentsStorage; +import org.argeo.slc.core.attachment.SimpleAttachment; +import org.springframework.web.HttpRequestHandler; + +/** Returns one single result. */ +public class GetAttachmentHandler implements HttpRequestHandler { + private AttachmentsStorage attachmentsStorage; + + public void handleRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + String uuid = request.getParameter("uuid"); + String contentType = request.getParameter("contentType"); + SimpleAttachment resourceDescriptor = new SimpleAttachment(); + resourceDescriptor.setUuid(uuid); + resourceDescriptor.setContentType(contentType); + + response.setContentType(contentType); + ServletOutputStream outputStream = response.getOutputStream(); + attachmentsStorage.retrieveAttachment(resourceDescriptor, outputStream); + } + + public void setAttachmentsStorage(AttachmentsStorage attachmentsStorage) { + this.attachmentsStorage = attachmentsStorage; + } + +} diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java new file mode 100644 index 000000000..46e828060 --- /dev/null +++ b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java @@ -0,0 +1,48 @@ +package org.argeo.slc.jms; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import javax.jms.BytesMessage; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; + +import org.apache.commons.io.IOUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.core.attachment.AttachmentsStorage; +import org.argeo.slc.core.attachment.SimpleAttachment; + +public class JmsAttachmentListener implements MessageListener { + private AttachmentsStorage attachmentsStorage; + + public void onMessage(Message msg) { + BytesMessage message = (BytesMessage) msg; + + InputStream in = null; + try { + SimpleAttachment attachment = new SimpleAttachment(); + attachment.setUuid(msg + .getStringProperty(JmsAttachmentUploader.ATTACHMENT_ID)); + attachment.setName(msg + .getStringProperty(JmsAttachmentUploader.ATTACHMENT_NAME)); + attachment + .setContentType(msg + .getStringProperty(JmsAttachmentUploader.ATTACHMENT_CONTENT_TYPE)); + + byte[] buffer = new byte[(int) message.getBodyLength()]; + message.readBytes(buffer); + in = new ByteArrayInputStream(buffer); + attachmentsStorage.storeAttachment(attachment, in); + } catch (JMSException e) { + throw new SlcException("Could not process attachment message " + + msg, e); + } + IOUtils.closeQuietly(in); + } + + public void setAttachmentsStorage(AttachmentsStorage attachmentsStorage) { + this.attachmentsStorage = attachmentsStorage; + } + +} diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java new file mode 100644 index 000000000..f5ea454ea --- /dev/null +++ b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java @@ -0,0 +1,67 @@ +package org.argeo.slc.jms; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; + +import javax.jms.BytesMessage; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.Session; + +import org.argeo.slc.SlcException; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.AttachmentUploader; +import org.springframework.core.io.Resource; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.jms.core.MessageCreator; + +public class JmsAttachmentUploader implements AttachmentUploader { + public final static String ATTACHMENT_ID = "slc_attachmentId"; + public final static String ATTACHMENT_NAME = "slc_attachmentName"; + public final static String ATTACHMENT_CONTENT_TYPE = "slc_attachmentContentType"; + + private JmsTemplate jmsTemplate; + private Destination destination; + + public void upload(final Attachment attachment, final Resource resource) { + jmsTemplate.send(destination, new MessageCreator() { + + public Message createMessage(Session session) throws JMSException { + BytesMessage message = session.createBytesMessage(); + message.setStringProperty(ATTACHMENT_ID, attachment.getUuid()); + message + .setStringProperty(ATTACHMENT_NAME, attachment + .getName()); + message.setStringProperty(ATTACHMENT_CONTENT_TYPE, attachment + .getContentType()); + + try { + BufferedInputStream in = new BufferedInputStream(resource + .getInputStream()); + byte[] buffer = new byte[1024 * 1024]; + while (in.read(buffer) > 0) { + message.writeBytes(buffer); + } + } catch (IOException e) { + throw new SlcException( + "Cannot write into byte message for attachment " + + attachment + " and resource " + resource, + e); + } + return message; + } + }); + + } + + public void setJmsTemplate(JmsTemplate jmsTemplate) { + this.jmsTemplate = jmsTemplate; + } + + public void setDestination(Destination destination) { + this.destination = destination; + } + +} diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsTreeTestResultListener.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsTreeTestResultListener.java index 20137826f..7da976a4d 100644 --- a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsTreeTestResultListener.java +++ b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsTreeTestResultListener.java @@ -5,7 +5,11 @@ import javax.jms.Destination; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.SimpleAttachment; import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.core.test.tree.TreeTestResultListener; +import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest; import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; import org.argeo.slc.msg.test.tree.ResultPartRequest; @@ -13,17 +17,17 @@ import org.argeo.slc.test.TestResultListener; import org.argeo.slc.test.TestResultPart; import org.springframework.jms.core.JmsTemplate; -public class JmsTreeTestResultListener implements - TestResultListener { +public class JmsTreeTestResultListener implements TreeTestResultListener { private final Log log = LogFactory.getLog(getClass()); private Boolean onlyOnClose = false; private JmsTemplate jmsTemplate; private Destination executionEventDestination; -// private Destination createDestination; -// private Destination addResultPartDestination; -// private Destination closeDestination; + + // private Destination createDestination; + // private Destination addResultPartDestination; + // private Destination closeDestination; public void resultPartAdded(TreeTestResult testResult, TestResultPart testResultPart) { @@ -83,6 +87,19 @@ public class JmsTreeTestResultListener implements } } + public void addAttachment(TreeTestResult testResult, Attachment attachment) { + try { + AddTreeTestResultAttachmentRequest req = new AddTreeTestResultAttachmentRequest(); + req.setResultUuid(testResult.getUuid()); + req.setAttachment((SimpleAttachment) attachment); + jmsTemplate.convertAndSend(executionEventDestination, req); + + } catch (Exception e) { + throw new SlcException("Could not notify to JMS", e); + } + + } + public void setOnlyOnClose(Boolean onlyOnClose) { this.onlyOnClose = onlyOnClose; } @@ -91,22 +108,9 @@ public class JmsTreeTestResultListener implements this.jmsTemplate = jmsTemplate; } - public void setExecutionEventDestination(Destination executionEventDestination) { + public void setExecutionEventDestination( + Destination executionEventDestination) { this.executionEventDestination = executionEventDestination; } - - - -// public void setCreateDestination(Destination createDestination) { -// this.createDestination = createDestination; -// } -// -// public void setAddResultPartDestination(Destination addResultPartDestination) { -// this.addResultPartDestination = addResultPartDestination; -// } -// -// public void setCloseDestination(Destination closeDestination) { -// this.closeDestination = closeDestination; -// } } diff --git a/runtime/org.argeo.slc.support.activemq/src/main/resources/org/argeo/slc/activemq/destinations.xml b/runtime/org.argeo.slc.support.activemq/src/main/resources/org/argeo/slc/activemq/destinations.xml index 967b0daf9..739f02504 100644 --- a/runtime/org.argeo.slc.support.activemq/src/main/resources/org/argeo/slc/activemq/destinations.xml +++ b/runtime/org.argeo.slc.support.activemq/src/main/resources/org/argeo/slc/activemq/destinations.xml @@ -7,7 +7,11 @@ - + + + + @@ -25,18 +29,19 @@ - - + + --> diff --git a/runtime/org.argeo.slc.support.castor/pom.xml b/runtime/org.argeo.slc.support.castor/pom.xml index 945dc6ec0..32d4aa701 100644 --- a/runtime/org.argeo.slc.support.castor/pom.xml +++ b/runtime/org.argeo.slc.support.castor/pom.xml @@ -39,6 +39,7 @@ org.argeo.slc.*;resolution:=optional, org.argeo.slc.execution;resolution:=optional, + org.argeo.slc.core.attachment;resolution:=optional, org.argeo.slc.core.structure;resolution:=optional, org.argeo.slc.core.structure.tree;resolution:=optional, org.argeo.slc.core.test;resolution:=optional, diff --git a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml new file mode 100644 index 000000000..6faf85209 --- /dev/null +++ b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml @@ -0,0 +1,16 @@ + + + + + + Attachment objects XML mapping + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/msg.xml b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/msg.xml index 146c020e8..e523bbdf2 100644 --- a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/msg.xml +++ b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/msg.xml @@ -52,6 +52,15 @@ + + + + + + + + classpath:org/argeo/slc/castor/execution.xml + + classpath:org/argeo/slc/castor/attachment.xml + diff --git a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/test.xml b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/test.xml index 520cfa346..90672c524 100644 --- a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/test.xml +++ b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/test.xml @@ -3,8 +3,7 @@ Test objects XML mapping - + @@ -25,8 +24,8 @@ - + @@ -39,15 +38,13 @@ - - + - + @@ -56,20 +53,22 @@ - - + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/spring/applicationContext.xml b/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/spring/applicationContext.xml index ed5252933..ca3346db6 100644 --- a/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/spring/applicationContext.xml +++ b/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/spring/applicationContext.xml @@ -45,6 +45,9 @@ org/argeo/slc/hibernate/runtime/SlcAgentDescriptor.hbm.xml + + org/argeo/slc/hibernate/attachment/SimpleAttachment.hbm.xml + diff --git a/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/test/tree/TreeTestResult.hbm.xml b/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/test/tree/TreeTestResult.hbm.xml index 5397a64bd..b7d02d7a6 100644 --- a/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/test/tree/TreeTestResult.hbm.xml +++ b/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/test/tree/TreeTestResult.hbm.xml @@ -7,11 +7,11 @@ - - + @@ -22,8 +22,7 @@ sort="natural"> - + - + - + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java new file mode 100644 index 000000000..e55260ed7 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java @@ -0,0 +1,9 @@ +package org.argeo.slc.core.attachment; + +public interface Attachment { + public String getUuid(); + + public String getName(); + + public String getContentType(); +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java new file mode 100644 index 000000000..f87b008f5 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java @@ -0,0 +1,7 @@ +package org.argeo.slc.core.attachment; + +import org.springframework.core.io.Resource; + +public interface AttachmentUploader { + public void upload(Attachment attachment, Resource resource); +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java new file mode 100644 index 000000000..dfdff1e7e --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java @@ -0,0 +1,5 @@ +package org.argeo.slc.core.attachment; + +public interface AttachmentsEnabled { + public void addAttachment(Attachment attachment); +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java new file mode 100644 index 000000000..dfb75604e --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java @@ -0,0 +1,12 @@ +package org.argeo.slc.core.attachment; + +import java.io.InputStream; +import java.io.OutputStream; + + +public interface AttachmentsStorage { + public void retrieveAttachment(Attachment attachment, + OutputStream outputStream); + + public void storeAttachment(Attachment attachment, InputStream inputStream); +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java new file mode 100644 index 000000000..fad4db19e --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java @@ -0,0 +1,61 @@ +package org.argeo.slc.core.attachment; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.io.IOUtils; +import org.argeo.slc.SlcException; + +public class FileAttachmentsStorage implements AttachmentsStorage { + private File attachmentsDirectory = new File(System + .getProperty("java.io.tmpdir") + + File.separator + "slcAttachments"); + + public void retrieveAttachment(Attachment attachment, + OutputStream outputStream) { + File file = getFile(attachment); + InputStream in = null; + try { + byte[] buffer = new byte[1024 * 1024]; + in = new FileInputStream(file); + while (in.read(buffer) >= 0) { + outputStream.write(buffer); + } + } catch (IOException e) { + throw new SlcException("Cannot write attachment " + attachment + + " to " + file, e); + } finally { + IOUtils.closeQuietly(in); + } + } + + public void storeAttachment(Attachment attachment, InputStream inputStream) { + File file = getFile(attachment); + FileOutputStream out = null; + try { + byte[] buffer = new byte[1024 * 1024]; + out = new FileOutputStream(file); + while (inputStream.read(buffer) >= 0) { + out.write(buffer); + } + } catch (IOException e) { + throw new SlcException("Cannot write attachment " + attachment + + " to " + file, e); + } finally { + IOUtils.closeQuietly(out); + } + + } + + protected File getFile(Attachment attachment) { + if (!attachmentsDirectory.exists()) + attachmentsDirectory.mkdirs(); + File file = new File(attachmentsDirectory + File.separator + + attachment.getUuid()); + return file; + } +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java new file mode 100644 index 000000000..f5ee9df67 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java @@ -0,0 +1,49 @@ +package org.argeo.slc.core.attachment; + +public class SimpleAttachment implements Attachment { + private String uuid; + private String name; + private String contentType; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String toString() { + return "Attachment #" + uuid + "(" + name + ", " + contentType + ")"; + } + + public boolean equals(Object obj) { + if (obj instanceof Attachment) { + Attachment attachment = (Attachment) obj; + if (uuid != null && attachment.getUuid() != null) + return uuid.equals(attachment.getUuid()); + + if (name != null && attachment.getName() != null) + return name.equals(attachment.getName()); + + return hashCode() == attachment.hashCode(); + } + return false; + } +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java new file mode 100644 index 000000000..499e11948 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java @@ -0,0 +1,42 @@ +package org.argeo.slc.core.execution.tasks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.AttachmentUploader; +import org.argeo.slc.core.attachment.AttachmentsEnabled; +import org.springframework.core.io.Resource; + +public class UploadAttachments implements Runnable { + private AttachmentUploader attachmentUploader; + private Map attachments = new HashMap(); + private List attachTo = new ArrayList(); + + public void run() { + for (Attachment attachment : attachments.keySet()) { + Resource resource = attachments.get(attachment); + attachmentUploader.upload(attachment, resource); + for (AttachmentsEnabled attachmentsEnabled : attachTo) { + attachmentsEnabled.addAttachment(attachment); + } + } + + } + + public void setAttachmentUploader(AttachmentUploader attachmentUploader) { + this.attachmentUploader = attachmentUploader; + } + + public void setAttachments(Map attachments) { + this.attachments = attachments; + } + + public void setAttachTo(List attachTo) { + this.attachTo = attachTo; + } + + +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java index 505a71060..c7fa530ac 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java @@ -1,5 +1,6 @@ package org.argeo.slc.core.test.tree; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -10,6 +11,8 @@ import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.AttachmentsEnabled; import org.argeo.slc.core.structure.tree.TreeSPath; import org.argeo.slc.structure.StructureAware; import org.argeo.slc.structure.StructureElement; @@ -25,7 +28,7 @@ import org.argeo.slc.test.TestRunAware; * structure. */ public class TreeTestResult implements TestResult, StructureAware, - Comparable { + Comparable, AttachmentsEnabled { private Log log = LogFactory.getLog(TreeTestResult.class); private List> listeners = new Vector>(); @@ -43,6 +46,7 @@ public class TreeTestResult implements TestResult, StructureAware, private SortedMap resultParts = new TreeMap(); private SortedMap elements = new TreeMap(); + private List attachments = new ArrayList(); private Map attributes = new TreeMap(); @@ -215,4 +219,23 @@ public class TreeTestResult implements TestResult, StructureAware, this.warnIfAlreadyClosed = warnIfAlreadyClosed; } + public List getAttachments() { + return attachments; + } + + public void setAttachments(List attachments) { + this.attachments = attachments; + } + + public void addAttachment(Attachment attachment) { + attachments.add(attachment); + synchronized (listeners) { + for (TestResultListener listener : listeners) { + if (listener instanceof TreeTestResultListener) + ((TreeTestResultListener) listener).addAttachment(this, + attachment); + } + } + } + } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java new file mode 100644 index 000000000..381eb7b75 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java @@ -0,0 +1,10 @@ +package org.argeo.slc.core.test.tree; + +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.test.TestResultListener; + +public interface TreeTestResultListener extends + TestResultListener { + public void addAttachment(TreeTestResult testResult, + Attachment attachment); +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java index 3924760a3..528874dd3 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java @@ -2,8 +2,7 @@ package org.argeo.slc.core.test.tree; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - -import org.argeo.slc.test.TestResultListener; +import org.argeo.slc.core.attachment.Attachment; import org.argeo.slc.test.TestResultPart; import org.argeo.slc.test.TestStatus; @@ -13,7 +12,7 @@ import org.argeo.slc.test.TestStatus; * @see TreeTestResult * */ -public class TreeTestResultLogger implements TestResultListener { +public class TreeTestResultLogger implements TreeTestResultListener { private static Log log = LogFactory.getLog(TreeTestResultLogger.class); @@ -49,4 +48,11 @@ public class TreeTestResultLogger implements TestResultListener this.logExceptionMessages = logExceptionMessages; } + public void addAttachment(TreeTestResult treeTestResult, + Attachment attachment) { + if (log.isDebugEnabled()) + log.debug("Attachment " + attachment + " added to " + + treeTestResult.getUuid()); + } + } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java index 7c5cc6e7a..d83fa668d 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java @@ -3,6 +3,7 @@ package org.argeo.slc.dao.test.tree; import java.util.List; import java.util.Map; +import org.argeo.slc.core.attachment.SimpleAttachment; import org.argeo.slc.core.structure.tree.TreeSPath; import org.argeo.slc.core.test.SimpleResultPart; import org.argeo.slc.core.test.tree.TreeTestResult; @@ -26,4 +27,6 @@ public interface TreeTestResultDao extends TestResultDao { /** Update attributes */ public void updateAttributes(String testResultId, Map attributes); + + public void addAttachment(String testResultId, SimpleAttachment attachment); } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java new file mode 100644 index 000000000..b479fcd5c --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java @@ -0,0 +1,25 @@ +package org.argeo.slc.msg.test.tree; + +import org.argeo.slc.core.attachment.SimpleAttachment; + +public class AddTreeTestResultAttachmentRequest { + private String resultUuid; + private SimpleAttachment attachment; + + public String getResultUuid() { + return resultUuid; + } + + public void setResultUuid(String resultUuid) { + this.resultUuid = resultUuid; + } + + public SimpleAttachment getAttachment() { + return attachment; + } + + public void setAttachment(SimpleAttachment attachment) { + this.attachment = attachment; + } + +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/tasks/core.xml b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/tasks/core.xml index 7348b12a6..bf9bb8511 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/tasks/core.xml +++ b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/tasks/core.xml @@ -14,4 +14,6 @@ abstract="true" /> + \ No newline at end of file diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/jms.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/jms.xml index e69584456..3349c3012 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/jms.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/jms.xml @@ -13,6 +13,11 @@ + + + + + @@ -30,14 +35,16 @@ + +--> - + diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml index 5f6423aba..1fdd460fb 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml @@ -6,7 +6,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - + @@ -15,7 +15,9 @@ - + + + diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms-osgi.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms-osgi.xml index 6ba1c5c42..8b172a1ca 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms-osgi.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms-osgi.xml @@ -18,6 +18,8 @@ bean-name="jmsTransactionManager" /> + diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms.xml index ec6900824..075610212 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms.xml @@ -6,6 +6,17 @@ + + + + + + + + + + + diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services-osgi.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services-osgi.xml index a078000b8..5a46059ec 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services-osgi.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services-osgi.xml @@ -10,6 +10,8 @@ + diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services.xml index 6f4602a26..6151309e7 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services.xml @@ -17,6 +17,9 @@ + + + diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/osgi.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/osgi.xml index b2b4a0ca2..1c9aea4c2 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/osgi.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/osgi.xml @@ -26,7 +26,8 @@ - + + + \ No newline at end of file diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/slc-service-servlet.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/slc-service-servlet.xml index e87262aff..6755e712f 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/slc-service-servlet.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/slc-service-servlet.xml @@ -92,6 +92,11 @@ + + + + + -- 2.39.2