Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2667,7 +2667,6 @@ study/src/org/labkey/study/model/StudyImpl.java -text
study/src/org/labkey/study/model/StudyLsidHandler.java -text
study/src/org/labkey/study/model/StudyManager.java -text
study/src/org/labkey/study/model/StudySnapshot.java -text
study/src/org/labkey/study/model/UploadLog.java -text
study/src/org/labkey/study/model/VisitDataset.java -text
study/src/org/labkey/study/model/VisitDatasetType.java -text
study/src/org/labkey/study/model/VisitImpl.java -text
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS study.UploadLog;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS study.UploadLog;
12 changes: 0 additions & 12 deletions study/resources/schemas/study.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1564,18 +1564,6 @@
<column columnName="Container"/>
</columns>
</table>
<table tableName="UploadLog" tableDbType="TABLE">
<columns>
<column columnName="RowId"/>
<column columnName="Container"/>
<column columnName="Created"/>
<column columnName="CreatedBy"/>
<column columnName="Description"/>
<column columnName="FilePath"/>
<column columnName="DatasetId"/>
<column columnName="Status"/>
</columns>
</table>
<table tableName="ParticipantVisit" tableDbType="TABLE">
<description>Contains one row per subject/visit combination in the study. Note that this table is populated dynamically as specimen, assay, and dataset data are loaded, and is guaranteed to always be complete.</description>
<columns>
Expand Down
6 changes: 1 addition & 5 deletions study/src/org/labkey/study/StudyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
import org.labkey.api.exp.PropertyType;
import org.labkey.api.exp.api.ExperimentService;
import org.labkey.api.exp.property.PropertyService;
import org.labkey.api.files.FileContentService;
import org.labkey.api.files.TableUpdaterFileListener;
import org.labkey.api.message.digest.ReportAndDatasetChangeDigestProvider;
import org.labkey.api.migration.DatabaseMigrationService;
import org.labkey.api.migration.DefaultMigrationSchemaHandler;
Expand Down Expand Up @@ -228,7 +226,7 @@ public String getName()
@Override
public Double getSchemaVersion()
{
return 25.003;
return 25.004;
}

@Override
Expand Down Expand Up @@ -391,8 +389,6 @@ protected void startupAfterSpringConfig(ModuleContext moduleContext)
folderRegistry.addFactories(new StudyWriterFactory(), new StudyImporterFactory());
}

FileContentService.get().addFileListener(new TableUpdaterFileListener(StudySchema.getInstance().getTableInfoUploadLog(), "FilePath", TableUpdaterFileListener.Type.filePath, "RowId"));

DatasetDefinition.cleanupOrphanedDatasetDomains();

OptionalFeatureService.get().addExperimentalFeatureFlag(StudyQuerySchema.EXPERIMENTAL_STUDY_SUBSCHEMAS, "Use sub-schemas in Study",
Expand Down
5 changes: 0 additions & 5 deletions study/src/org/labkey/study/StudySchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,6 @@ public TableInfo getTableInfoParticipantVisit()
return getSchema().getTable("ParticipantVisit");
}

public TableInfo getTableInfoUploadLog()
{
return getSchema().getTable("UploadLog");
}

public TableInfo getTableInfoCohort()
{
return getSchema().getTable("Cohort");
Expand Down
111 changes: 3 additions & 108 deletions study/src/org/labkey/study/assay/StudyPublishManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.api.assay.AbstractAssayProvider;
import org.labkey.api.assay.AssayFileWriter;
import org.labkey.api.assay.AssayProtocolSchema;
import org.labkey.api.assay.AssayProvider;
import org.labkey.api.assay.AssayService;
Expand Down Expand Up @@ -113,9 +111,7 @@
import org.labkey.api.study.publish.StudyDatasetLinkedColumn;
import org.labkey.api.study.publish.StudyPublishService;
import org.labkey.api.study.query.PublishResultsQueryView;
import org.labkey.api.util.DateUtil;
import org.labkey.api.util.FileStream;
import org.labkey.api.util.FileUtil;
import org.labkey.api.util.PageFlowUtil;
import org.labkey.api.util.Pair;
import org.labkey.api.util.StringExpressionFactory;
Expand All @@ -134,16 +130,12 @@
import org.labkey.study.model.DatasetDomainKind;
import org.labkey.study.model.StudyImpl;
import org.labkey.study.model.StudyManager;
import org.labkey.study.model.UploadLog;
import org.labkey.study.query.StudyQuerySchema;
import org.springframework.beans.MutablePropertyValues;

import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -179,12 +171,6 @@ public synchronized static StudyPublishManager getInstance()
return (StudyPublishManager) StudyPublishService.get();
}


private TableInfo getTinfoUpdateLog()
{
return StudySchema.getInstance().getTableInfoUploadLog();
}

/**
* Studies that the user has permission to.
*/
Expand Down Expand Up @@ -932,71 +918,16 @@ private static String createUniqueDatasetName(Study study, String assayName)
return name;
}

public UploadLog saveUploadData(User user, Dataset dsd, FileStream tsv, String filename) throws IOException
{
PipeRoot pipelineRoot = PipelineService.get().findPipelineRoot(dsd.getContainer());
if (null == pipelineRoot || !pipelineRoot.isValid())
throw new IOException("Please have your administrator set up a pipeline root for this folder.");

Path dir = pipelineRoot.resolveToNioPath(AssayFileWriter.DIR_NAME);
if (null == dir)
throw new IOException("Cannot create directory uploaded data: " + AssayFileWriter.DIR_NAME);

if (!Files.exists(dir))
{
FileUtil.createDirectory(dir);
}

//File name is studyname_datasetname_date_hhmm.ss
Date dateCreated = new Date();
String dateString = DateUtil.formatDateTime(dateCreated, "yyy-MM-dd-HHmm");
int id = 0;
Path file;
do
{
String extension = Objects.toString(filename == null ? "tsv" : FileUtil.getExtension(filename), "tsv");
String extra = id++ == 0 ? "" : String.valueOf(id);
String fileName = dsd.getStudy().getLabel() + "-" + dsd.getLabel() + "-" + dateString + extra + "." + extension;
fileName = fileName.replace('\\', '_').replace('/', '_').replace(':', '_');
file = FileUtil.appendName(dir, fileName);
}
while (Files.exists(file));

try (OutputStream out = Files.newOutputStream(file))
{
IOUtils.copy(tsv.openInputStream(), out);
tsv.closeInputStream();
}

UploadLog ul = new UploadLog();
ul.setContainer(dsd.getContainer());
ul.setDatasetId(dsd.getDatasetId());
ul.setCreated(dateCreated);
ul.setUserId(user.getUserId());
ul.setStatus("Initializing");
String filePath = FileUtil.hasCloudScheme(file) ? FileUtil.pathToString(file) : file.toFile().getPath();
ul.setFilePath(filePath);

return Table.insert(user, getTinfoUpdateLog(), ul);
}


/**
* Return an array of LSIDs from the newly created dataset entries,
* along with the upload log.
* Return an array of LSIDs from the newly created dataset entries.
*/
public Pair<List<String>, UploadLog> importDatasetTSV(User user, StudyImpl study, DatasetDefinition dsd, DataLoader dl, LookupResolutionType lookupResolutionType, FileStream fileIn, String originalFileName, Map<String, String> columnMap, BatchValidationException errors, QueryUpdateService.InsertOption insertOption, @Nullable AuditBehaviorType auditBehaviorType)
public List<String> importDatasetTSV(User user, StudyImpl study, DatasetDefinition dsd, DataLoader dl, LookupResolutionType lookupResolutionType, FileStream fileIn, String originalFileName, Map<String, String> columnMap, BatchValidationException errors, QueryUpdateService.InsertOption insertOption, @Nullable AuditBehaviorType auditBehaviorType)
{
DbScope scope = StudySchema.getInstance().getScope();

UploadLog ul = null;
List<String> lsids = Collections.emptyList();

try
{
if (null != fileIn)
ul = saveUploadData(user, dsd, fileIn, originalFileName);

try (DbScope.Transaction transaction = scope.ensureTransaction())
{
Long defaultQCStateId = study.getDefaultDirectEntryQCState();
Expand All @@ -1020,45 +951,9 @@ public Pair<List<String>, UploadLog> importDatasetTSV(User user, StudyImpl study
catch (IOException x)
{
errors.addRowError(new ValidationException("Exception: " + x.getMessage()));
if (ul != null)
{
ul.setStatus("ERROR");
String description = ul.getDescription();
ul.setDescription(description == null ? "" : description + "\n" + new Date() + ":" + x.getMessage());
ul = Table.update(user, StudySchema.getInstance().getTableInfoUploadLog(), ul, ul.getRowId());
return Pair.of(lsids, ul);
}
}

if (!errors.hasErrors())
{
//Update the status
assert ul != null : "Upload log should always exist if no errors have occurred.";
ul.setStatus("SUCCESS");
ul = Table.update(user, getTinfoUpdateLog(), ul, ul.getRowId());
}
else if (ul != null)
{
ul.setStatus("ERROR");
StringBuilder sb = new StringBuilder();
String sep = "";
for (ValidationException e : errors.getRowErrors())
{
sb.append(sep).append(e.getMessage());
sep = "\n";
}
ul.setDescription(sb.toString());
ul = Table.update(user, getTinfoUpdateLog(), ul, ul.getRowId());
}
return Pair.of(lsids, ul);
}

public UploadLog getUploadLog(Container c, int id)
{
SimpleFilter filter = SimpleFilter.createContainerFilter(c);
filter.addCondition(FieldKey.fromParts("rowId"), id);

return new TableSelector(getTinfoUpdateLog(), filter, null).getObject(UploadLog.class);
return lsids;
}

@Override
Expand Down
74 changes: 5 additions & 69 deletions study/src/org/labkey/study/controllers/StudyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@
import org.labkey.api.data.RuntimeSQLException;
import org.labkey.api.data.SQLFragment;
import org.labkey.api.data.ShowRows;
import org.labkey.api.data.SimpleDisplayColumn;
import org.labkey.api.data.SimpleFilter;
import org.labkey.api.data.Sort;
import org.labkey.api.data.SqlExecutor;
Expand Down Expand Up @@ -210,7 +209,6 @@
import org.labkey.api.util.XmlBeansUtil;
import org.labkey.api.view.ActionURL;
import org.labkey.api.view.DataView;
import org.labkey.api.view.GridView;
import org.labkey.api.view.HtmlView;
import org.labkey.api.view.HttpView;
import org.labkey.api.view.JspView;
Expand All @@ -227,7 +225,6 @@
import org.labkey.api.view.template.EmptyView;
import org.labkey.api.view.template.PageConfig;
import org.labkey.api.writer.FileSystemFile;
import org.labkey.api.writer.HtmlWriter;
import org.labkey.api.writer.VirtualFile;
import org.labkey.data.xml.TablesDocument;
import org.labkey.study.CohortFilterFactory;
Expand Down Expand Up @@ -265,7 +262,6 @@
import org.labkey.study.model.StudyImpl;
import org.labkey.study.model.StudyManager;
import org.labkey.study.model.StudySnapshot;
import org.labkey.study.model.UploadLog;
import org.labkey.study.model.VisitDataset;
import org.labkey.study.model.VisitDatasetType;
import org.labkey.study.model.VisitImpl;
Expand Down Expand Up @@ -2712,19 +2708,19 @@ protected int importData(DataLoader dl, FileStream file, String originalName, Ba
columnMap.put(_form.getSequenceNum(), column);
}

Pair<List<String>, UploadLog> result = StudyPublishManager.getInstance().importDatasetTSV(getUser(), _study, _def, dl, getLookupResolutionType(), file, originalName, columnMap, errors, _form.getInsertOption(), auditBehaviorType);
List<String> lsids = StudyPublishManager.getInstance().importDatasetTSV(getUser(), _study, _def, dl, getLookupResolutionType(), file, originalName, columnMap, errors, _form.getInsertOption(), auditBehaviorType);

if (!result.getKey().isEmpty())
if (!lsids.isEmpty())
{
// Log the import when SUMMARY is configured, if DETAILED is configured the DetailedAuditLogDataIterator will handle each row change.
// It would be nice in the future to replace the DetailedAuditLogDataIterator with a general purpose AuditLogDataIterator
// that can delegate the audit behavior type to the AuditDataHandler, so this code can go away
//
String comment = "Dataset data imported. " + result.getKey().size() + " rows imported";
new DatasetDefinition.DatasetAuditHandler(_def).addAuditEvent(getUser(), getContainer(), AuditBehaviorType.SUMMARY, comment, result.getValue());
String comment = "Dataset data imported. " + lsids.size() + " rows imported";
new DatasetDefinition.DatasetAuditHandler(_def).addAuditEvent(getUser(), getContainer(), AuditBehaviorType.SUMMARY, comment);
}

return result.getKey().size();
return lsids.size();
}

@Override
Expand Down Expand Up @@ -2843,66 +2839,6 @@ public void setManifest(String manifest)
}
}

@RequiresPermission(UpdatePermission.class)
public class ShowUploadHistoryAction extends SimpleViewAction<IdForm>
{
String _datasetLabel;

@Override
public ModelAndView getView(IdForm form, BindException errors)
{
TableInfo tInfo = StudySchema.getInstance().getTableInfoUploadLog();
DataRegion dr = new DataRegion();
dr.addColumns(tInfo, "RowId,Created,CreatedBy,Status,Description");
GridView gv = new GridView(dr, errors);
DisplayColumn dc = new SimpleDisplayColumn(null) {
@Override
public void renderGridCellContents(RenderContext ctx, HtmlWriter out)
{
ActionURL url = new ActionURL(DownloadTsvAction.class, ctx.getContainer()).addParameter("id", String.valueOf(ctx.get("RowId")));
out.write(LinkBuilder.labkeyLink("Download Data File", url));
}
};
dr.addDisplayColumn(dc);

SimpleFilter filter = SimpleFilter.createContainerFilter(getContainer());
if (form.getId() != 0)
{
filter.addCondition(Dataset.DATASET_KEY, form.getId());
DatasetDefinition dsd = StudyManager.getInstance().getDatasetDefinition(getStudyRedirectIfNull(), form.getId());
if (dsd != null)
_datasetLabel = dsd.getLabel();
}

gv.setFilter(filter);
return gv;
}

@Override
public void addNavTrail(NavTree root)
{
root.addChild("Upload History" + (null != _datasetLabel ? " for " + _datasetLabel : ""));
}
}

@RequiresPermission(UpdatePermission.class)
public static class DownloadTsvAction extends SimpleViewAction<IdForm>
{
@Override
public ModelAndView getView(IdForm form, BindException errors) throws Exception
{
UploadLog ul = StudyPublishManager.getInstance().getUploadLog(getContainer(), form.getId());
PageFlowUtil.streamFile(getViewContext().getResponse(), new File(ul.getFilePath()).toPath(), true);

return null;
}

@Override
public void addNavTrail(NavTree root)
{
}
}

@RequiresPermission(ReadPermission.class)
public static class DatasetItemDetailsAction extends SimpleViewAction<SourceLsidForm>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ public synchronized ActionURL updateSnapshot(QuerySnapshotForm form, BindExcepti

ViewContext context = form.getViewContext();
new DatasetDefinition.DatasetAuditHandler(dsDef).addAuditEvent(context.getUser(), context.getContainer(), AuditBehaviorType.DETAILED,
"Dataset snapshot was updated. " + numRowsDeleted + " rows were removed and replaced with " + newRows.size() + " rows.", null);
"Dataset snapshot was updated. " + numRowsDeleted + " rows were removed and replaced with " + newRows.size() + " rows.");

def.setLastUpdated(new Date());
def.save(form.getViewContext().getUser());
Expand All @@ -504,7 +504,7 @@ public synchronized ActionURL updateSnapshot(QuerySnapshotForm form, BindExcepti
{
ViewContext context = form.getViewContext();
new DatasetDefinition.DatasetAuditHandler(dsDef).addAuditEvent(context.getUser(), context.getContainer(), AuditBehaviorType.DETAILED,
"Dataset snapshot was not updated. Cause of failure: " + e.getMessage(), null);
"Dataset snapshot was not updated. Cause of failure: " + e.getMessage());
}
}
}
Expand Down Expand Up @@ -791,7 +791,7 @@ public void run()
DatasetDefinition dsDef = StudyManager.getInstance().getDatasetDefinitionByName(study, _def.getName());
if (dsDef != null)
new DatasetDefinition.DatasetAuditHandler(dsDef).addAuditEvent(context.getUser(), context.getContainer(), AuditBehaviorType.DETAILED,
"Dataset snapshot was not updated. Cause of failure: " + errors.getMessage(), null);
"Dataset snapshot was not updated. Cause of failure: " + errors.getMessage());
}
}
}
Expand Down
Loading