import java.util.List;
import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Reference;
import org.apache.karaf.shell.api.action.lifecycle.Service;
+ "if transaction-debug-context-enabled is true in mdsaltrace_config.xml")
public class PrintOpenTransactionsCommand implements Action {
+ @Argument(index = 0, name = "minOpenTransactions", required = false, multiValued = false,
+ description = "Minimum open number of transactions (leaks with fewer are suppressed)")
+ Integer minOpenTransactions = 1;
+
@Reference
private List<TracingDOMDataBroker> tracingDOMDataBrokers;
@Override
@SuppressWarnings("checkstyle:RegexpSingleLineJava")
public Object execute() {
+ boolean hasFound = false;
for (TracingDOMDataBroker tracingDOMDataBroker : tracingDOMDataBrokers) {
- tracingDOMDataBroker.printOpenTransactions(System.out);
+ hasFound |= tracingDOMDataBroker.printOpenTransactions(System.out, minOpenTransactions);
+ }
+ if (hasFound) {
+ System.out.println(
+ "Actually did find real leaks with more than " + minOpenTransactions + " open transactions");
+ } else {
+ System.out.println(
+ "Did not find any real leaks with more than " + minOpenTransactions + " open transactions");
}
- return null;
+ return hasFound;
}
}
return child.startsWith(parent.substring(parentOffset), childOffset);
}
- @SuppressWarnings("checkstyle:hiddenField")
+ @SuppressWarnings({ "checkstyle:hiddenField", "hiding" })
public boolean subtreesOverlap(YangInstanceIdentifier iid, LogicalDatastoreType store) {
if (this.store != null && !this.store.equals(store)) {
return false;
return isParent(iidString, otherIidString) || isParent(otherIidString, iidString);
}
- @SuppressWarnings("checkstyle:hiddenField")
+ @SuppressWarnings({ "checkstyle:hiddenField", "hiding" })
public boolean eventIsOfInterest(YangInstanceIdentifier iid, LogicalDatastoreType store) {
if (this.store != null && !this.store.equals(store)) {
return false;
}
@Override
- public boolean printOpenTransactions(PrintStream ps) {
+ public boolean printOpenTransactions(PrintStream ps, int minOpenTXs) {
if (transactionChainsRegistry.getAllUnique().isEmpty()
&& readOnlyTransactionsRegistry.getAllUnique().isEmpty()
&& writeTransactionsRegistry.getAllUnique().isEmpty()
ps.println("[NB: If no stack traces are shown below, then "
+ "enable transaction-debug-context-enabled in mdsaltrace_config.xml]");
ps.println();
- printRegistryOpenTransactions(readOnlyTransactionsRegistry, ps, " ");
- printRegistryOpenTransactions(writeTransactionsRegistry, ps, " ");
- printRegistryOpenTransactions(readWriteTransactionsRegistry, ps, " ");
+ // Flag to track if we really found any real leaks with more (or equal) to minOpenTXs
+ boolean hasFound = print(readOnlyTransactionsRegistry, ps, " ", minOpenTXs);
+ hasFound |= print(writeTransactionsRegistry, ps, " ", minOpenTXs);
+ hasFound |= print(readWriteTransactionsRegistry, ps, " ", minOpenTXs);
// Now print details for each non-closed TransactionChain
// incl. in turn each ones own read/Write[Only]TransactionsRegistry
ps.println(" " + transactionChainsRegistry.getAnchor() + " : "
+ transactionChainsRegistry.getCreateDescription());
}
- entries.forEach(entry -> {
+ for (CloseTrackedRegistryReportEntry<TracingTransactionChain> entry : entries) {
ps.println(" " + entry.getNumberAddedNotRemoved() + "x TransactionChains opened but not closed here:");
printStackTraceElements(ps, " ", entry.getStackTraceElements());
@SuppressWarnings("resource")
TracingTransactionChain txChain = (TracingTransactionChain) entry
.getExampleCloseTracked().getRealCloseTracked();
- printRegistryOpenTransactions(txChain.getReadOnlyTransactionsRegistry(), ps, " ");
- printRegistryOpenTransactions(txChain.getWriteTransactionsRegistry(), ps, " ");
- printRegistryOpenTransactions(txChain.getReadWriteTransactionsRegistry(), ps, " ");
- });
+ hasFound |= print(txChain.getReadOnlyTransactionsRegistry(), ps, " ", minOpenTXs);
+ hasFound |= print(txChain.getWriteTransactionsRegistry(), ps, " ", minOpenTXs);
+ hasFound |= print(txChain.getReadWriteTransactionsRegistry(), ps, " ", minOpenTXs);
+ }
ps.println();
- return true;
+ return hasFound;
}
- private <T extends CloseTracked<T>> void printRegistryOpenTransactions(
- CloseTrackedRegistry<T> registry, PrintStream ps, String indent) {
+ private <T extends CloseTracked<T>> boolean print(
+ CloseTrackedRegistry<T> registry, PrintStream ps, String indent, int minOpenTransactions) {
Set<CloseTrackedRegistryReportEntry<T>> unsorted = registry.getAllUnique();
+ if (unsorted.size() < minOpenTransactions) {
+ return false;
+ }
List<CloseTrackedRegistryReportEntry<T>> entries = new ArrayList<>(unsorted);
entries.sort((o1, o2) -> Long.compare(o2.getNumberAddedNotRemoved(), o1.getNumberAddedNotRemoved()));
if (!entries.isEmpty()) {
ps.println();
}
+ return true;
}
private void printStackTraceElements(PrintStream ps, String indent, List<StackTraceElement> stackTraceElements) {