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

LMS-1219 Extend FlowLineFeeder

SVN: 12876
parent 2f6f494e
No related branches found
No related tags found
No related merge requests found
...@@ -19,7 +19,9 @@ package ch.ethz.bsse.cisd.dsu.dss; ...@@ -19,7 +19,9 @@ package ch.ethz.bsse.cisd.dsu.dss;
import java.io.File; import java.io.File;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import ch.systemsx.cisd.common.TimingParameters; import ch.systemsx.cisd.common.TimingParameters;
...@@ -27,11 +29,20 @@ import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; ...@@ -27,11 +29,20 @@ import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
import ch.systemsx.cisd.common.filesystem.FastRecursiveHardLinkMaker; import ch.systemsx.cisd.common.filesystem.FastRecursiveHardLinkMaker;
import ch.systemsx.cisd.common.filesystem.FileOperations; import ch.systemsx.cisd.common.filesystem.FileOperations;
import ch.systemsx.cisd.common.filesystem.FileUtilities;
import ch.systemsx.cisd.common.filesystem.IFileOperations; import ch.systemsx.cisd.common.filesystem.IFileOperations;
import ch.systemsx.cisd.common.filesystem.IImmutableCopier; import ch.systemsx.cisd.common.filesystem.IImmutableCopier;
import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.common.utilities.PropertyUtils;
import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
import ch.systemsx.cisd.openbis.dss.generic.shared.IPostRegistrationDatasetHandler; import ch.systemsx.cisd.openbis.dss.generic.shared.IPostRegistrationDatasetHandler;
import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
/** /**
* Post registration data set handler which makes a hard-link copy of all flow-line files * Post registration data set handler which makes a hard-link copy of all flow-line files
...@@ -44,13 +55,15 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler ...@@ -44,13 +55,15 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler
static final String FLOW_LINE_DROP_BOX_TEMPLATE = "flow-line-drop-box-template"; static final String FLOW_LINE_DROP_BOX_TEMPLATE = "flow-line-drop-box-template";
static final String FILE_TYPE = ".srf"; static final String FILE_TYPE = ".srf";
private final IEncapsulatedOpenBISService service;
private final MessageFormat flowLineDropBoxTemplate; private final MessageFormat flowLineDropBoxTemplate;
private final IImmutableCopier copier; private final IImmutableCopier copier;
private final IFileOperations fileOperations; private final IFileOperations fileOperations;
private final List<File> flowLineDataSets = new ArrayList<File>(); private final List<File> flowLineDataSets = new ArrayList<File>();
FlowLineFeeder(Properties properties) FlowLineFeeder(Properties properties, IEncapsulatedOpenBISService service)
{ {
this.service = service;
flowLineDropBoxTemplate = flowLineDropBoxTemplate =
new MessageFormat(PropertyUtils.getMandatoryProperty(properties, new MessageFormat(PropertyUtils.getMandatoryProperty(properties,
FLOW_LINE_DROP_BOX_TEMPLATE)); FLOW_LINE_DROP_BOX_TEMPLATE));
...@@ -60,6 +73,7 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler ...@@ -60,6 +73,7 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler
public void handle(File originalData, DataSetInformation dataSetInformation) public void handle(File originalData, DataSetInformation dataSetInformation)
{ {
Map<String, Sample> flowLineSampleMap = createFlowLineSampleMap(dataSetInformation);
String flowcellID = originalData.getName(); String flowcellID = originalData.getName();
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<File>();
findFiles(originalData, files); findFiles(originalData, files);
...@@ -68,6 +82,11 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler ...@@ -68,6 +82,11 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler
String flowLine = extractFlowLine(file); String flowLine = extractFlowLine(file);
File dropBox = createDropBoxFile(flowLine); File dropBox = createDropBoxFile(flowLine);
File flowLineDataSet = new File(dropBox, flowcellID + "_" + flowLine); File flowLineDataSet = new File(dropBox, flowcellID + "_" + flowLine);
if (flowLineDataSet.exists())
{
throw new EnvironmentFailureException("There is already a data set for flow line "
+ flowLine + ".");
}
flowLineDataSets.add(flowLineDataSet); flowLineDataSets.add(flowLineDataSet);
boolean success = flowLineDataSet.mkdir(); boolean success = flowLineDataSet.mkdir();
if (success == false) if (success == false)
...@@ -75,6 +94,7 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler ...@@ -75,6 +94,7 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler
throw new EnvironmentFailureException("Couldn't create folder '" throw new EnvironmentFailureException("Couldn't create folder '"
+ flowLineDataSet.getAbsolutePath() + "'."); + flowLineDataSet.getAbsolutePath() + "'.");
} }
createMetaDataFile(flowLineDataSet, flowLineSampleMap, flowLine);
success = copier.copyImmutably(file, flowLineDataSet, null); success = copier.copyImmutably(file, flowLineDataSet, null);
if (success == false) if (success == false)
{ {
...@@ -86,6 +106,51 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler ...@@ -86,6 +106,51 @@ class FlowLineFeeder implements IPostRegistrationDatasetHandler
} }
private Map<String, Sample> createFlowLineSampleMap(DataSetInformation dataSetInformation)
{
SampleIdentifier sampleIdentifier = dataSetInformation.getSampleIdentifier();
Sample flowCell = service.tryGetSampleWithExperiment(sampleIdentifier);
if (flowCell == null)
{
throw new UserFailureException("Unkown flow cell sample: " + sampleIdentifier);
}
TechId flowCellID = new TechId(flowCell.getId());
ListSampleCriteria criteria = ListSampleCriteria.createForContainer(flowCellID);
List<Sample> flowLineSamples = service.listSamples(criteria);
Map<String, Sample> flowLineSampleMap = new LinkedHashMap<String, Sample>();
for (Sample flowLineSample : flowLineSamples)
{
flowLineSampleMap.put(flowLineSample.getSubCode(), flowLineSample);
}
return flowLineSampleMap;
}
private void createMetaDataFile(File flowLineDataSet, Map<String, Sample> flowLineSampleMap,
String flowLine)
{
Sample flowLineSample = flowLineSampleMap.get(flowLine);
if (flowLineSample == null)
{
throw new UserFailureException("No flow line sample for flow line " + flowLine + " exists");
}
StringBuilder builder = new StringBuilder();
addLine(builder, "Parent", flowLineSample.getGeneratedFrom().getIdentifier());
addLine(builder, "Code", flowLineSample.getCode());
addLine(builder, "Contact Person Email", flowLineSample.getRegistrator().getEmail());
SampleIdentifier identifier = SampleIdentifierFactory.parse(flowLineSample.getIdentifier());
IEntityProperty[] properties = service.getPropertiesOfTopSampleRegisteredFor(identifier);
for (IEntityProperty property : properties)
{
addLine(builder, property.getPropertyType().getLabel(), property.tryGetAsString());
}
FileUtilities.writeToFile(new File(flowLineDataSet, "meta-data.tsv"), builder.toString());
}
private void addLine(StringBuilder builder, String key, String value)
{
builder.append(key).append('\t').append(value).append('\n');
}
private File createDropBoxFile(String flowLine) private File createDropBoxFile(String flowLine)
{ {
File dropBox = new File(flowLineDropBoxTemplate.format(new Object[] {flowLine})); File dropBox = new File(flowLineDropBoxTemplate.format(new Object[] {flowLine}));
......
...@@ -19,6 +19,7 @@ package ch.ethz.bsse.cisd.dsu.dss; ...@@ -19,6 +19,7 @@ package ch.ethz.bsse.cisd.dsu.dss;
import java.util.Properties; import java.util.Properties;
import ch.systemsx.cisd.etlserver.DelegatingStorageProcessorWithDropbox; import ch.systemsx.cisd.etlserver.DelegatingStorageProcessorWithDropbox;
import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
/** /**
* Storage processor which feeds flow-line drop boxes. Needs the property * Storage processor which feeds flow-line drop boxes. Needs the property
...@@ -31,7 +32,7 @@ public class StorageProcessor extends DelegatingStorageProcessorWithDropbox ...@@ -31,7 +32,7 @@ public class StorageProcessor extends DelegatingStorageProcessorWithDropbox
{ {
public StorageProcessor(Properties properties) public StorageProcessor(Properties properties)
{ {
super(properties, new FlowLineFeeder(properties)); super(properties, new FlowLineFeeder(properties, ServiceProvider.getOpenBISService()));
} }
} }
...@@ -18,8 +18,15 @@ package ch.ethz.bsse.cisd.dsu.dss; ...@@ -18,8 +18,15 @@ package ch.ethz.bsse.cisd.dsu.dss;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
...@@ -27,6 +34,14 @@ import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase; ...@@ -27,6 +34,14 @@ import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.common.filesystem.FileUtilities;
import ch.systemsx.cisd.common.test.AssertionUtil; import ch.systemsx.cisd.common.test.AssertionUtil;
import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
/** /**
* *
...@@ -35,21 +50,52 @@ import ch.systemsx.cisd.common.test.AssertionUtil; ...@@ -35,21 +50,52 @@ import ch.systemsx.cisd.common.test.AssertionUtil;
*/ */
public class FlowLineFeederTest extends AbstractFileSystemTestCase public class FlowLineFeederTest extends AbstractFileSystemTestCase
{ {
private static final Sample EXAMPLE_FLOW_CELL_SAMPLE = createFlowCellSample();
private static final DataSetInformation EXAMPLE_DATA_SET_INFO = createDataSetInfo();
private static final String SAMPLE_CODE = "fc";
private static final String DROP_BOX_PREFIX = "drop-box-"; private static final String DROP_BOX_PREFIX = "drop-box-";
private static DataSetInformation createDataSetInfo()
{
DataSetInformation dataSetInfo = new DataSetInformation();
dataSetInfo.setSampleCode(SAMPLE_CODE);
return dataSetInfo;
}
private static Sample createFlowCellSample()
{
Sample sample = new Sample();
sample.setId(42L);
sample.setCode(SAMPLE_CODE);
return sample;
}
private FlowLineFeeder flowLineFeeder; private FlowLineFeeder flowLineFeeder;
private Mockery context;
private IEncapsulatedOpenBISService service;
@Override @Override
@BeforeMethod @BeforeMethod
public void setUp() throws IOException public void setUp() throws IOException
{ {
super.setUp(); super.setUp();
context = new Mockery();
service = context.mock(IEncapsulatedOpenBISService.class);
assertEquals(true, new File(workingDirectory, DROP_BOX_PREFIX + "1").mkdirs()); assertEquals(true, new File(workingDirectory, DROP_BOX_PREFIX + "1").mkdirs());
assertEquals(true, new File(workingDirectory, DROP_BOX_PREFIX + "2").mkdirs()); assertEquals(true, new File(workingDirectory, DROP_BOX_PREFIX + "2").mkdirs());
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(FlowLineFeeder.FLOW_LINE_DROP_BOX_TEMPLATE, new File( properties.setProperty(FlowLineFeeder.FLOW_LINE_DROP_BOX_TEMPLATE, new File(
workingDirectory, DROP_BOX_PREFIX).getAbsolutePath() workingDirectory, DROP_BOX_PREFIX).getAbsolutePath()
+ "{0}"); + "{0}");
flowLineFeeder = new FlowLineFeeder(properties); flowLineFeeder = new FlowLineFeeder(properties, service);
}
@AfterMethod
public void tearDown()
{
// To following line of code should also be called at the end of each test method.
// Otherwise one does not known which test failed.
context.assertIsSatisfied();
} }
@Test @Test
...@@ -57,13 +103,15 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase ...@@ -57,13 +103,15 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase
{ {
try try
{ {
new FlowLineFeeder(new Properties()); new FlowLineFeeder(new Properties(), service);
fail("ConfigurationFailureException expected"); fail("ConfigurationFailureException expected");
} catch (ConfigurationFailureException ex) } catch (ConfigurationFailureException ex)
{ {
assertEquals("Given key '" + FlowLineFeeder.FLOW_LINE_DROP_BOX_TEMPLATE assertEquals("Given key '" + FlowLineFeeder.FLOW_LINE_DROP_BOX_TEMPLATE
+ "' not found in properties '[]'", ex.getMessage()); + "' not found in properties '[]'", ex.getMessage());
} }
context.assertIsSatisfied();
} }
@Test @Test
...@@ -72,15 +120,38 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase ...@@ -72,15 +120,38 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase
File flowCell = new File(workingDirectory, "abc"); File flowCell = new File(workingDirectory, "abc");
assertEquals(true, flowCell.mkdir()); assertEquals(true, flowCell.mkdir());
FileUtilities.writeToFile(new File(flowCell, "s_3.srf"), "hello flow line 3"); FileUtilities.writeToFile(new File(flowCell, "s_3.srf"), "hello flow line 3");
prepareLoadFlowCellSample(EXAMPLE_FLOW_CELL_SAMPLE);
prepareListFlowLines(EXAMPLE_FLOW_CELL_SAMPLE, Arrays.<Sample>asList());
try try
{ {
flowLineFeeder.handle(flowCell, null); flowLineFeeder.handle(flowCell, EXAMPLE_DATA_SET_INFO);
fail("ConfigurationFailureException expected"); fail("ConfigurationFailureException expected");
} catch (ConfigurationFailureException ex) } catch (ConfigurationFailureException ex)
{ {
AssertionUtil.assertContains(DROP_BOX_PREFIX + "3", ex.getMessage()); AssertionUtil.assertContains(DROP_BOX_PREFIX + "3", ex.getMessage());
} }
context.assertIsSatisfied();
}
@Test
public void testUnkownFlowCell()
{
File flowCell = new File(workingDirectory, "abc");
prepareLoadFlowCellSample(null);
try
{
flowLineFeeder.handle(flowCell, EXAMPLE_DATA_SET_INFO);
fail("UserFailureException expected");
} catch (UserFailureException ex)
{
assertEquals("Unkown flow cell sample: " + EXAMPLE_DATA_SET_INFO.getSampleIdentifier(),
ex.getMessage());
}
context.assertIsSatisfied();
} }
@Test @Test
...@@ -97,11 +168,18 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase ...@@ -97,11 +168,18 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase
FileUtilities.writeToFile(originalFlowLine1, "hello flow line 1"); FileUtilities.writeToFile(originalFlowLine1, "hello flow line 1");
File originalFlowLine2 = new File(srfFolder, "2.srf"); File originalFlowLine2 = new File(srfFolder, "2.srf");
FileUtilities.writeToFile(originalFlowLine2, "hello flow line 2"); FileUtilities.writeToFile(originalFlowLine2, "hello flow line 2");
prepareLoadFlowCellSample(EXAMPLE_FLOW_CELL_SAMPLE);
Sample fl1 = createFlowLineSample(1);
Sample fl2 = createFlowLineSample(2);
prepareListFlowLines(EXAMPLE_FLOW_CELL_SAMPLE, Arrays.asList(fl1, fl2));
flowLineFeeder.handle(flowCell, null); flowLineFeeder.handle(flowCell, EXAMPLE_DATA_SET_INFO);
checkFlowLineDataSet(originalFlowLine1, "1"); checkFlowLineDataSet(originalFlowLine1, "1");
checkFlowLineDataSet(originalFlowLine2, "2"); checkFlowLineDataSet(originalFlowLine2, "2");
context.assertIsSatisfied();
} }
@Test @Test
...@@ -116,6 +194,53 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase ...@@ -116,6 +194,53 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase
assertEquals(0, new File(workingDirectory, DROP_BOX_PREFIX + "1").list().length); assertEquals(0, new File(workingDirectory, DROP_BOX_PREFIX + "1").list().length);
assertEquals(0, new File(workingDirectory, DROP_BOX_PREFIX + "2").list().length); assertEquals(0, new File(workingDirectory, DROP_BOX_PREFIX + "2").list().length);
} }
private void prepareLoadFlowCellSample(final Sample flowCellSample)
{
context.checking(new Expectations()
{
{
one(service).tryGetSampleWithExperiment(EXAMPLE_DATA_SET_INFO.getSampleIdentifier());
will(returnValue(flowCellSample));
}
});
}
private void prepareListFlowLines(final Sample flowCellSample, final List<Sample> flowLineSamples)
{
context.checking(new Expectations()
{
{
one(service).listSamples(with(new BaseMatcher<ListSampleCriteria>()
{
public boolean matches(Object item)
{
if (item instanceof ListSampleCriteria)
{
ListSampleCriteria criteria = (ListSampleCriteria) item;
return criteria.getContainerSampleId().getId().equals(
flowCellSample.getId());
}
return false;
}
public void describeTo(Description description)
{
description.appendText("Flow cell with ID "
+ flowCellSample.getId());
}
}));
will(returnValue(flowLineSamples));
for (Sample sample : flowLineSamples)
{
SampleIdentifier identifier =
SampleIdentifierFactory.parse(sample.getIdentifier());
one(service).getPropertiesOfTopSampleRegisteredFor(identifier);
}
}
});
}
private void checkFlowLineDataSet(File originalFlowLine, String flowLineNumber) private void checkFlowLineDataSet(File originalFlowLine, String flowLineNumber)
{ {
...@@ -132,4 +257,19 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase ...@@ -132,4 +257,19 @@ public class FlowLineFeederTest extends AbstractFileSystemTestCase
originalFlowLine.setLastModified(4711000); originalFlowLine.setLastModified(4711000);
assertEquals(4711000, flowLine.lastModified()); assertEquals(4711000, flowLine.lastModified());
} }
private Sample createFlowLineSample(int flowLineNumber)
{
Sample sample = new Sample();
sample.setCode(SAMPLE_CODE);
sample.setSubCode(Integer.toString(flowLineNumber));
sample.setGeneratedFrom(EXAMPLE_FLOW_CELL_SAMPLE);
Person registrator = new Person();
registrator.setEmail("ab@c.de");
sample.setRegistrator(registrator);
sample.setIdentifier(SAMPLE_CODE + SampleIdentifier.CONTAINED_SAMPLE_CODE_SEPARARTOR_STRING
+ flowLineNumber);
return sample;
}
} }
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