Skip to content
Merged
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
29 changes: 29 additions & 0 deletions api/src/org/labkey/api/action/BaseViewAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
import org.jetbrains.annotations.NotNull;
import org.labkey.api.attachments.AttachmentFile;
import org.labkey.api.attachments.SpringAttachmentFile;
import org.labkey.api.audit.TransactionAuditProvider;
import org.labkey.api.data.Container;
import org.labkey.api.data.ConvertHelper;
import org.labkey.api.security.User;
import org.labkey.api.util.HelpTopic;
import org.labkey.api.util.HttpUtil;
import org.labkey.api.util.PageFlowUtil;
import org.labkey.api.util.logging.LogHelper;
import org.labkey.api.view.HttpView;
import org.labkey.api.view.ViewContext;
import org.labkey.api.view.template.PageConfig;
import org.labkey.api.writer.ContainerUser;
import org.springframework.beans.AbstractPropertyAccessor;
Expand Down Expand Up @@ -71,6 +74,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
Expand Down Expand Up @@ -535,6 +539,31 @@ public boolean supports(Class clazz)
return getCommandClass().isAssignableFrom(clazz);
}

public Map<TransactionAuditProvider.TransactionDetail, Object> getTransactionAuditDetails()
{
return getTransactionAuditDetails(getViewContext());
}

public static Map<TransactionAuditProvider.TransactionDetail, Object> getTransactionAuditDetails(ViewContext viewContext)
{
Map<TransactionAuditProvider.TransactionDetail, Object> map = new HashMap<>();
map.put(TransactionAuditProvider.TransactionDetail.Action, viewContext.getActionURL().getController() + "-" + viewContext.getActionURL().getAction());
String clientLibrary = HttpUtil.getClientLibrary(viewContext.getRequest());
if (null != clientLibrary)
map.put(TransactionAuditProvider.TransactionDetail.ClientLibrary, clientLibrary);
else
{
String productName = HttpUtil.getProductNameFromReferer(viewContext.getRequest()); // app
if (null != productName)
map.put(TransactionAuditProvider.TransactionDetail.Product, productName);
else // LKS
{
String refererRelativeURL = HttpUtil.getRefererRelativeURL(viewContext.getRequest());
map.put(TransactionAuditProvider.TransactionDetail.RequestSource, refererRelativeURL);
}
}
return map;
}

/* for TableViewForm, uses BeanUtils to work with DynaBeans */
static public class BeanUtilsPropertyBindingResult extends BeanPropertyBindingResult
Expand Down
5 changes: 3 additions & 2 deletions api/src/org/labkey/api/assay/AssayFilePropertyWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.apache.logging.log4j.Logger;
import org.labkey.api.audit.AuditLogService;
import org.labkey.api.audit.TransactionAuditProvider;
import org.labkey.api.audit.provider.FileSystemAuditProvider;
import org.labkey.api.collections.CaseInsensitiveHashMap;
import org.labkey.api.data.Container;
Expand Down Expand Up @@ -59,7 +60,7 @@ public static void cleanupPostedFiles(Container container, Set<FileLike> files,
}
}

public CaseInsensitiveHashMap<FileLike> savePostedFiles(Container container, User user, Map<String, MultipartFile> filePropertyMap, Long auditTransactionId, String auditComment) throws ExperimentException
public CaseInsensitiveHashMap<FileLike> savePostedFiles(Container container, User user, Map<String, MultipartFile> filePropertyMap, TransactionAuditProvider.TransactionAuditEvent auditTransactionEvent, String auditComment) throws ExperimentException
{
FileLike targetDirectory = AssayFileWriter.ensureUploadDirectory(container);
CaseInsensitiveHashMap<FileLike> properties = new CaseInsensitiveHashMap<>();
Expand Down Expand Up @@ -87,7 +88,7 @@ public CaseInsensitiveHashMap<FileLike> savePostedFiles(Container container, Use
event.setProvidedFileName(originalName);
event.setFile(file.getName());
event.setDirectory(file.getParent());
event.setTransactionId(auditTransactionId);
event.setTransactionEvent(auditTransactionEvent, FileSystemAuditProvider.EVENT_TYPE);
event.setFieldName(entry.getKey());
AuditLogService.get().addEvent(user, event);

Expand Down
14 changes: 10 additions & 4 deletions api/src/org/labkey/api/assay/AssayRunCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
package org.labkey.api.assay;

import org.jetbrains.annotations.Nullable;
import org.labkey.api.audit.TransactionAuditProvider;
import org.labkey.api.exp.ExperimentException;
import org.labkey.api.exp.api.ExpExperiment;
import org.labkey.api.exp.api.ExpRun;
import org.labkey.api.query.ValidationException;
import org.labkey.api.util.Pair;

import java.util.Map;

/**
* An AssayRunCreator does the actual work of constructing an assay run and saving it to the database. It gets
* data about the run to be created from a AssayRunUploadContext and translates it into objects in the Experiment
Expand All @@ -40,14 +43,17 @@ public interface AssayRunCreator<ProviderType extends AssayProvider>
* @param batchId if not null, the run group that's already created for this batch. If null, a new one will be created.
* @return Pair of batch and run that were inserted. ExpBatch will not be null, but ExpRun may be null when inserting the run async.
*/
Pair<ExpExperiment, ExpRun> saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable Long batchId)
throws ExperimentException, ValidationException;
default Pair<ExpExperiment, ExpRun> saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable Long batchId)
throws ExperimentException, ValidationException
{
return saveExperimentRun(context, batchId, false, null);
}

Pair<ExpExperiment, ExpRun> saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable Long batchId, boolean forceAsync)
Pair<ExpExperiment, ExpRun> saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable Long batchId, boolean forceAsync, Map<TransactionAuditProvider.TransactionDetail, Object> transactionDetails)
throws ExperimentException, ValidationException;
/**
* @return the batch to which the run has been assigned
*/
ExpExperiment saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable ExpExperiment batch, ExpRun run, boolean forceSaveBatchProps)
ExpExperiment saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable ExpExperiment batch, ExpRun run, boolean forceSaveBatchProps, @Nullable Map<TransactionAuditProvider.TransactionDetail, Object> transactionDetails)
throws ExperimentException, ValidationException;
}
28 changes: 15 additions & 13 deletions api/src/org/labkey/api/assay/DefaultAssayRunCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,6 @@ public TransformResult transform(AssayRunUploadContext<ProviderType> context, Ex
{
return DataTransformService.get().transformAndValidate(context, run, DataTransformService.TransformOperation.INSERT);
}

@Override
public Pair<ExpExperiment, ExpRun> saveExperimentRun(AssayRunUploadContext<ProviderType> context, @Nullable Long batchId) throws ExperimentException, ValidationException
{
return saveExperimentRun(context, batchId, false);
}

/**
* Create and save an experiment run synchronously or asynchronously in a background job depending upon the assay design.
*
Expand All @@ -141,7 +134,8 @@ public Pair<ExpExperiment, ExpRun> saveExperimentRun(AssayRunUploadContext<Provi
public Pair<ExpExperiment, ExpRun> saveExperimentRun(
AssayRunUploadContext<ProviderType> context,
@Nullable Long batchId,
boolean forceAsync
boolean forceAsync,
Map<TransactionAuditProvider.TransactionDetail, Object> transactionDetails
) throws ExperimentException, ValidationException
{
ExpExperiment exp = null;
Expand All @@ -156,9 +150,10 @@ public Pair<ExpExperiment, ExpRun> saveExperimentRun(

try (DbScope.Transaction transaction = ExperimentService.get().getSchema().getScope().ensureTransaction(ExperimentService.get().getProtocolImportLock()))
{
if (transaction.getAuditId() == null)
TransactionAuditProvider.TransactionAuditEvent auditEvent = transaction.getAuditEvent();
if (auditEvent == null)
{
TransactionAuditProvider.TransactionAuditEvent auditEvent = AbstractQueryUpdateService.createTransactionAuditEvent(context.getContainer(), context.getReRunId() == null ? QueryService.AuditAction.UPDATE : QueryService.AuditAction.INSERT);
auditEvent = AbstractQueryUpdateService.createTransactionAuditEvent(context.getContainer(), context.getReRunId() == null ? QueryService.AuditAction.UPDATE : QueryService.AuditAction.INSERT, transactionDetails);
AbstractQueryUpdateService.addTransactionAuditEvent(transaction, context.getUser(), auditEvent);
}
context.init();
Expand All @@ -172,11 +167,13 @@ public Pair<ExpExperiment, ExpRun> saveExperimentRun(
throw new ClassCastException("FileLike expected: " + errFile + " context: " + context.getClass() + " " + context);
}
FileLike primaryFile = context.getUploadedData().get(AssayDataCollector.PRIMARY_FILE);
if (primaryFile != null)
auditEvent.addDetail(TransactionAuditProvider.TransactionDetail.ImportFileName, primaryFile.getName());
run = AssayService.get().createExperimentRun(context.getName(), context.getContainer(), protocol, null == primaryFile ? null : primaryFile.toNioPathForRead().toFile());
run.setComments(context.getComments());
run.setWorkflowTaskId(context.getWorkflowTask());

exp = saveExperimentRun(context, exp, run, false);
exp = saveExperimentRun(context, exp, run, false, transactionDetails);

// re-fetch the run after it has been fully constructed
run = ExperimentService.get().getExpRun(run.getRowId());
Expand All @@ -187,6 +184,10 @@ public Pair<ExpExperiment, ExpRun> saveExperimentRun(
{
context.uploadComplete(null);
context.setTransactionAuditId(transaction.getAuditId());
FileLike primaryFile = context.getUploadedData().get(AssayDataCollector.PRIMARY_FILE);
if (primaryFile != null)
auditEvent.addDetail(TransactionAuditProvider.TransactionDetail.ImportFileName, primaryFile.getName());
auditEvent.addDetail(TransactionAuditProvider.TransactionDetail.ImportOptions, "BackgroundImport");
exp = saveExperimentRunAsync(context, exp);
}
transaction.commit();
Expand Down Expand Up @@ -267,7 +268,8 @@ public ExpExperiment saveExperimentRun(
final AssayRunUploadContext<ProviderType> context,
@Nullable ExpExperiment batch,
@NotNull ExpRun run,
boolean forceSaveBatchProps
boolean forceSaveBatchProps,
@Nullable Map<TransactionAuditProvider.TransactionDetail, Object> transactionDetails
) throws ExperimentException, ValidationException
{
context.setAutoFillDefaultResultColumns(run.getRowId() > 0); // need to setAutoFillDefaultResultColumns before run is saved
Expand Down Expand Up @@ -327,7 +329,7 @@ public ExpExperiment saveExperimentRun(
}
else
{
var auditEvent = AbstractQueryUpdateService.createTransactionAuditEvent(container, auditAction);
var auditEvent = AbstractQueryUpdateService.createTransactionAuditEvent(container, auditAction, transactionDetails);
AbstractQueryUpdateService.addTransactionAuditEvent(transaction, context.getUser(), auditEvent);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ public class RunStepHandler extends StepHandler<FormType>

public final ExpRun saveExperimentRun(FormType form) throws ExperimentException, ValidationException
{
Pair<ExpExperiment, ExpRun> pair = form.getProvider().getRunCreator().saveExperimentRun(form, form.getBatchId());
Pair<ExpExperiment, ExpRun> pair = form.getProvider().getRunCreator().saveExperimentRun(form, form.getBatchId(), false, getTransactionAuditDetails());
assert pair != null && pair.first != null;
ExpExperiment exp = pair.first;
ExpRun run = pair.second;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.labkey.api.assay.AssayProvider;
import org.labkey.api.assay.AssayService;
import org.labkey.api.assay.AssayUrls;
import org.labkey.api.audit.TransactionAuditProvider;
import org.labkey.api.exp.ExperimentException;
import org.labkey.api.exp.api.ExpExperiment;
import org.labkey.api.exp.api.ExpRun;
Expand Down Expand Up @@ -155,8 +156,13 @@ public void doWork()
_forceSaveBatchProps = true;
}

Map<TransactionAuditProvider.TransactionDetail, Object> transactionDetails = new HashMap<>();
transactionDetails.put(TransactionAuditProvider.TransactionDetail.ImportFileName, _primaryFile.getName());
transactionDetails.put(TransactionAuditProvider.TransactionDetail.ImportOptions, "BackgroundImport");
transactionDetails.put(TransactionAuditProvider.TransactionDetail.Action, "AssayUploadPipelineJob");

// Do all the real work of the import
ExpExperiment result = _context.getProvider().getRunCreator().saveExperimentRun(_context, batch, _run, _forceSaveBatchProps);
ExpExperiment result = _context.getProvider().getRunCreator().saveExperimentRun(_context, batch, _run, _forceSaveBatchProps, transactionDetails);
setStatus(TaskStatus.complete);
getLogger().info("Finished assay upload");

Expand Down
9 changes: 9 additions & 0 deletions api/src/org/labkey/api/audit/AuditTypeEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ public void setTransactionId(Long transactionId)
_transactionId = transactionId;
}

public void setTransactionEvent(@Nullable TransactionAuditProvider.TransactionAuditEvent transactionEvent, String auditEventType)
{
if (transactionEvent == null)
return;

_transactionId = transactionEvent.getRowId();
transactionEvent.addDetail(TransactionAuditProvider.TransactionDetail.AuditEvents, auditEventType);
}

protected String getContainerMessageElement(@NotNull Container container)
{
String value = " (" + container.getId() + ")";
Expand Down
3 changes: 1 addition & 2 deletions api/src/org/labkey/api/audit/ExperimentAuditEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ public class ExperimentAuditEvent extends AuditTypeEvent
public ExperimentAuditEvent()
{
super();
setTransactionId(TransactionAuditProvider.getCurrentTransactionAuditId());
}

public ExperimentAuditEvent(Container container, String comment)
{
super(EVENT_TYPE, container, comment);
setTransactionId(TransactionAuditProvider.getCurrentTransactionAuditId());
setTransactionEvent(TransactionAuditProvider.getCurrentTransactionAuditEvent(), EVENT_TYPE);
}

public String getProtocolLsid()
Expand Down
3 changes: 1 addition & 2 deletions api/src/org/labkey/api/audit/SampleTimelineAuditEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,12 @@ public static SampleTimelineEventType getTypeFromName(@Nullable String name)
public SampleTimelineAuditEvent()
{
super();
setTransactionId(TransactionAuditProvider.getCurrentTransactionAuditId());
}

public SampleTimelineAuditEvent(Container container, String comment)
{
super(EVENT_TYPE, container, comment);
setTransactionId(TransactionAuditProvider.getCurrentTransactionAuditId());
setTransactionEvent(TransactionAuditProvider.getCurrentTransactionAuditEvent(), EVENT_TYPE);
}

public String getSampleLsid()
Expand Down
Loading