Bump odlparent to 6.0.0
[controller.git] / opendaylight / md-sal / mdsal-trace / dom-impl / src / main / java / org / opendaylight / controller / md / sal / trace / dom / impl / TracingBroker.java
index 8160b4689ea7c801e49d13e178de62632eb36e86..ab633a22b77c60943528b2f8e7cdeff43c17bdce 100644 (file)
@@ -7,14 +7,15 @@
  */
 package org.opendaylight.controller.md.sal.trace.dom.impl;
 
+import static java.util.Objects.requireNonNull;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
-import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataTreeChangeListener;
@@ -98,12 +99,14 @@ import org.slf4j.LoggerFactory;
  * </ul>
  *
  */
+@Deprecated
 public class TracingBroker implements TracingDOMDataBroker {
-
+    @SuppressFBWarnings("SLF4J_LOGGER_SHOULD_BE_PRIVATE")
     static final Logger LOG = LoggerFactory.getLogger(TracingBroker.class);
 
     private static final int STACK_TRACE_FIRST_RELEVANT_FRAME = 2;
 
+    private final String type; // "default" VS "pingpong"
     private final BindingNormalizedNodeSerializer codec;
     private final DOMDataBroker delegate;
     private final List<Watch> registrationWatches = new ArrayList<>();
@@ -145,7 +148,7 @@ public class TracingBroker implements TracingDOMDataBroker {
             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;
@@ -155,7 +158,7 @@ public class TracingBroker implements TracingDOMDataBroker {
             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;
@@ -165,9 +168,10 @@ public class TracingBroker implements TracingDOMDataBroker {
         }
     }
 
-    public TracingBroker(DOMDataBroker delegate, Config config, BindingNormalizedNodeSerializer codec) {
-        this.delegate = Objects.requireNonNull(delegate);
-        this.codec = Objects.requireNonNull(codec);
+    public TracingBroker(String type, DOMDataBroker delegate, Config config, BindingNormalizedNodeSerializer codec) {
+        this.type = requireNonNull(type, "type");
+        this.delegate = requireNonNull(delegate, "delegate");
+        this.codec = requireNonNull(codec, "codec");
         configure(config);
 
         if (config.isTransactionDebugContextEnabled() != null) {
@@ -221,6 +225,8 @@ public class TracingBroker implements TracingDOMDataBroker {
         writeWatches.add(watch);
     }
 
+    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
+            justification = "https://github.com/spotbugs/spotbugs/issues/811")
     private boolean isRegistrationWatched(YangInstanceIdentifier iid, LogicalDatastoreType store) {
         if (registrationWatches.isEmpty()) {
             return true;
@@ -271,7 +277,7 @@ public class TracingBroker implements TracingDOMDataBroker {
         }
     }
 
-    private void reconstructIidPathString(YangInstanceIdentifier yiid, StringBuilder sb) {
+    private static void reconstructIidPathString(YangInstanceIdentifier yiid, StringBuilder sb) {
         sb.append("<RECONSTRUCTED FROM: \"").append(yiid.toString()).append("\">");
         for (YangInstanceIdentifier.PathArgument pathArg : yiid.getPathArguments()) {
             if (pathArg instanceof YangInstanceIdentifier.AugmentationIdentifier) {
@@ -315,7 +321,6 @@ public class TracingBroker implements TracingDOMDataBroker {
         return new TracingReadOnlyTransaction(delegate.newReadOnlyTransaction(), readOnlyTransactionsRegistry);
     }
 
-    @Nonnull
     @Override
     public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
         Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> res = delegate.getSupportedExtensions();
@@ -327,10 +332,9 @@ public class TracingBroker implements TracingDOMDataBroker {
         res = new HashMap<>(res);
 
         res.put(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() {
-            @Nonnull
             @Override
             public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerDataTreeChangeListener(
-                    @Nonnull DOMDataTreeIdentifier domDataTreeIdentifier, @Nonnull L listener) {
+                    DOMDataTreeIdentifier domDataTreeIdentifier, L listener) {
                 if (isRegistrationWatched(domDataTreeIdentifier.getRootIdentifier(),
                         domDataTreeIdentifier.getDatastoreType())) {
                     LOG.warn("{} registration (registerDataTreeChangeListener) for {} from {}.",
@@ -345,22 +349,25 @@ public class TracingBroker implements TracingDOMDataBroker {
     }
 
     @Override
-    public boolean printOpenTransactions(PrintStream ps) {
+    public boolean printOpenTransactions(PrintStream ps, int minOpenTXs) {
         if (transactionChainsRegistry.getAllUnique().isEmpty()
             && readOnlyTransactionsRegistry.getAllUnique().isEmpty()
             && writeTransactionsRegistry.getAllUnique().isEmpty()
             && readWriteTransactionsRegistry.getAllUnique().isEmpty()) {
 
+            ps.println(type + ": No open transactions, great!");
             return false;
         }
 
-        ps.println(getClass().getSimpleName() + " found some not yet (or never..) closed transaction[chain]s!");
+        ps.println(type + ": " + getClass().getSimpleName()
+                 + " found some not yet (or never..) closed transaction[chain]s!");
         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
@@ -370,24 +377,27 @@ public class TracingBroker implements TracingDOMDataBroker {
             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()));
@@ -403,6 +413,7 @@ public class TracingBroker implements TracingDOMDataBroker {
         if (!entries.isEmpty()) {
             ps.println();
         }
+        return true;
     }
 
     private void printStackTraceElements(PrintStream ps, String indent, List<StackTraceElement> stackTraceElements) {