Skip to content

Commit 1ad1022

Browse files
committed
Merge branch 'develop' into fb_filewatcher_select
2 parents df2a57d + ee31d85 commit 1ad1022

File tree

12 files changed

+88
-175
lines changed

12 files changed

+88
-175
lines changed

api/schemas/expTypes.xsd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
<xs:element name="Comments" type="string" minOccurs="0"/>
9797
<xs:element name="ExperimentLSID" type="string" minOccurs="0" maxOccurs="1" />
9898
<xs:element name="Properties" type="exp:PropertyCollectionType" minOccurs="0"/>
99-
<xs:element name="WorkflowTaskLSID" type="string" minOccurs="0" maxOccurs="1" />
99+
<xs:element name="WorkflowTaskId" type="string" minOccurs="0" maxOccurs="1" />
100100
<xs:element name="ReplacedByRunLSID" type="string" minOccurs="0">
101101
<xs:annotation>
102102
<xs:documentation>Reference to another run that defines an updated version of this data</xs:documentation>

api/schemas/folder.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
<xs:element name="moduleProperties" minOccurs="0" type="modulePropertiesType"/>
9494
<xs:element name="xar" minOccurs="0" type="exportDirType" />
9595
<xs:element name="inventory" minOccurs="0" type="exportDirType"/>
96+
<xs:element name="workflow" minOccurs="0" type="exportDirType"/>
9697
<xs:element name="fileBrowserConfig" minOccurs="0" maxOccurs="1">
9798
<xs:complexType>
9899
<xs:attribute name="file" type="xs:string">

api/src/org/labkey/api/admin/FolderArchiveDataTypes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ private FolderArchiveDataTypes() {}
5151
public static final String DATA_CLASS_DATA = "Data Class Data";
5252
public static final String INVENTORY = "Inventory locations and items";
5353
public static final String VIEW_CATEGORIES = "Categories";
54+
public static final String WORKFLOW = "Workflow jobs, templates, tasks, actions and entities";
5455
}

api/src/org/labkey/api/admin/FolderImportContext.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class FolderImportContext extends AbstractFolderContext
5151
private String _xarJobId;
5252

5353
private final HashSet<String> _importedReports = new HashSet<>();
54+
private Map<Long, Long> _assayRunWorkflowTaskMap = new HashMap<>();
5455

5556
private static final String FOLDER_IMPORT_DB_SEQUENCE_PREFIX = "FolderImportJobCounter-";
5657

@@ -180,6 +181,16 @@ public void addImportedReport(ReportDescriptor d)
180181
_importedReports.add(ReportUtil.getSerializedName(d));
181182
}
182183

184+
public Map<Long, Long> getAssayRunWorkflowTaskMap()
185+
{
186+
return _assayRunWorkflowTaskMap;
187+
}
188+
189+
public void setAssayRunWorkflowTaskMap(Map<Long, Long> assayRunWorkflowTaskMap)
190+
{
191+
_assayRunWorkflowTaskMap = assayRunWorkflowTaskMap;
192+
}
193+
183194
@Override
184195
public AuditBehaviorType getAuditBehaviorType() throws Exception
185196
{

api/src/org/labkey/api/exp/api/ExpProtocol.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -165,21 +165,5 @@ default String getDocumentId()
165165
return String.join(":",getContainer().getId(), "assay", String.valueOf(getRowId()));
166166
}
167167

168-
static boolean isSampleWorkflowJobProtocol(String lsid)
169-
{
170-
return lsid.contains(ExperimentService.SAMPLE_MANAGEMENT_JOB_PROTOCOL_PREFIX);
171-
}
172-
173-
static boolean isSampleWorkflowTaskProtocol(String lsid)
174-
{
175-
return lsid.contains(ExperimentService.SAMPLE_MANAGEMENT_TASK_PROTOCOL_PREFIX);
176-
}
177-
178-
// TODO remove this and its relatives once the workflow folder import/export rewrite has happened.
179-
static boolean isSampleWorkflowProtocol(String lsid)
180-
{
181-
return isSampleWorkflowTaskProtocol(lsid) || isSampleWorkflowJobProtocol(lsid);
182-
}
183-
184168
Map<String, Object> getAuditRecordMap(AssayProvider provider);
185169
}

api/src/org/labkey/api/exp/api/ExperimentService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ ValidationException updateDataClass(
393393
*/
394394
@NotNull List<? extends ExpMaterial> getExpMaterialsByName(String name, @Nullable Container container, User user);
395395

396+
@NotNull List<? extends ExpMaterial> getExpMaterialsByName(@NotNull Collection<String> names, @NotNull String sampleTypeName, @NotNull Container container, User user);
397+
396398
@Nullable ExpData findExpData(
397399
Container c,
398400
User user,

experiment/src/org/labkey/experiment/XarExporter.java

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,8 @@ public void addExperimentRun(ExpRun run) throws ExperimentException
330330
addProtocolApplication(application, run, xApplications);
331331
}
332332

333-
// TODO need to update this for run workflowTaskId support in XAR on workflow job folder export/import is supported
334-
//ExpProtocolApplication workflowTask = run.getWorkflowTask();
335-
//if (workflowTask != null)
336-
//{
337-
// // Due to the way ProtocolApplication LSIDs are generated we can't actually round trip them the normal way
338-
// // via the LSIDRelativizer. Instead we construct an LSID out of the object ID with a custom prefix.
339-
// String workflowObjectId = Lsid.parse(workflowTask.getLSID()).getObjectId();
340-
// xRun.setWorkflowTaskLSID("${WorkflowTaskReference}:" + workflowObjectId);
341-
//}
333+
if (run.getWorkflowTaskId() != null)
334+
xRun.setWorkflowTaskId(run.getWorkflowTaskId().toString());
342335

343336
// get AssayService.get().getProvider(run).getXarCallbacks().beforeXarExportRun() with simple attempt at caching for common case
344337
if (null != AssayService.get())
@@ -1407,38 +1400,6 @@ private PropertyCollectionType getProperties(Map<String, ObjectProperty> propert
14071400
catch (URISyntaxException ignored) {}
14081401
simpleValue.setStringValue(link);
14091402
}
1410-
// This property stores rowIds of assay designs; we need to translate them to LSIDs for export
1411-
// TODO perhaps this property should hold protocol strings instead of rowIds
1412-
else if (value.getPropertyURI().endsWith(":WorkflowTask#AssayTypes"))
1413-
{
1414-
String assayIdsString = value.getStringValue();
1415-
if (!StringUtils.isEmpty(assayIdsString))
1416-
{
1417-
String[] assayIds = assayIdsString.split(",");
1418-
List<String> protocolStrings = new ArrayList<>();
1419-
List<ExpProtocol> protocols = AssayService.get().getAssayProtocols(value.getContainer());
1420-
for (String assayId : assayIds)
1421-
{
1422-
try
1423-
{
1424-
int assayRowId = Integer.parseInt(assayId);
1425-
Optional<ExpProtocol> protocol = protocols.stream().filter(p -> p.getRowId() == assayRowId).findFirst();
1426-
if (protocol.isPresent())
1427-
protocolStrings.add(relativizeLSIDPropertyValue(protocol.get().getLSID(), SimpleTypeNames.STRING));
1428-
else
1429-
logProgress("Unable to find protocol for assay id " + assayRowId + ". Not included in values for " + value.getName() + ".");
1430-
}
1431-
catch (NumberFormatException ignore)
1432-
{
1433-
// assume it's an LSID and try to relativize it
1434-
protocolStrings.add(relativizeLSIDPropertyValue(assayId, SimpleTypeNames.STRING));
1435-
}
1436-
}
1437-
simpleValue.setStringValue(StringUtils.join(protocolStrings, ","));
1438-
}
1439-
else
1440-
simpleValue.setStringValue(assayIdsString);
1441-
}
14421403
else
14431404
{
14441405
simpleValue.setStringValue(relativizeLSIDPropertyValue(value.getStringValue(), SimpleTypeNames.STRING));

experiment/src/org/labkey/experiment/XarReader.java

Lines changed: 42 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.fhcrc.cpas.exp.xml.*;
3030
import org.jetbrains.annotations.NotNull;
3131
import org.jetbrains.annotations.Nullable;
32+
import org.labkey.api.admin.FolderImportContext;
3233
import org.labkey.api.assay.AssayProvider;
3334
import org.labkey.api.assay.AssayService;
3435
import org.labkey.api.collections.LongHashMap;
@@ -138,7 +139,8 @@ public class XarReader extends AbstractXarImporter
138139

139140
private final Set<String> _experimentLSIDs = new HashSet<>();
140141
private final Map<String, Integer> _propertyIdMap = new HashMap<>();
141-
private final Map<Long, String> _runWorkflowTaskMap = new LongHashMap<>();
142+
private final Map<Long, Long> _runWorkflowTaskMap = new LongHashMap<>();
143+
private final FolderImportContext _folderImportContext;
142144
/** Retain replacement info so we can wire them up after all runs have been imported */
143145
private final Map<Long, String> _runReplacedByMap = new LongHashMap<>();
144146

@@ -168,9 +170,15 @@ public class XarReader extends AbstractXarImporter
168170
private AuditBehaviorType _auditBehaviorType = null;
169171

170172
public XarReader(XarSource source, PipelineJob job)
173+
{
174+
this(source, job, null);
175+
}
176+
177+
public XarReader(XarSource source, PipelineJob job, FolderImportContext ctx)
171178
{
172179
super(source, job);
173180
_fileRootPath = getContainerFileRootPath(job.getContainer());
181+
_folderImportContext = ctx;
174182
}
175183

176184
public void setReloadExistingRuns(boolean reloadExistingRuns)
@@ -429,10 +437,8 @@ private void loadDoc() throws ExperimentException
429437
}
430438
}
431439

432-
if (!_runWorkflowTaskMap.isEmpty())
433-
{
434-
saveRunWorkflowTaskIds();
435-
}
440+
if (_folderImportContext != null)
441+
_folderImportContext.setAssayRunWorkflowTaskMap(_runWorkflowTaskMap);
436442

437443
resolveReplacedByRunLSIDs();
438444

@@ -1100,56 +1106,45 @@ private void loadExperimentRun(ExperimentRunType a, List<ExpMaterial> startingMa
11001106
}
11011107
}
11021108

1103-
if (run == null)
1104-
{
1105-
ExperimentRun vals = new ExperimentRun();
1106-
// todo not sure about having roots stored in database
1107-
// todo support substitutions here?
11081109

1109-
vals.setLSID(pRunLSID.toString());
1110+
ExperimentRun vals = new ExperimentRun();
1111+
// todo not sure about having roots stored in database
1112+
// todo support substitutions here?
11101113

1111-
vals.setName(trimString(a.getName()));
1112-
vals.setProtocolLSID(protocol.getLSID());
1113-
vals.setComments(trimString(a.getComments()));
1114+
vals.setLSID(pRunLSID.toString());
11141115

1115-
vals.setFilePathRoot(FileUtil.getAbsolutePath(_xarSource.getJobRootPath()));
1116-
vals.setContainer(getContainer());
1117-
// TODO need to update this for run workflowTaskId support in XAR on workflow job folder export/import is supported
1118-
//String workflowTaskLSID = a.getWorkflowTaskLSID();
1119-
//if (workflowTaskLSID != null)
1120-
//{
1121-
// if (!workflowTaskLSID.startsWith("${WorkflowTaskReference}:"))
1122-
// throw new XarFormatException("Invalid WorkflowTaskLSID encountered: " + workflowTaskLSID);
1123-
//
1124-
// workflowTaskLSID = workflowTaskLSID.split(":")[1];
1125-
//}
1126-
if (_job != null)
1127-
{
1128-
// remember which job created the run so we can show this run on the job details page
1129-
vals.setJobId(PipelineService.get().getJobId(_job.getUser(), _job.getContainer(), _job.getJobGUID()));
1130-
}
1116+
vals.setName(trimString(a.getName()));
1117+
vals.setProtocolLSID(protocol.getLSID());
1118+
vals.setComments(trimString(a.getComments()));
11311119

1132-
ExpRunImpl impl = new ExpRunImpl(vals);
1133-
try
1134-
{
1135-
impl.save(getUser());
1136-
run = impl.getDataObject();
1120+
vals.setFilePathRoot(FileUtil.getAbsolutePath(_xarSource.getJobRootPath()));
1121+
vals.setContainer(getContainer());
11371122

1138-
//if (workflowTaskLSID != null)
1139-
// _runWorkflowTaskMap.put(run.getRowId(), workflowTaskLSID);
1123+
if (_job != null)
1124+
{
1125+
// remember which job created the run so we can show this run on the job details page
1126+
vals.setJobId(PipelineService.get().getJobId(_job.getUser(), _job.getContainer(), _job.getJobGUID()));
1127+
}
11401128

1141-
String replacedByLSID = a.getReplacedByRunLSID();
1142-
if (replacedByLSID != null)
1143-
// Save for later so that we can resolve after everything's been imported
1144-
{
1145-
_runReplacedByMap.put(impl.getRowId(), replacedByLSID);
1146-
}
1147-
}
1148-
catch (BatchValidationException x)
1129+
ExpRunImpl impl = new ExpRunImpl(vals);
1130+
try
1131+
{
1132+
impl.save(getUser());
1133+
run = impl.getDataObject();
1134+
String taskIdStr = a.getWorkflowTaskId();
1135+
if (taskIdStr != null)
1136+
_runWorkflowTaskMap.put(run.getRowId(), Long.valueOf(taskIdStr));
1137+
String replacedByLSID = a.getReplacedByRunLSID();
1138+
if (replacedByLSID != null)
1139+
// Save for later so that we can resolve after everything's been imported
11491140
{
1150-
throw new ExperimentException(x);
1141+
_runReplacedByMap.put(impl.getRowId(), replacedByLSID);
11511142
}
11521143
}
1144+
catch (BatchValidationException x)
1145+
{
1146+
throw new ExperimentException(x);
1147+
}
11531148

11541149
if (experimentLSID != null)
11551150
{
@@ -1208,46 +1203,6 @@ private void loadExperimentRun(ExperimentRunType a, List<ExpMaterial> startingMa
12081203
getLog().debug("Finished loading ExperimentRun with LSID '" + runLSID + "'");
12091204
}
12101205

1211-
/**
1212-
* // TODO need to update this for run workflowTaskId support in XAR
1213-
* This method runs last, and is used to wire up the Workflow Task FK relationship between Exp Runs and
1214-
* Exp ProtocolApplications. This needs to run last because we have no good way to guarantee import order and ensure
1215-
* all the appropriate ProtocolApplications are imported before the Exp Runs.
1216-
*/
1217-
private void saveRunWorkflowTaskIds() throws ExperimentException
1218-
{
1219-
for (ExpRun run : _loadedRuns)
1220-
{
1221-
String objectId = _runWorkflowTaskMap.get(run.getRowId());
1222-
1223-
if (objectId != null)
1224-
{
1225-
List<? extends ExpProtocolApplication> protocolApplications = ExperimentService.get().getExpProtocolApplicationsByObjectId(getContainer(), objectId);
1226-
1227-
if (protocolApplications.size() > 1)
1228-
{
1229-
throw new ExperimentException("Multiple ProtocolApplications found with object id: " + objectId);
1230-
}
1231-
else if (protocolApplications.isEmpty())
1232-
{
1233-
getLog().warn("Could not find ProtocolApplication with LSID containing object id: " + objectId);
1234-
}
1235-
else
1236-
{
1237-
run.setWorkflowTaskId(protocolApplications.get(0).getRowId());
1238-
1239-
try {
1240-
run.save(getUser());
1241-
}
1242-
catch (BatchValidationException e)
1243-
{
1244-
throw new ExperimentException(e);
1245-
}
1246-
}
1247-
}
1248-
}
1249-
}
1250-
12511206
public List<String> getProcessedRunsLSIDs()
12521207
{
12531208
return _processedRunsLSIDs;
@@ -1449,9 +1404,7 @@ private void loadProtocolApplication(ProtocolApplicationBaseType xmlProtocolApp,
14491404
if ((protocolLSID.equals(SAMPLE_ALIQUOT_PROTOCOL_LSID) || protocolLSID.equals(SAMPLE_DERIVATION_PROTOCOL_LSID)) &&
14501405
!material.isOperationPermitted(SampleTypeService.SampleOperations.EditLineage))
14511406
return SampleTypeService.get().getOperationNotPermittedMessage(Collections.singleton(material), SampleTypeService.SampleOperations.EditLineage);
1452-
if ((ExpProtocol.isSampleWorkflowProtocol(protocolLSID))
1453-
&& !material.isOperationPermitted(SampleTypeService.SampleOperations.AddToWorkflow))
1454-
return SampleTypeService.get().getOperationNotPermittedMessage(Collections.singleton(material), SampleTypeService.SampleOperations.AddToWorkflow);
1407+
14551408
return null;
14561409
}
14571410

experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,23 @@ public List<ExpMaterialImpl> getExpMaterialsByName(@NotNull String name, @Nullab
855855
.toList();
856856
}
857857

858+
@NotNull
859+
@Override
860+
public List<ExpMaterialImpl> getExpMaterialsByName(@NotNull Collection<String> names, @NotNull String sampleTypeName, @NotNull Container container, User user)
861+
{
862+
ExpSampleType sampleType = SampleTypeService.get().getSampleType(container, user, sampleTypeName);
863+
if (sampleType == null)
864+
return Collections.emptyList();
865+
SimpleFilter filter = new SimpleFilter(FieldKey.fromParts(ExpMaterialTable.Column.Name.name()), names, IN);
866+
filter.addCondition(FieldKey.fromParts("Container"), container);
867+
filter.addCondition(FieldKey.fromParts("CpasType"), sampleType.getLSID());
868+
869+
return getExpMaterials(filter)
870+
.stream()
871+
.filter(m -> m.getContainer().hasPermission(user, ReadPermission.class) && m.getSampleType() != null)
872+
.toList();
873+
}
874+
858875
public @Nullable ExpMaterialImpl getExpMaterial(SimpleFilter filter)
859876
{
860877
Material material = new TableSelector(getTinfoMaterial(), filter, null).getObject(Material.class);

experiment/src/org/labkey/experiment/samples/AbstractExpFolderImporter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ else if (file.equalsIgnoreCase(XAR_RUNS_NAME) || file.equalsIgnoreCase(XAR_RUNS_
157157
throw(e);
158158
}
159159
log.info("Importing the runs XAR file: " + runsXarFile.getName());
160-
XarReader runsReader = new FolderXarImporterFactory.FolderExportXarReader(runsXarSource, job);
160+
XarReader runsReader = new FolderXarImporterFactory.FolderExportXarReader(runsXarSource, job, ctx);
161161
runsReader.setStrictValidateExistingSampleType(xarCtx.isStrictValidateExistingSampleType());
162162
runsReader.parseAndLoad(false, ctx.getAuditBehaviorType());
163163
}
@@ -220,7 +220,7 @@ protected XarReader getXarReader(@Nullable PipelineJob job, FolderImportContext
220220
log.error("Failed to initialize types XAR source", e);
221221
throw(e);
222222
}
223-
return new FolderXarImporterFactory.FolderExportXarReader(typesXarSource, job);
223+
return new FolderXarImporterFactory.FolderExportXarReader(typesXarSource, job, ctx);
224224
}
225225

226226
protected PipelineJob getDummyPipelineJob(FolderImportContext ctx)

0 commit comments

Comments
 (0)