Skip to content
Snippets Groups Projects
Commit f76d1e8f authored by felmer's avatar felmer
Browse files

LMS-1880 IProcessingPluginTask modified, tests for ProcessDatasetsCommand written.

SVN: 19012
parent c1dda6a9
No related branches found
No related tags found
No related merge requests found
Showing
with 381 additions and 19 deletions
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.generic.server;
import java.util.Map;
import ch.systemsx.cisd.common.mail.IMailClient;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IProcessingPluginTask;
/**
* Context for processing data sets by a {@link IProcessingPluginTask}.
*
* @author Franz-Josef Elmer
*/
public class DataSetProcessingContext
{
private final Map<String, String> parameterBindings;
private final IMailClient mailClient;
private final String userEmailOrNull;
/**
* Creates an instance for specified parameter bindings, e-mail client, and user e-mail address.
*/
public DataSetProcessingContext(Map<String, String> parameterBindings, IMailClient mailClient,
String userEmailOrNull)
{
this.parameterBindings = parameterBindings;
this.mailClient = mailClient;
this.userEmailOrNull = userEmailOrNull;
}
public final Map<String, String> getParameterBindings()
{
return parameterBindings;
}
public final IMailClient getMailClient()
{
return mailClient;
}
public final String getUserEmailOrNull()
{
return userEmailOrNull;
}
}
......@@ -288,7 +288,7 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic
}
public ProcessingStatus process(List<DatasetDescription> datasets,
Map<String, String> parameterBindings)
DataSetProcessingContext context)
{
if (archive)
{
......
......@@ -21,11 +21,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.activation.DataHandler;
import org.apache.log4j.Logger;
import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
import ch.systemsx.cisd.common.exceptions.Status;
import ch.systemsx.cisd.common.logging.LogCategory;
import ch.systemsx.cisd.common.logging.LogFactory;
import ch.systemsx.cisd.common.mail.EMailAddress;
import ch.systemsx.cisd.common.mail.From;
import ch.systemsx.cisd.common.mail.IMailClient;
import ch.systemsx.cisd.common.mail.MailClient;
import ch.systemsx.cisd.common.mail.MailClientParameters;
......@@ -57,28 +62,96 @@ public class ProcessDatasetsCommand implements IDataSetCommand
private final DatastoreServiceDescription serviceDescription;
private final MailClientParameters mailClientParameters;
private final IMailClient mailClient;
public ProcessDatasetsCommand(IProcessingPluginTask task, List<DatasetDescription> datasets,
Map<String, String> parameterBindings, String userEmailOrNull,
DatastoreServiceDescription serviceDescription,
MailClientParameters mailClientParameters)
{
this(task, datasets, parameterBindings, userEmailOrNull, serviceDescription, new MailClient(mailClientParameters));
}
ProcessDatasetsCommand(IProcessingPluginTask task, List<DatasetDescription> datasets,
Map<String, String> parameterBindings, String userEmailOrNull,
DatastoreServiceDescription serviceDescription,
IMailClient mailClient)
{
this.task = task;
this.datasets = datasets;
this.parameterBindings = parameterBindings;
this.userEmailOrNull = userEmailOrNull;
this.serviceDescription = serviceDescription;
this.mailClientParameters = mailClientParameters;
this.mailClient = mailClient;
}
private static final class ProxyMailClient implements IMailClient
{
private final IMailClient mailClient;
private boolean mailSent;
ProxyMailClient(IMailClient mailClient){
this.mailClient = mailClient;
}
boolean hasMailSent()
{
return mailSent;
}
public void sendMessage(String subject, String content, String replyToOrNull,
From fromOrNull, String... recipients) throws EnvironmentFailureException
{
mailClient.sendMessage(subject, content, replyToOrNull, fromOrNull, recipients);
mailSent = true;
}
public void sendEmailMessage(String subject, String content, EMailAddress replyToOrNull,
EMailAddress fromOrNull, EMailAddress... recipients)
throws EnvironmentFailureException
{
mailClient.sendEmailMessage(subject, content, replyToOrNull, fromOrNull, recipients);
mailSent = true;
}
@SuppressWarnings("deprecation")
public void sendMessageWithAttachment(String subject, String content, String filename,
DataHandler attachmentContent, String replyToOrNull, From fromOrNull,
String... recipients) throws EnvironmentFailureException
{
mailClient.sendMessageWithAttachment(subject, content, filename, attachmentContent,
replyToOrNull, fromOrNull, recipients);
mailSent = true;
}
public void sendEmailMessageWithAttachment(String subject, String content, String filename,
DataHandler attachmentContent, EMailAddress replyToOrNull, EMailAddress fromOrNull,
EMailAddress... recipients) throws EnvironmentFailureException
{
mailClient.sendEmailMessageWithAttachment(subject, content, filename,
attachmentContent, replyToOrNull, fromOrNull, recipients);
mailSent = true;
}
public void sendTestEmail()
{
mailClient.sendTestEmail();
}
}
public void execute(File store)
{
String errorMessageOrNull = null;
ProcessingStatus processingStatusOrNull = null;
ProxyMailClient proxyMailClient = new ProxyMailClient(mailClient);
try
{
processingStatusOrNull = task.process(datasets, parameterBindings);
DataSetProcessingContext context =
new DataSetProcessingContext(parameterBindings, proxyMailClient,
userEmailOrNull);
processingStatusOrNull = task.process(datasets, context);
} catch (RuntimeException e)
{
// exception message should be readable for users
......@@ -101,7 +174,10 @@ public class ProcessDatasetsCommand implements IDataSetCommand
}
return;
}
createContentAndSendMessage(errorMessageOrNull, processingStatusOrNull);
if (proxyMailClient.hasMailSent() == false || errorMessageOrNull != null)
{
createContentAndSendMessage(errorMessageOrNull, processingStatusOrNull);
}
}
}
......@@ -134,7 +210,6 @@ public class ProcessDatasetsCommand implements IDataSetCommand
private void sendMessage(String subject, String content, String recipient)
{
final IMailClient mailClient = new MailClient(mailClientParameters);
mailClient.sendMessage(subject, content, null, null, recipient);
}
......
......@@ -18,9 +18,9 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.demo;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import ch.systemsx.cisd.openbis.dss.generic.server.DataSetProcessingContext;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IProcessingPluginTask;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ProcessingStatus;
import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
......@@ -39,7 +39,7 @@ public class DemoProcessingPlugin implements IProcessingPluginTask
}
public ProcessingStatus process(List<DatasetDescription> datasets,
Map<String, String> parameterBindings)
DataSetProcessingContext context)
{
System.out.println("Processing of the following datasets has been requested: " + datasets);
System.out.println("sleeping for 2 sec");
......
......@@ -27,6 +27,7 @@ import ch.systemsx.cisd.common.exceptions.Status;
import ch.systemsx.cisd.common.filesystem.FileUtilities;
import ch.systemsx.cisd.common.logging.LogCategory;
import ch.systemsx.cisd.common.logging.LogFactory;
import ch.systemsx.cisd.openbis.dss.generic.server.DataSetProcessingContext;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IProcessingPluginTask;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ProcessingStatus;
import ch.systemsx.cisd.openbis.dss.generic.shared.IPostRegistrationDatasetHandler;
......@@ -68,12 +69,12 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP
}
public ProcessingStatus process(List<DatasetDescription> datasets,
Map<String, String> parameterBindings)
DataSetProcessingContext context)
{
final ProcessingStatus result = new ProcessingStatus();
for (DatasetDescription dataset : datasets)
{
Status status = processDataset(dataset, parameterBindings);
Status status = processDataset(dataset, context.getParameterBindings());
result.addDatasetStatus(dataset, status);
}
return result;
......
......@@ -18,9 +18,8 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import ch.systemsx.cisd.openbis.generic.shared.Constants;
import ch.systemsx.cisd.openbis.dss.generic.server.DataSetProcessingContext;
import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
/**
......@@ -34,12 +33,12 @@ public interface IProcessingPluginTask extends Serializable
/**
* Processes asynchronously the specified datasets with specified parameter bindings.
*
* @param parameterBindings Contains at least the parameter {@link Constants#USER_PARAMETER} with
* the ID of the user who initiated processing.
* @param context Processing context which contains parameter bindings, mail-client, and user
* e-mail address.
* @returns {@link ProcessingStatus} of the finished processing with statuses of processing for
* all scheduled data sets or null if processing succeeded for all datasets and no
* additional information is provided.
*/
ProcessingStatus process(List<DatasetDescription> datasets, Map<String, String> parameterBindings);
ProcessingStatus process(List<DatasetDescription> datasets, DataSetProcessingContext context);
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.generic.server;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.core.IsAnything;
import org.hamcrest.core.IsNull;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import ch.systemsx.cisd.common.exceptions.Status;
import ch.systemsx.cisd.common.mail.From;
import ch.systemsx.cisd.common.mail.IMailClient;
import ch.systemsx.cisd.common.test.RecordingMatcher;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IProcessingPluginTask;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ProcessingStatus;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
/**
*
*
* @author Franz-Josef Elmer
*/
public class ProcessDatasetsCommandTest extends AssertJUnit
{
private static final String EXAMPLE_TASK_LABEL = "My task";
private static final String E_MAIL = "my@e.mail";
private static final String MESSAGE = "hello";
private Mockery context;
private IProcessingPluginTask task;
private IMailClient mailClient;
private DatasetDescription ds1;
private DatasetDescription ds2;
private ProcessDatasetsCommand command;
private List<DatasetDescription> dataSets;
private Map<String, String> parameterBindings;
private RecordingMatcher<String> subjectRecorder;
private RecordingMatcher<String> contentRecorder;
@BeforeMethod
public void beforeMethod() throws IOException
{
context = new Mockery();
task = context.mock(IProcessingPluginTask.class);
mailClient = context.mock(IMailClient.class);
ds1 = new DatasetDescription();
ds1.setDatasetCode("ds1");
ds2 = new DatasetDescription();
ds2.setDatasetCode("ds2");
parameterBindings = new HashMap<String, String>();
dataSets = Arrays.<DatasetDescription> asList(ds1, ds2);
command = new ProcessDatasetsCommand(task, dataSets,
parameterBindings, E_MAIL, new DatastoreServiceDescription("MY_TASK", EXAMPLE_TASK_LABEL,
new String[0], "DSS1"), mailClient);
subjectRecorder = new RecordingMatcher<String>();
contentRecorder = new RecordingMatcher<String>();
context.checking(new Expectations()
{
{
allowing(mailClient).sendMessage(with(subjectRecorder), with(contentRecorder),
with(new IsNull<String>()), with(new IsNull<From>()),
with(new IsAnything<String[]>()));
}
});
}
@AfterMethod
public void afterMethod()
{
// To following line of code should also be called at the end of each test method.
// Otherwise one do not known which test failed.
context.assertIsSatisfied();
}
@Test
public void testTaskPartiallyProcessedSuccessfully()
{
context.checking(new Expectations()
{
{
one(task).process(with(dataSets),
with(createDataSetProcessingContext(null)));
ProcessingStatus status = new ProcessingStatus();
status.addDatasetStatus(ds1, Status.OK);
status.addDatasetStatus(ds2, Status.createError(true, "Oops!"));
will(returnValue(status));
}
});
command.execute(null);
assertEquals("['" + EXAMPLE_TASK_LABEL + "' processing finished]", subjectRecorder
.getRecordedObjects().toString());
assertEquals("[This is an automatically generated report from the completed processing "
+ "of data sets in openBIS.\n"
+ "- number of successfully processed data sets: 1. Datasets: ds1\n"
+ "- processing of 1 data set(s) failed because: Oops!. Datasets: ds2\n" + "]",
contentRecorder.getRecordedObjects().toString());
context.assertIsSatisfied();
}
@Test
public void testTaskWhichThrowsException()
{
context.checking(new Expectations()
{
{
one(task).process(with(dataSets), with(createDataSetProcessingContext(null)));
will(throwException(new IllegalStateException("illegal state!")));
}
});
try
{
command.execute(null);
fail("IllegalStateException expected.");
} catch (IllegalStateException e)
{
assertEquals("illegal state!", e.getMessage());
}
assertEquals("['" + EXAMPLE_TASK_LABEL + "' processing failed]", subjectRecorder
.getRecordedObjects().toString());
assertEquals("['My task' processing failed on 2 data set(s): \nds1,ds2\n\n"
+ "Error message:\nillegal state!]", contentRecorder.getRecordedObjects()
.toString());
context.assertIsSatisfied();
}
@Test
public void testProcessingTaskSendsEMail()
{
context.checking(new Expectations()
{
{
one(task)
.process(with(dataSets), with(createDataSetProcessingContext(MESSAGE)));
}
});
command.execute(null);
assertEquals("[null]", subjectRecorder.getRecordedObjects().toString());
assertEquals("[hello]", contentRecorder.getRecordedObjects().toString());
context.assertIsSatisfied();
}
@Test
public void testProcessingTaskSendsEMailAndFails()
{
context.checking(new Expectations()
{
{
one(task)
.process(with(dataSets), with(createDataSetProcessingContext(MESSAGE)));
will(throwException(new RuntimeException()));
}
});
try
{
command.execute(null);
fail("RuntimeException expected");
} catch (RuntimeException e)
{
assertEquals(null, e.getMessage());
}
assertEquals("[null, 'My task' processing failed]", subjectRecorder.getRecordedObjects()
.toString());
assertEquals("[hello, 'My task' processing failed on 2 data set(s): \nds1,ds2\n\n"
+ "Error message:\n]", contentRecorder.getRecordedObjects().toString());
context.assertIsSatisfied();
}
private BaseMatcher<DataSetProcessingContext> createDataSetProcessingContext(
final String eMailMessageOrNull)
{
return new BaseMatcher<DataSetProcessingContext>()
{
public boolean matches(Object item)
{
DataSetProcessingContext processingContext = (DataSetProcessingContext) item;
assertEquals(parameterBindings, processingContext.getParameterBindings());
assertEquals(E_MAIL, processingContext.getUserEmailOrNull());
IMailClient client = processingContext.getMailClient();
if (eMailMessageOrNull != null)
{
client.sendMessage(null, eMailMessageOrNull, null, null);
}
return true;
}
public void describeTo(Description description)
{
}
};
}
}
......@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.jmock.Expectations;
......@@ -38,6 +39,7 @@ 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.openbis.dss.generic.server.DataSetProcessingContext;
import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ProcessingStatus;
import ch.systemsx.cisd.openbis.generic.shared.Constants;
import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
......@@ -74,7 +76,7 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
private File dsData;
private HashMap<String, String> parameterBindings;
private DataSetProcessingContext dataSetProcessingContext;
@BeforeMethod
public void beforeMethod() throws IOException
......@@ -105,8 +107,9 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
ds1Folder.mkdirs();
dsData = new File(ds1Folder, "data.txt");
dsData.createNewFile();
parameterBindings = new HashMap<String, String>();
Map<String, String> parameterBindings = new HashMap<String, String>();
parameterBindings.put(Constants.USER_PARAMETER, USER_ID);
dataSetProcessingContext = new DataSetProcessingContext(parameterBindings, null, null);
}
@AfterMethod
......@@ -134,7 +137,7 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
new DataSetCopierForUsers(properties, storeRoot, pathFactory, sshFactory);
ProcessingStatus processingStatus =
dataSetCopier.process(Arrays.asList(ds), parameterBindings);
dataSetCopier.process(Arrays.asList(ds), dataSetProcessingContext);
assertNoErrors(processingStatus);
assertSuccessful(processingStatus, ds);
......@@ -158,7 +161,7 @@ public class DataSetCopierForUsersTest extends AbstractFileSystemTestCase
new DataSetCopierForUsers(properties, storeRoot, pathFactory, sshFactory);
ProcessingStatus processingStatus =
dataSetCopier.process(Arrays.asList(ds), parameterBindings);
dataSetCopier.process(Arrays.asList(ds), dataSetProcessingContext);
assertNoErrors(processingStatus);
assertSuccessful(processingStatus, ds);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment