From 172b2c19999311a0a57a6ed0ae0ea355b88e74bf Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Thu, 12 Jul 2012 09:40:37 +0000
Subject: [PATCH] SP-183, BIS-91: provide correct destination path in e-mail
 message

SVN: 26086
---
 .../AbstractDropboxProcessingPlugin.java      |  4 +-
 .../plugins/standard/DataSetCopier.java       |  9 ++-
 .../standard/DataSetCopierForUsers.java       | 61 +++++++++++++------
 .../standard/DataSetCopierForUsersTest.java   | 47 ++++++++++++--
 .../server/plugins/DataSetCopier.java         |  5 +-
 .../etl/DropboxProcessingPluginYeastX.java    |  5 +-
 6 files changed, 100 insertions(+), 31 deletions(-)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java
index 37b20b2122e..75f1bdcd7a3 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java
@@ -117,7 +117,7 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP
                         dataSetDescription.getSampleTypeCode());
         boolean withSample = sampleOrNull != null;
         boolean processingFailed = status.isError();
-        String processingDescription = getProcessingDescription();
+        String processingDescription = getProcessingDescription(dataSetDescription, context);
         Template template = getEMailMessageTemplate(processingFailed, withSample).createFreshCopy();
         String subject;
         if (processingFailed)
@@ -159,7 +159,7 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP
     /**
      * Returns a description to be used in e-mails.
      */
-    protected abstract String getProcessingDescription();
+    protected abstract String getProcessingDescription(DatasetDescription dataset, DataSetProcessingContext context);
 
     private String render(String entity, String entityType)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopier.java
index 530eac02899..6ea60a47932 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopier.java
@@ -22,7 +22,9 @@ import java.util.Properties;
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.common.utilities.SystemTimeProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IPostRegistrationDatasetHandler;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
 
 /**
  * Processing plugin which copies data sets to a destination folder by using rsync. The destination
@@ -80,13 +82,14 @@ public class DataSetCopier extends AbstractDropboxProcessingPlugin
     }
 
     public DataSetCopier(Properties properties, File storeRoot,
-            IPostRegistrationDatasetHandler dropboxHandler)
+            IPostRegistrationDatasetHandler dropboxHandler, ITimeProvider timeProvider)
     {
-        super(properties, storeRoot, dropboxHandler);
+        super(properties, storeRoot, dropboxHandler, timeProvider);
     }
 
     @Override
-    protected String getProcessingDescription()
+    protected String getProcessingDescription(DatasetDescription dataset,
+            DataSetProcessingContext context)
     {
         return "Copy to " + properties.getProperty(DESTINATION_KEY);
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsers.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsers.java
index 86d3369dd8f..0822e1af601 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsers.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsers.java
@@ -23,6 +23,10 @@ import java.util.Properties;
 
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.utilities.ITimeProvider;
+import ch.systemsx.cisd.common.utilities.SystemTimeProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
 
 /**
  * 
@@ -37,13 +41,15 @@ public class DataSetCopierForUsers extends DataSetCopier
 
     public DataSetCopierForUsers(Properties properties, File storeRoot)
     {
-        this(properties, storeRoot, new RsyncCopierFactory(), new SshCommandExecutorFactory(), new ImmutableCopierFactory());
+        this(properties, storeRoot, new RsyncCopierFactory(), new SshCommandExecutorFactory(),
+                new ImmutableCopierFactory(), SystemTimeProvider.SYSTEM_TIME_PROVIDER);
     }
 
     @Private
     DataSetCopierForUsers(Properties properties, File storeRoot,
             IPathCopierFactory pathCopierFactory,
-            ISshCommandExecutorFactory sshCommandExecutorFactory, IImmutableCopierFactory immutableCopierFactory)
+            ISshCommandExecutorFactory sshCommandExecutorFactory,
+            IImmutableCopierFactory immutableCopierFactory, ITimeProvider timeProvider)
     {
         super(properties, storeRoot, new Copier(properties, pathCopierFactory,
                 sshCommandExecutorFactory, immutableCopierFactory)
@@ -54,25 +60,40 @@ public class DataSetCopierForUsers extends DataSetCopier
                 protected String transformHostFile(String originalHostFile,
                         Map<String, String> parameterBindings)
                 {
-                    int indexOfParameter = originalHostFile.indexOf(USER_PARAMETER_STRING);
-                    String hostFile = originalHostFile;
-                    if (indexOfParameter >= 0)
-                    {
-                        String user = parameterBindings.get(USER_PARAMETER);
-                        if (user == null)
-                        {
-                            throw new UserFailureException("Missing parameter '" + USER_PARAMETER
-                                    + "'.");
-                        }
-                        hostFile =
-                                originalHostFile.substring(0, indexOfParameter)
-                                        + user
-                                        + originalHostFile.substring(indexOfParameter
-                                                + USER_PARAMETER_STRING.length());
-                    }
-                    return hostFile;
+                    return createDestinationFileName(originalHostFile, parameterBindings);
                 }
-            });
+            }, timeProvider);
+    }
+
+    private static String createDestinationFileName(String originalHostFile,
+            Map<String, String> parameterBindings)
+    {
+        int indexOfParameter = originalHostFile.indexOf(USER_PARAMETER_STRING);
+        String hostFile = originalHostFile;
+        if (indexOfParameter >= 0)
+        {
+            String user = parameterBindings.get(USER_PARAMETER);
+            if (user == null)
+            {
+                throw new UserFailureException("Missing parameter '" + USER_PARAMETER
+                        + "'.");
+            }
+            hostFile =
+                    originalHostFile.substring(0, indexOfParameter)
+                            + user
+                            + originalHostFile.substring(indexOfParameter
+                                    + USER_PARAMETER_STRING.length());
+        }
+        return hostFile;
+    }
+
+    @Override
+    protected String getProcessingDescription(DatasetDescription dataset,
+            DataSetProcessingContext context)
+    {
+        return "Copy to "
+                + createDestinationFileName(properties.getProperty(DESTINATION_KEY),
+                        context.getParameterBindings());
     }
 
 }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsersTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsersTest.java
index 45929b766e0..b9bff125128 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsersTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetCopierForUsersTest.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
+import org.hamcrest.core.IsNull;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.testng.annotations.AfterMethod;
@@ -40,6 +41,10 @@ import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.filesystem.IPathCopier;
 import ch.systemsx.cisd.common.filesystem.ssh.ISshCommandExecutor;
+import ch.systemsx.cisd.common.mail.EMailAddress;
+import ch.systemsx.cisd.common.mail.IMailClient;
+import ch.systemsx.cisd.common.test.RecordingMatcher;
+import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ProcessingStatus;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
@@ -54,6 +59,8 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
 {
     private static final String USER_ID = "test-user";
 
+    private static final String USER_EMAIL = "a@bc.de";
+
     private static final String DS_LOCATION = "ds";
 
     private Mockery context;
@@ -68,6 +75,10 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
 
     private IImmutableCopierFactory hardLinkMakerFactory;
     
+    private IMailClient mailClient;
+
+    private ITimeProvider timeProvider;
+
     private File storeRoot;
 
     private File sshExecutableDummy;
@@ -86,6 +97,8 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
     public void beforeMethod() throws IOException
     {
         context = new Mockery();
+        timeProvider = context.mock(ITimeProvider.class);
+        mailClient = context.mock(IMailClient.class);
         pathFactory = context.mock(IPathCopierFactory.class);
         sshFactory = context.mock(ISshCommandExecutorFactory.class);
         hardLinkMakerFactory = context.mock(IImmutableCopierFactory.class);
@@ -101,9 +114,11 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
         properties.setProperty("ssh-executable", sshExecutableDummy.getPath());
         properties.setProperty("rsync-executable", rsyncExecutableDummy.getPath());
         DatasetDescriptionBuilder dsb =
-                new DatasetDescriptionBuilder("ds1").location(DS_LOCATION).sample("s").space("g")
+                new DatasetDescriptionBuilder("ds1").type("MY-DATA").location(DS_LOCATION).sample("s").space("g")
                         .project("p").experiment("e").databaseInstance("i");
         ds = dsb.getDatasetDescription();
+        ds.setExperimentIdentifier("/g/p/e");
+        ds.setExperimentTypeCode("MY_EXPERIMENT");
         File ds1Folder = new File(new File(storeRoot, DEFAULT_SHARE_ID), DS_LOCATION + "/original");
         ds1Folder.mkdirs();
         dsData = new File(ds1Folder, "data.txt");
@@ -113,7 +128,15 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
         MockDataSetDirectoryProvider directoryProvider =
                 new MockDataSetDirectoryProvider(storeRoot, DEFAULT_SHARE_ID);
         dataSetProcessingContext =
-                new DataSetProcessingContext(null, directoryProvider, parameterBindings, null, null);
+                new DataSetProcessingContext(null, directoryProvider, parameterBindings,
+                        mailClient, USER_EMAIL);
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(timeProvider).getTimeInMilliseconds();
+                    will(returnValue(42L));
+                }
+            });
     }
 
     @AfterMethod
@@ -128,23 +151,39 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
     public void testCopyWithDestinationTemplate()
     {
         properties.setProperty(DESTINATION_KEY, "tmp/${" + Constants.USER_PARAMETER + "}");
+        properties.setProperty(AbstractDropboxProcessingPlugin.SEND_DETAILED_EMAIL_KEY, "true");
         prepareCreateAndCheckCopier();
+        final RecordingMatcher<String> subjectRecorder = new RecordingMatcher<String>();
+        final RecordingMatcher<String> contentRecorder = new RecordingMatcher<String>();
+        final RecordingMatcher<EMailAddress[]> recipientsRecorder =
+                new RecordingMatcher<EMailAddress[]>();
         context.checking(new Expectations()
             {
                 {
                     File canonicalFile = getCanonicalFile("tmp/" + USER_ID);
                     one(copier).copyToRemote(dsData, canonicalFile, null, null, null);
                     will(returnValue(Status.OK));
+
+                    one(mailClient).sendEmailMessage(with(subjectRecorder), with(contentRecorder),
+                            with(new IsNull<EMailAddress>()), with(new IsNull<EMailAddress>()),
+                            with(recipientsRecorder));
                 }
             });
         DataSetCopier dataSetCopier =
                 new DataSetCopierForUsers(properties, storeRoot, pathFactory, sshFactory,
-                        hardLinkMakerFactory);
+                        hardLinkMakerFactory, timeProvider);
 
         ProcessingStatus processingStatus =
                 dataSetCopier.process(Arrays.asList(ds), dataSetProcessingContext);
         assertNoErrors(processingStatus);
         assertSuccessful(processingStatus, ds);
+        assertEquals(USER_EMAIL, recipientsRecorder.recordedObject()[0].tryGetEmailAddress());
+        assertEquals("Data set ds1 [MY-DATA] successfully processed",
+                subjectRecorder.recordedObject());
+        assertEquals("Successfully processed data set ds1 [MY-DATA].\n\n" + "Processing details:\n"
+                + "Description: Copy to tmp/test-user\n" + "Experiment: /g/p/e [MY_EXPERIMENT]\n"
+                + "Started: 1970-01-01 01:00:00 +0100.\n" + "Finished: 1970-01-01 01:00:00 +0100.",
+                contentRecorder.recordedObject());
 
         context.assertIsSatisfied();
     }
@@ -164,7 +203,7 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
             });
         DataSetCopier dataSetCopier =
                 new DataSetCopierForUsers(properties, storeRoot, pathFactory, sshFactory,
-                        hardLinkMakerFactory);
+                        hardLinkMakerFactory, timeProvider);
 
         ProcessingStatus processingStatus =
                 dataSetCopier.process(Arrays.asList(ds), dataSetProcessingContext);
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/dss/proteomics/server/plugins/DataSetCopier.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/dss/proteomics/server/plugins/DataSetCopier.java
index 07b85da7ba1..72e0c5de15e 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/dss/proteomics/server/plugins/DataSetCopier.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/dss/proteomics/server/plugins/DataSetCopier.java
@@ -27,6 +27,8 @@ import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.IPathCopierF
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.ISshCommandExecutorFactory;
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.RsyncCopierFactory;
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.SshCommandExecutorFactory;
+import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
 
 /**
  * 
@@ -50,7 +52,8 @@ public class DataSetCopier extends AbstractDropboxProcessingPlugin
     }
 
     @Override
-    protected String getProcessingDescription()
+    protected String getProcessingDescription(DatasetDescription dataset,
+            DataSetProcessingContext context)
     {
         return "Copy to " + properties.getProperty(DESTINATION_KEY);
     }
diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/DropboxProcessingPluginYeastX.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/DropboxProcessingPluginYeastX.java
index 41ab3e190c3..eb01f10a959 100644
--- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/DropboxProcessingPluginYeastX.java
+++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/DropboxProcessingPluginYeastX.java
@@ -21,7 +21,9 @@ import java.util.Properties;
 
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.AbstractDropboxProcessingPlugin;
+import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
 
 /**
  * A dropbox processing plugin that gets its dropbox directory from properties.
@@ -75,7 +77,8 @@ public class DropboxProcessingPluginYeastX extends AbstractDropboxProcessingPlug
     }
 
     @Override
-    protected String getProcessingDescription()
+    protected String getProcessingDescription(DatasetDescription dataset,
+            DataSetProcessingContext context)
     {
         return "Copy to " + properties.getProperty(DROPBOX_INCOMING_DIRECTORY_PROPERTY);
     }
-- 
GitLab