diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index 74c8a45114..16f7a5b5db 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -15,14 +15,12 @@ import org.labkey.remoteapi.query.Sort; import org.labkey.test.Locator; import org.labkey.test.WebDriverWrapper; -import org.labkey.test.WebTestHelper; import org.labkey.test.pages.core.admin.ShowAdminPage; import org.labkey.test.pages.core.admin.ShowAuditLogPage; import java.io.IOException; import java.net.URL; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -92,6 +90,8 @@ public enum AuditEvent ASSAY_AUDIT_EVENT("AssayAuditEvent"), // available with SampleManagement module ASSAY_RESULT_AUDIT_EVENT("AssayResultAuditEvent"), // available with SampleManagement module ATTACHMENT_AUDIT_EVENT("AttachmentAuditEvent"), + DOMAIN_AUDIT_EVENT("DomainAuditEvent"), + DOMAIN_PROPERTY_AUDIT_EVENT("DomainPropertyAuditEvent"), EXPERIMENT_AUDIT_EVENT("ExperimentAuditEvent"), FILE_SYSTEM_EVENT("FileSystem"), GRID_VIEW_AUDIT_EVENT("GridViewAuditEvent"), @@ -101,6 +101,7 @@ public enum AuditEvent PLATE_DATA_AUDIT_EVENT("PlateDataAuditEvent"), // available in Biologics module PLATE_SET_AUDIT_EVENT("PlateSetEvent"), // available in Biologics module QUERY_UPDATE_AUDIT_EVENT("QueryUpdateAuditEvent"), + REGISTRY_AUDIT_EVENT("RegistryEvent"), // available in Biologics module SAMPLE_SET_AUDIT_EVENT("SampleSetAuditEvent"), SAMPLE_TIMELINE_EVENT("SampleTimelineEvent"), SAMPLE_WORKFLOW_AUDIT_EVENT("SamplesWorkflowAuditEvent"), @@ -137,7 +138,7 @@ public enum TransactionDetail FileWatcher; } - public Integer getLatestAuditRowId(String auditTable) throws IOException, CommandException + public Integer getLatestAuditRowId(String auditTable) { String rowId = "rowId"; @@ -147,13 +148,12 @@ public Integer getLatestAuditRowId(String auditTable) throws IOException, Comman selectRows.setMaxRows(1); selectRows.setContainerFilter(ContainerFilter.AllFolders); - SelectRowsResponse response = selectRows.execute(_connectionSupplier.get(), null); - List> rows = response.getRows(); + List> rows = executeSelectCommand(selectRows); if (rows.isEmpty()) { return 0; } - return (Integer) rows.get(0).get(rowId); + return (Integer) rows.getFirst().get(rowId); } public DataRegionTable beginAtAuditEventView(String auditTable, Integer rowIdCutoff) @@ -179,25 +179,25 @@ public DataRegionTable goToAuditEventView(String eventType) * Get the audit logs from the LabKey server filtered to the given project. * * @param containerPath Path of the LK container to use for the select command. - * @param auditEventName Name of the audit event to filter on. Example 'SamplesWorkflowAuditEvent'. + * @param auditEvent Name of the audit event to filter on. Example 'SamplesWorkflowAuditEvent'. * @param columnNames The name of the columns to return. * @param filters The filters to be applied * @param maxRows The maximum number of rows to return. If null, all rows for the provided filters will be returned. - * @param containerFilter The container filter to be applied. If null, default is ContainerFilter.Current. + * @param containerFilter The container filter to be applied. If null, the default is ContainerFilter.Current. * @return A rowResponse with the query logs. * @throws IOException Can be thrown by the SelectRowsCommand. * @throws CommandException Can be thrown by the SelectRowsCommand. */ - public SelectRowsResponse getAuditLogsFromLKS(String containerPath, AuditEvent auditEventName, List columnNames, + public SelectRowsResponse getAuditLogsFromLKS(String containerPath, AuditEvent auditEvent, List columnNames, @Nullable List filters, @Nullable Integer maxRows, @Nullable ContainerFilter containerFilter) throws IOException, CommandException { - return getAuditLogsFromLKS(containerPath, _wrapper.getCurrentProject(), auditEventName, columnNames, filters, maxRows, containerFilter); + return getAuditLogsFromLKS(containerPath, _wrapper.getCurrentProject(), auditEvent, columnNames, filters, maxRows, containerFilter); } - public SelectRowsResponse getAuditLogsFromLKS(String containerPath, @NotNull String projectName, AuditEvent auditEventName, List columnNames, + public SelectRowsResponse getAuditLogsFromLKS(String containerPath, @NotNull String projectName, AuditEvent auditEvent, List columnNames, @Nullable List filters, @Nullable Integer maxRows, @Nullable ContainerFilter containerFilter) throws IOException, CommandException { - SelectRowsCommand cmd = new SelectRowsCommand("auditLog", auditEventName.getName()); + SelectRowsCommand cmd = new SelectRowsCommand("auditLog", auditEvent.getName()); cmd.setColumns(columnNames); cmd.addFilter("ProjectId/Name", projectName, Filter.Operator.EQUAL); if (filters != null) @@ -220,7 +220,7 @@ public List> getAuditLogsForTransactionId(String containerPa { List transactionFilter = new ArrayList<>(); if (transactionId != null) - transactionFilter.add(new Filter("TransactionId", transactionId, Filter.Operator.EQUAL)); + transactionFilter.add(new Filter("TransactionId", transactionId)); if (eventFilters != null && !eventFilters.isEmpty()) transactionFilter.addAll(eventFilters); return getAuditLogsFromLKS(containerPath, auditEventName, columnNames, transactionFilter, null, containerFilter).getRows(); @@ -236,7 +236,7 @@ public List> getAuditLogsForTransactionId(String containerPa { List transactionFilter = new ArrayList<>(); if (transactionId != null) - transactionFilter.add(new Filter("TransactionId", transactionId, Filter.Operator.EQUAL)); + transactionFilter.add(new Filter("TransactionId", transactionId)); if (eventFilters != null && !eventFilters.isEmpty()) transactionFilter.addAll(eventFilters); return getAuditLogsFromLKS(containerPath, projectName, auditEventName, columnNames, transactionFilter, null, containerFilter).getRows(); @@ -261,7 +261,7 @@ public void checkAuditEventValuesForTransactionId(String containerPath, AuditEve public void checkAuditEventValuesForTransactionId(String containerPath, AuditEvent auditEventName, Integer transactionId, List> expectedValues) throws IOException, CommandException { - List columnNames = expectedValues.get(0).keySet().stream().map(Object::toString).toList(); + List columnNames = expectedValues.getFirst().keySet().stream().map(Object::toString).toList(); checkAuditEventValuesForTransactionId(containerPath, auditEventName, columnNames, transactionId, expectedValues); } @@ -278,14 +278,13 @@ public void checkAuditEventValuesForTransactionId(String containerPath, AuditEve public Map getTransactionAuditLogDetails(Integer transactionAuditId) { - Connection cn = WebTestHelper.getRemoteApiConnection(); - SelectRowsCommand cmd = new SelectRowsCommand("auditLog", "TransactionAuditEvent"); + SelectRowsCommand cmd = new SelectRowsCommand("auditLog", AuditEvent.TRANSACTION_AUDIT_EVENT.getName()); cmd.setRequiredVersion(9.1); - cmd.setColumns(Arrays.asList("TransactionDetails")); + cmd.setColumns(List.of("TransactionDetails")); cmd.addFilter("RowId", transactionAuditId, Filter.Operator.EQUAL); cmd.setContainerFilter(ContainerFilter.AllFolders); - Map event = executeSelectCommand(cn, cmd).get(0); + Map event = executeSelectCommand(cmd).getFirst(); String detailJSON = getLogColumnValue(event, "TransactionDetails"); log("TransactionAuditEvent Details: " + detailJSON); if (detailJSON == null || detailJSON.isEmpty()) @@ -376,14 +375,13 @@ public void checkAuditEventDiffCount(String containerPath, AuditEvent auditEvent public void checkAuditLogDataChanges(AuditEvent auditEventName, int transactionId, List changes) { - Connection cn = WebTestHelper.getRemoteApiConnection(); SelectRowsCommand cmd = new SelectRowsCommand("auditLog", auditEventName.getName()); cmd.setRequiredVersion(9.1); - cmd.setColumns(Arrays.asList("oldvalues", "newvalues", "datachanges")); + cmd.setColumns(List.of("oldvalues", "newvalues", "datachanges")); cmd.addFilter("transactionauditid", transactionId, Filter.Operator.EQUAL); cmd.setContainerFilter(ContainerFilter.AllFolders); - Map event = executeSelectCommand(cn, cmd).get(0); + Map event = executeSelectCommand(cmd).getFirst(); String datachanges = getLogColumnDisplayValue(event, "datachanges").toLowerCase(); @@ -397,7 +395,7 @@ public Integer getLastTransactionId(String containerPath, AuditEvent auditEventN try { List> events = getAuditLogsFromLKS(containerPath, auditEventName, List.of("TransactionId"), Collections.emptyList(), 1, ContainerFilter.CurrentAndSubfolders).getRows(); - return events.size() == 1 ? (Integer) events.get(0).get("TransactionId") : null; + return events.size() == 1 ? (Integer) events.getFirst().get("TransactionId") : null; } catch (Exception e) { @@ -410,7 +408,7 @@ public Integer getLastTransactionId(String containerPath) try { List> events = getAuditLogsFromLKS(containerPath, AuditEvent.TRANSACTION_AUDIT_EVENT, List.of("RowId"), Collections.emptyList(), 1, ContainerFilter.CurrentAndSubfolders).getRows(); - return events.size() == 1 ? (Integer) events.get(0).get("RowId") : null; + return events.size() == 1 ? (Integer) events.getFirst().get("RowId") : null; } catch (Exception e) { @@ -423,7 +421,7 @@ public Integer getLastEventId(String containerPath, AuditEvent auditEventName) try { List> events = getAuditLogsFromLKS(containerPath, auditEventName, List.of("RowId"), Collections.emptyList(), 1, ContainerFilter.CurrentAndSubfolders).getRows(); - return events.size() == 1 ? (Integer) events.get(0).get("RowId") : null; + return events.size() == 1 ? (Integer) events.getFirst().get("RowId") : null; } catch (Exception e) { @@ -470,14 +468,14 @@ public Integer checkAuditEventDiffCountForLastTransaction(String containerPath, Integer transactionId = getLastTransactionId(containerPath, auditEventName); List transactionFilter = new ArrayList<>(); if (transactionId != null) - transactionFilter.add(new Filter("TransactionId", transactionId, Filter.Operator.EQUAL)); + transactionFilter.add(new Filter("TransactionId", transactionId)); if (eventFilters != null && !eventFilters.isEmpty()) transactionFilter.addAll(eventFilters); List> events = getAuditLogsFromLKS(containerPath, auditEventName, List.of("Comment", "UserComment", "NewRecordMap"), transactionFilter, null, ContainerFilter.CurrentAndSubfolders).getRows(); if (expectedEventCount != null) { - if (expectedEventCount.intValue() != events.size()) - log("Last audit event info: " + events.get(0)); + if (expectedEventCount != events.size()) + log("Last audit event info: " + events.getFirst()); assertEquals("Unexpected number of events for transactionId " + transactionId, expectedEventCount.intValue(), events.size()); } List expectedChangeCounts = Collections.nCopies(events.size(), expectedDiffCount); @@ -558,7 +556,7 @@ public boolean validateDomainPropertiesAuditLog(String domainName, Integer domai if (expectedAuditDetails.size() != actualAuditDetails.size()) { pass = false; - log(String.format("Number of DomainPropertyAuditEvent events not as expected. Expected %d, Actual %d.", expectedAuditDetails.size(), actualAuditDetails.size())); + log(String.format("Number of %s events not as expected. Expected %d, Actual %d.", AuditEvent.DOMAIN_PROPERTY_AUDIT_EVENT.getName(), expectedAuditDetails.size(), actualAuditDetails.size())); } for (String key : expectedAuditDetails.keySet()) @@ -568,7 +566,7 @@ public boolean validateDomainPropertiesAuditLog(String domainName, Integer domai if (actualAuditDetail == null) { pass = false; - log("Field " + key + " is missing DomainPropertyAuditEvent."); + log(String.format("Field %s is missing %s", key, AuditEvent.DOMAIN_PROPERTY_AUDIT_EVENT.getName())); } else pass = pass && validateDetailAuditLog(expectedAuditDetail, actualAuditDetail); @@ -607,7 +605,7 @@ public List getDomainEventIds(String projectName, String domainName, @N List eventLog = getDomainAuditEventLog(projectName, domainName, null, 1); if (eventLog.isEmpty()) return null; - return eventLog.get(0); + return eventLog.getFirst(); } public @Nullable Integer getLastDomainEventId(String projectName, String domainName) @@ -757,10 +755,9 @@ private List getDomainAuditEventLog(String projectName, S log("Get a list of the Domain Events for project '" + projectName + "'. "); domainName = domainName.trim(); - Connection cn = WebTestHelper.getRemoteApiConnection(); - SelectRowsCommand cmd = new SelectRowsCommand("auditLog", "DomainAuditEvent"); + SelectRowsCommand cmd = new SelectRowsCommand("auditLog", AuditEvent.DOMAIN_AUDIT_EVENT.getName()); cmd.setRequiredVersion(9.1); - cmd.setColumns(Arrays.asList("rowid", "domainuri", "domainname", "comment", "usercomment", "oldvalues", "newvalues", "datachanges")); + cmd.setColumns(List.of("rowid", "domainuri", "domainname", "comment", "usercomment", "oldvalues", "newvalues", "datachanges")); cmd.addFilter("projectid/DisplayName", projectName, Filter.Operator.EQUAL); cmd.addFilter("domainname", domainName, Filter.Operator.EQUAL); if (null != ignoreIds) @@ -774,7 +771,7 @@ private List getDomainAuditEventLog(String projectName, S if (maxRows != null) cmd.setMaxRows(maxRows); - List> domainAuditEventAllRows = executeSelectCommand(cn, cmd); + List> domainAuditEventAllRows = executeSelectCommand(cmd); log(String.format("Number of Domain Event log entries for domain '%s' in '%s': %d", domainName, projectName, domainAuditEventAllRows.size())); List domainAuditEventRows = new ArrayList<>(); @@ -796,10 +793,10 @@ private List getDomainAuditEventLog(String projectName, S private List> getDomainPropertyEventLog(String domainName, @Nullable List eventIds) { - Connection cn = WebTestHelper.getRemoteApiConnection(); - SelectRowsCommand cmd = new SelectRowsCommand("auditLog", "DomainPropertyAuditEvent"); + SelectRowsCommand cmd = new SelectRowsCommand("auditLog", AuditEvent.DOMAIN_PROPERTY_AUDIT_EVENT.getName()); cmd.setRequiredVersion(9.1); - cmd.setColumns(Arrays.asList("Created", "CreatedBy", "ImpersonatedBy", "propertyname", "action", "domainname", "domaineventid", "Comment", "UserComment", "oldvalues", "newvalues", "datachanges")); + cmd.setColumns(List.of("Created", "CreatedBy", "ImpersonatedBy", "propertyname", "action", "domainname", "domaineventid", "Comment", "UserComment", "oldvalues", "newvalues", "datachanges")); + cmd.setContainerFilter(ContainerFilter.AllFolders); cmd.addFilter("domainname", domainName, Filter.Operator.EQUAL); if (null != eventIds) @@ -808,19 +805,16 @@ private List> getDomainPropertyEventLog(String domainName, @ cmd.addFilter("domaineventid/rowid", rowIds, Filter.Operator.IN); } - cmd.setContainerFilter(ContainerFilter.AllFolders); - - return executeSelectCommand(cn, cmd); + return executeSelectCommand(cmd); } - private List> executeSelectCommand(Connection cn, SelectRowsCommand cmd) + private List> executeSelectCommand(SelectRowsCommand cmd) { - List> rowsReturned = new ArrayList<>(); try { - SelectRowsResponse response = cmd.execute(cn, "/"); + SelectRowsResponse response = cmd.execute(_connectionSupplier.get(), "/"); log("Number of rows: " + response.getRowCount()); - rowsReturned.addAll(response.getRows()); + return response.getRows(); } catch (IOException | CommandException ex) { @@ -828,43 +822,7 @@ private List> executeSelectCommand(Connection cn, SelectRows fail("There was a command exception when getting the log: " + ex); } - return rowsReturned; - } - - private Map getDomainPropertyEventComment(Map row) - { - String comment = getLogColumnValue(row, "Comment"); - if (comment != null) - return null; - - String[] commentAsArray = comment.split(";"); - - Map fieldComments = new HashMap<>(); - - for (String s : commentAsArray) - { - String[] fieldValue = s.split(":"); - - // If the split on the ':' produced more than two entries in the array it most likely means that the - // comment for that property had a : in it. So treat the first entry as the field name and then concat the - // other fields together. - // For example the ConditionalFormats field will log the following during an update: - // ConditionalFormats: old: , new: 1; - // And a create of a Lookup will log as: - // Lookup: [Schema: lists, Query: LookUp01]; - StringBuilder sb = new StringBuilder(); - sb.append(fieldValue[1].trim()); - - for (int j = 2; j < fieldValue.length; j++) - { - sb.append(":"); - sb.append(fieldValue[j]); - } - - fieldComments.put(fieldValue[0].trim(), sb.toString()); - } - - return fieldComments; + return Collections.emptyList(); } private String getLogColumnValue(Map rowEntry, String columnName, String valueType)