Skip to content

Commit

Permalink
Adds pending changesets to update report (DAT-16332) (#5402)
Browse files Browse the repository at this point in the history
* [DAT-16332] Adds pending changesets to update report. Count failed changes.

* [DAT-16332] Remove unused object.

* [DAT-16332] Handle potential NPEs and when there are no actual pending changes.

* [DAT-16332] Fix pending changes on failure.
  • Loading branch information
abrackx committed Dec 29, 2023
1 parent 74d621a commit 44b6397
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ public void run(CommandResultsBuilder resultsBuilder) throws Exception {
StatusVisitor statusVisitor = getStatusVisitor(commandScope, database, contexts, labelExpression, databaseChangeLog);

AtomicInteger rowsAffected = new AtomicInteger(0);
UpdateSummaryDetails summaryDetails = new UpdateSummaryDetails();

HashMap<String, Object> scopeValues = new HashMap<>();
scopeValues.put("showSummary", getShowSummary(commandScope));
scopeValues.put("rowsAffected", rowsAffected);
Expand All @@ -112,15 +110,14 @@ public void run(CommandResultsBuilder resultsBuilder) throws Exception {
} finally {
UpdateSummaryDetails details = ShowSummaryUtil.buildSummaryDetails(databaseChangeLog, getShowSummary(commandScope), getShowSummaryOutput(commandScope), statusVisitor, resultsBuilder.getOutputStream(), runChangeLogIterator);
if (details != null) {
summaryDetails.setSummary(details.getSummary());
summaryDetails.setOutput(details.getOutput());
updateReportParameters.getOperationInfo().setUpdateSummaryMsg(details.getOutput());
updateReportParameters.getChangesetInfo().addAllToPendingChangesetInfoList(details.getSkipped());
updateReportParameters.getChangesetInfo().setPendingChangesetCount(updateReportParameters.getChangesetInfo().getPendingChangesetInfoList().size());
}
}
});
updateReportParameters.getOperationInfo().setUpdateSummaryMsg(summaryDetails.getOutput());
updateReportParameters.getOperationInfo().setRowsAffected(rowsAffected.get());
database.afterUpdate();

resultsBuilder.addResult("statusCode", 0);
addChangelogFileToMdc(getChangelogFileArg(commandScope), databaseChangeLog);
Scope.getCurrentScope().addMdcValue(MdcKey.ROWS_AFFECTED, String.valueOf(rowsAffected.get()));
Expand Down Expand Up @@ -202,8 +199,16 @@ private void logDeploymentOutcomeMdc(ChangeExecListener defaultListener, boolean
int failedChangeSetCount = failedChangeSets.size();
ChangesetsUpdated changesetsUpdated = new ChangesetsUpdated(deployedChangeSets);
updateReportParameters.getChangesetInfo().setChangesetCount(deployedChangeSetCount + failedChangeSetCount);
updateReportParameters.getChangesetInfo().setFailedChangesetCount(failedChangeSetCount);
updateReportParameters.getChangesetInfo().addAllToChangesetInfoList(deployedChangeSets, false);
updateReportParameters.getChangesetInfo().addAllToChangesetInfoList(failedChangeSets, false);
if (!updateReportParameters.getChangesetInfo().getPendingChangesetInfoList().isEmpty()) {
// If there are failures remove these changes from the pending changeset list
// and update the count to reflect only skipped(pending) changes by removing the failed count
updateReportParameters.getChangesetInfo().getPendingChangesetInfoList()
.removeIf(pendingChangesetInfo -> failedChangeSets.stream().anyMatch(changeSet -> changeSet.equals(pendingChangesetInfo.getChangeSet())));
updateReportParameters.getChangesetInfo().setPendingChangesetCount(updateReportParameters.getChangesetInfo().getPendingChangesetCount() - failedChangeSetCount);
}
Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME_COUNT, String.valueOf(deployedChangeSetCount));
Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESETS_UPDATED, changesetsUpdated);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,22 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Data
public class ChangesetInfo {
/**
* The number of deployed (aka executed) changesets
*/
private int changesetCount;
/**
* The number of pending (aka skipped) changesets
*/
private int pendingChangesetCount;
private int failedChangesetCount;
private final List<IndividualChangesetInfo> changesetInfoList = new ArrayList<>();
private final List<PendingChangesetInfo> pendingChangesetInfoList = new ArrayList<>();

public void addAllToChangesetInfoList(List<ChangeSet> changeSets, boolean isRollback) {
if (changeSets != null) {
Expand Down Expand Up @@ -81,4 +91,26 @@ private static List<String> buildAttributesString(ChangeSet changeSet) {
}
return attributes;
}

/**
* Map all changeset status and reason for skipping to a PendingChangesetInfo object and add to the list.
*
* @param pendingChanges the map of ChangeSetStatus and their reason for being skipped.
*/
public void addAllToPendingChangesetInfoList(Map<ChangeSet, String> pendingChanges) {
if (pendingChanges != null) {
pendingChanges.forEach((changeSet, reason) -> {
PendingChangesetInfo pendingChangesetInfo = new PendingChangesetInfo(
changeSet.getAuthor(),
changeSet.getId(),
changeSet.getFilePath(),
changeSet.getComments(),
changeSet.getLabels() == null ? null : changeSet.getLabels().toString(),
changeSet.getContextFilter() == null ? null : changeSet.getContextFilter().getOriginalString(),
reason,
changeSet);
pendingChangesetInfoList.add(pendingChangesetInfo);
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package liquibase.report;

import liquibase.changelog.ChangeSet;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class PendingChangesetInfo {
private String changesetAuthor;
private String changesetId;
private String changelogFile;
private String comment;
private String labels;
private String contexts;
private String reason;
private ChangeSet changeSet;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import liquibase.logging.mdc.customobjects.UpdateSummary;
import liquibase.report.ShowSummaryGenerator;
import liquibase.report.ShowSummaryGeneratorFactory;
import lombok.Data;

import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -116,11 +117,10 @@ public static UpdateSummaryDetails buildSummaryDetails(DatabaseChangeLog changeL
summaryDetails.getSummary().setValue(showSummary.toString());
boolean shouldPrintDetailTable = showSummary != UpdateSummaryEnum.SUMMARY && (!skippedChangeSets.isEmpty() || !denied.isEmpty() || !additionalChangeSetStatus.isEmpty());

//
// Show the details too
//
SortedMap<String, Integer> skippedMdc = showDetailTable(skippedChangeSets, filterDenied, outputStream, shouldPrintDetailTable, showSummaryOutput, additionalChangeSetStatus, runChangeLogIterator);
summaryDetails.getSummary().setSkipped(skippedMdc);
FilteredChanges filteredChanges = showDetailTable(skippedChangeSets, filterDenied, outputStream, shouldPrintDetailTable, showSummaryOutput, additionalChangeSetStatus, runChangeLogIterator);
summaryDetails.getSummary().setSkipped(filteredChanges.getMdcSkipCounts());
summaryDetails.setSkipped(filteredChanges.getSkippedChangesetsMessage());
try (MdcObject updateSummaryMdcObject = Scope.getCurrentScope().addMdcValue(MdcKey.UPDATE_SUMMARY, summaryDetails.getSummary())) {
Scope.getCurrentScope().getLog(ShowSummaryUtil.class).info("Update summary generated");
}
Expand All @@ -130,7 +130,7 @@ public static UpdateSummaryDetails buildSummaryDetails(DatabaseChangeLog changeL
//
// Show the details
//
private static SortedMap<String, Integer> showDetailTable(List<ChangeSet> skippedChangeSets,
private static FilteredChanges showDetailTable(List<ChangeSet> skippedChangeSets,
List<ChangeSetStatus> filterDenied,
OutputStream outputStream,
boolean shouldPrintDetailTable,
Expand All @@ -143,7 +143,7 @@ private static SortedMap<String, Integer> showDetailTable(List<ChangeSet> skippe
// Nothing to do
//
if (filterDenied.isEmpty() && skippedChangeSets.isEmpty() && additionalChangesets.isEmpty()) {
return new TreeMap<>(Collections.singletonMap(totalSkippedMdcKey, 0));
return new FilteredChanges(new TreeMap<>(Collections.singletonMap(totalSkippedMdcKey, 0)), new LinkedHashMap<>());
}
List<String> columnHeaders = new ArrayList<>();
columnHeaders.add("Changeset Info");
Expand All @@ -169,29 +169,29 @@ public int compare(ChangeSetStatus o1, ChangeSetStatus o2) {
}
});

//
// Filtered because of labels or context
//
Map<ChangeSet, String> filteredChangesets = new LinkedHashMap<>();
List<String> skippedMessages = new ArrayList<>();
for (ChangeSetStatus st : finalList) {
for (ChangeSetStatus changeSetStatus : finalList) {
AtomicBoolean flag = new AtomicBoolean(true);
StringBuilder builder = new StringBuilder();
st.getFilterResults().forEach(consumer -> {
if (consumer.getFilter() != null && !consumer.getFilter().isAssignableFrom(ShouldNotCountAsSkipChangesetFilter.class)) {
String displayName = consumer.getMdcName();
changeSetStatus.getFilterResults().forEach(filterResult -> {
if (filterResult.getFilter() != null && !filterResult.getFilter().isAssignableFrom(ShouldNotCountAsSkipChangesetFilter.class)) {
String displayName = filterResult.getMdcName();
mdcSkipCounts.merge(displayName, 1, Integer::sum);
}
String skippedMessage = String.format(" '%s' : %s", st.getChangeSet().toString(), consumer.getMessage());
String skippedMessage = String.format(" '%s' : %s", changeSetStatus.getChangeSet().toString(), filterResult.getMessage());
skippedMessages.add(skippedMessage);
if (!flag.get()) {
builder.append(System.lineSeparator());
}
builder.append(consumer.getMessage());
builder.append(filterResult.getMessage());
flag.set(false);
});
List<String> outputRow = new ArrayList<>();
outputRow.add(st.getChangeSet().toString());
outputRow.add(changeSetStatus.getChangeSet().toString());
outputRow.add(builder.toString());
filteredChangesets.put(changeSetStatus.getChangeSet(), builder.toString());
table.add(outputRow);
}

Expand All @@ -208,7 +208,7 @@ public int compare(ChangeSetStatus o1, ChangeSetStatus o2) {
skippedMessages.forEach(ShowSummaryUtil::writeToLog);
}
}
return mdcSkipCounts;
return new FilteredChanges(mdcSkipCounts, filteredChangesets);
}


Expand Down Expand Up @@ -380,4 +380,10 @@ private static void writeToLog(String message) {
.filter(s -> !StringUtil.isWhitespace(s))
.forEach(Scope.getCurrentScope().getLog(ShowSummaryUtil.class)::info);
}

@Data
private static class FilteredChanges {
private final SortedMap<String, Integer> mdcSkipCounts;
private final Map<ChangeSet, String> skippedChangesetsMessage;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package liquibase.util;

import liquibase.Beta;
import liquibase.changelog.ChangeSet;
import liquibase.logging.mdc.customobjects.UpdateSummary;
import lombok.Data;
import lombok.ToString;

import java.util.Map;

/**
* Container to handle sharing update summary message between different services
*/
Expand All @@ -14,4 +17,5 @@
public class UpdateSummaryDetails {
private UpdateSummary summary;
private String output;
private Map<ChangeSet, String> skipped;
}

0 comments on commit 44b6397

Please sign in to comment.