X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=trace%2Fmdsal-trace-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Ftrace%2Fimpl%2FTracingBroker.java;h=b7b528b636de630f645554e18e5d6fb1a814a1c0;hb=1487e0720cbb7f7b1f04507a85494c1a96dc82ad;hp=5b02713a050a124007b33a8c8ba1f90fcba58009;hpb=02b6592214e112d1b2d2aacfdc722ce6790370cd;p=mdsal.git diff --git a/trace/mdsal-trace-impl/src/main/java/org/opendaylight/mdsal/trace/impl/TracingBroker.java b/trace/mdsal-trace-impl/src/main/java/org/opendaylight/mdsal/trace/impl/TracingBroker.java index 5b02713a05..b7b528b636 100644 --- a/trace/mdsal-trace-impl/src/main/java/org/opendaylight/mdsal/trace/impl/TracingBroker.java +++ b/trace/mdsal-trace-impl/src/main/java/org/opendaylight/mdsal/trace/impl/TracingBroker.java @@ -9,29 +9,21 @@ package org.opendaylight.mdsal.trace.impl; import static java.util.Objects.requireNonNull; -import com.google.common.collect.ClassToInstanceMap; -import com.google.common.collect.MutableClassToInstanceMap; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.Set; -import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener; import org.opendaylight.mdsal.dom.api.DOMDataBroker; -import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension; -import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener; -import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService; -import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMTransactionChain; -import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener; import org.opendaylight.mdsal.trace.api.TracingDOMDataBroker; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsaltrace.rev160908.Config; -import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -40,7 +32,6 @@ import org.slf4j.LoggerFactory; @SuppressWarnings("checkstyle:JavadocStyle") //...because otherwise it whines about the elements in the @code block even though it's completely valid Javadoc - /** * TracingBroker logs "write" operations and listener registrations to the md-sal. It logs the instance identifier path, * the objects themselves, as well as the stack trace of the call invoking the registration or write operation. @@ -94,16 +85,13 @@ import org.slf4j.LoggerFactory; * watchRegistrations and allow all registrations to be logged. * * - * */ public class TracingBroker implements TracingDOMDataBroker { - @SuppressFBWarnings("SLF4J_LOGGER_SHOULD_BE_PRIVATE") - static final Logger LOG = LoggerFactory.getLogger(TracingBroker.class); + 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 BindingCodecTree codec; private final DOMDataBroker delegate; private final List registrationWatches = new ArrayList<>(); private final List writeWatches = new ArrayList<>(); @@ -118,19 +106,18 @@ public class TracingBroker implements TracingDOMDataBroker { final String iidString; final LogicalDatastoreType store; - Watch(String iidString, LogicalDatastoreType storeOrNull) { - this.store = storeOrNull; + Watch(final String iidString, final LogicalDatastoreType storeOrNull) { + store = storeOrNull; this.iidString = iidString; } - private String toIidCompString(YangInstanceIdentifier iid) { + private String toIidCompString(final YangInstanceIdentifier iid) { StringBuilder builder = new StringBuilder(); toPathString(iid, builder); - builder.append('/'); - return builder.toString(); + return builder.append('/').toString(); } - private boolean isParent(String parent, String child) { + private boolean isParent(final String parent, final String child) { int parentOffset = 0; if (parent.length() > 0 && parent.charAt(0) == '<') { parentOffset = parent.indexOf('>') + 1; @@ -145,7 +132,7 @@ public class TracingBroker implements TracingDOMDataBroker { } @SuppressWarnings({ "checkstyle:hiddenField", "hiding" }) - public boolean subtreesOverlap(YangInstanceIdentifier iid, LogicalDatastoreType store) { + public boolean subtreesOverlap(final YangInstanceIdentifier iid, final LogicalDatastoreType store) { if (this.store != null && !this.store.equals(store)) { return false; } @@ -155,7 +142,7 @@ public class TracingBroker implements TracingDOMDataBroker { } @SuppressWarnings({ "checkstyle:hiddenField", "hiding" }) - public boolean eventIsOfInterest(YangInstanceIdentifier iid, LogicalDatastoreType store) { + public boolean eventIsOfInterest(final YangInstanceIdentifier iid, final LogicalDatastoreType store) { if (this.store != null && !this.store.equals(store)) { return false; } @@ -164,27 +151,22 @@ public class TracingBroker implements TracingDOMDataBroker { } } - public TracingBroker(String type, DOMDataBroker delegate, Config config, BindingNormalizedNodeSerializer codec) { - this.type = requireNonNull(type, "type"); + public TracingBroker(final DOMDataBroker delegate, final Config config, final BindingCodecTree codec) { this.delegate = requireNonNull(delegate, "delegate"); this.codec = requireNonNull(codec, "codec"); configure(config); - if (config.isTransactionDebugContextEnabled() != null) { - this.isDebugging = config.isTransactionDebugContextEnabled(); - } else { - this.isDebugging = false; - } + isDebugging = Boolean.TRUE.equals(config.getTransactionDebugContextEnabled()); final String db = "DataBroker"; - this.transactionChainsRegistry = new CloseTrackedRegistry<>(db, "createTransactionChain()", isDebugging); - this.readOnlyTransactionsRegistry = new CloseTrackedRegistry<>(db, "newReadOnlyTransaction()", isDebugging); - this.writeTransactionsRegistry = new CloseTrackedRegistry<>(db, "newWriteOnlyTransaction()", isDebugging); - this.readWriteTransactionsRegistry = new CloseTrackedRegistry<>(db, "newReadWriteTransaction()", isDebugging); + transactionChainsRegistry = new CloseTrackedRegistry<>(db, "createTransactionChain()", isDebugging); + readOnlyTransactionsRegistry = new CloseTrackedRegistry<>(db, "newReadOnlyTransaction()", isDebugging); + writeTransactionsRegistry = new CloseTrackedRegistry<>(db, "newWriteOnlyTransaction()", isDebugging); + readWriteTransactionsRegistry = new CloseTrackedRegistry<>(db, "newReadWriteTransaction()", isDebugging); } - private void configure(Config config) { + private void configure(final Config config) { registrationWatches.clear(); - List paths = config.getRegistrationWatches(); + Set paths = config.getRegistrationWatches(); if (paths != null) { for (String path : paths) { watchRegistrations(path, null); @@ -205,7 +187,7 @@ public class TracingBroker implements TracingDOMDataBroker { * @param iidString the iid path of the root of the subtree * @param store Which LogicalDataStore? or null for both */ - public void watchRegistrations(String iidString, LogicalDatastoreType store) { + public void watchRegistrations(final String iidString, final LogicalDatastoreType store) { LOG.info("Watching registrations to {} in {}", iidString, store); registrationWatches.add(new Watch(iidString, store)); } @@ -215,13 +197,13 @@ public class TracingBroker implements TracingDOMDataBroker { * @param iidString the iid path of the root of the subtree * @param store Which LogicalDataStore? or null for both */ - public void watchWrites(String iidString, LogicalDatastoreType store) { + public void watchWrites(final String iidString, final LogicalDatastoreType store) { LOG.info("Watching writes to {} in {}", iidString, store); Watch watch = new Watch(iidString, store); writeWatches.add(watch); } - private boolean isRegistrationWatched(YangInstanceIdentifier iid, LogicalDatastoreType store) { + private boolean isRegistrationWatched(final YangInstanceIdentifier iid, final LogicalDatastoreType store) { if (registrationWatches.isEmpty()) { return true; } @@ -235,7 +217,7 @@ public class TracingBroker implements TracingDOMDataBroker { return false; } - boolean isWriteWatched(YangInstanceIdentifier iid, LogicalDatastoreType store) { + boolean isWriteWatched(final YangInstanceIdentifier iid, final LogicalDatastoreType store) { if (writeWatches.isEmpty()) { return true; } @@ -249,21 +231,21 @@ public class TracingBroker implements TracingDOMDataBroker { return false; } - static void toPathString(InstanceIdentifier iid, StringBuilder builder) { - for (InstanceIdentifier.PathArgument pathArg : iid.getPathArguments()) { - builder.append('/').append(pathArg.getType().getSimpleName()); + static void toPathString(final InstanceIdentifier iid, final StringBuilder builder) { + for (var pathArg : iid.getPathArguments()) { + builder.append('/').append(pathArg.type().getSimpleName()); } } - String toPathString(YangInstanceIdentifier yiid) { + String toPathString(final YangInstanceIdentifier yiid) { StringBuilder sb = new StringBuilder(); toPathString(yiid, sb); return sb.toString(); } - private void toPathString(YangInstanceIdentifier yiid, StringBuilder sb) { - InstanceIdentifier iid = codec.fromYangInstanceIdentifier(yiid); + private void toPathString(final YangInstanceIdentifier yiid, final StringBuilder sb) { + InstanceIdentifier iid = codec.getInstanceIdentifierCodec().toBinding(yiid); if (null == iid) { reconstructIidPathString(yiid, sb); } else { @@ -271,13 +253,9 @@ public class TracingBroker implements TracingDOMDataBroker { } } - private static void reconstructIidPathString(YangInstanceIdentifier yiid, StringBuilder sb) { + private static void reconstructIidPathString(final YangInstanceIdentifier yiid, final StringBuilder sb) { sb.append(""); for (YangInstanceIdentifier.PathArgument pathArg : yiid.getPathArguments()) { - if (pathArg instanceof YangInstanceIdentifier.AugmentationIdentifier) { - sb.append('/').append("AUGMENTATION"); - continue; - } sb.append('/').append(pathArg.getNodeType().getLocalName()); } } @@ -305,9 +283,13 @@ public class TracingBroker implements TracingDOMDataBroker { } @Override - public DOMTransactionChain createTransactionChain(DOMTransactionChainListener transactionChainListener) { - return new TracingTransactionChain(delegate.createTransactionChain(transactionChainListener), this, - transactionChainsRegistry); + public DOMTransactionChain createTransactionChain() { + return new TracingTransactionChain(delegate.createTransactionChain(), this, transactionChainsRegistry); + } + + @Override + public DOMTransactionChain createMergingTransactionChain() { + return new TracingTransactionChain(delegate.createMergingTransactionChain(), this, transactionChainsRegistry); } @Override @@ -316,44 +298,34 @@ public class TracingBroker implements TracingDOMDataBroker { } @Override - public ClassToInstanceMap getExtensions() { - final ClassToInstanceMap delegateExt = delegate.getExtensions(); - final DOMDataTreeChangeService treeChangeSvc = delegateExt.getInstance(DOMDataTreeChangeService.class); - if (treeChangeSvc == null) { - return delegateExt; - } - - final ClassToInstanceMap res = MutableClassToInstanceMap.create(delegateExt); - res.put(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() { - @Override - public ListenerRegistration registerDataTreeChangeListener( - DOMDataTreeIdentifier domDataTreeIdentifier, L listener) { - if (isRegistrationWatched(domDataTreeIdentifier.getRootIdentifier(), - domDataTreeIdentifier.getDatastoreType())) { + public T extension(final Class type) { + final var ext = delegate.extension(type); + if (DataTreeChangeExtension.class.equals(type) && ext instanceof DataTreeChangeExtension treeChange) { + return type.cast((DataTreeChangeExtension) (domDataTreeIdentifier, listener) -> { + final var rootId = domDataTreeIdentifier.path(); + if (isRegistrationWatched(rootId, domDataTreeIdentifier.datastore())) { LOG.warn("{} registration (registerDataTreeChangeListener) for {} from {}.", - listener instanceof ClusteredDOMDataTreeChangeListener ? "Clustered" : "Non-clustered", - toPathString(domDataTreeIdentifier.getRootIdentifier()), getStackSummary()); + listener instanceof ClusteredDOMDataTreeChangeListener ? "Clustered" : "Non-clustered", + toPathString(rootId), getStackSummary()); } - return treeChangeSvc.registerDataTreeChangeListener(domDataTreeIdentifier, listener); - } - }); - - return res; + return treeChange.registerDataTreeChangeListener(domDataTreeIdentifier, listener); + }); + } + return ext; } @Override - public boolean printOpenTransactions(PrintStream ps, int minOpenTXs) { + public boolean printOpenTransactions(final PrintStream ps, final int minOpenTXs) { if (transactionChainsRegistry.getAllUnique().isEmpty() && readOnlyTransactionsRegistry.getAllUnique().isEmpty() && writeTransactionsRegistry.getAllUnique().isEmpty() && readWriteTransactionsRegistry.getAllUnique().isEmpty()) { - ps.println(type + ": No open transactions, great!"); + ps.println("No open transactions, great!"); return false; } - ps.println(type + ": " + getClass().getSimpleName() - + " found some not yet (or never..) closed transaction[chain]s!"); + ps.println(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(); @@ -385,8 +357,24 @@ public class TracingBroker implements TracingDOMDataBroker { return hasFound; } - private > boolean print( - CloseTrackedRegistry registry, PrintStream ps, String indent, int minOpenTransactions) { + final void logEmptySet(final YangInstanceIdentifier yiid) { + if (LOG.isDebugEnabled()) { + LOG.debug("Empty data set write to {}", toPathString(yiid)); + } + } + + @SuppressFBWarnings(value = "SLF4J_SIGN_ONLY_FORMAT", justification = "pre-formatted logs") + static final void logOperations(final Object identifier, final List operations) { + if (LOG.isWarnEnabled()) { + LOG.warn("Transaction {} contains the following operations:", identifier); + for (var operation : operations) { + LOG.warn("{}", operation); + } + } + } + + private > boolean print(final CloseTrackedRegistry registry, final PrintStream ps, + final String indent, final int minOpenTransactions) { Set> unsorted = registry.getAllUnique(); if (unsorted.size() < minOpenTransactions) { return false; @@ -409,7 +397,8 @@ public class TracingBroker implements TracingDOMDataBroker { return true; } - private void printStackTraceElements(PrintStream ps, String indent, List stackTraceElements) { + private void printStackTraceElements(final PrintStream ps, final String indent, + final List stackTraceElements) { boolean ellipsis = false; for (final StackTraceElement stackTraceElement : stackTraceElements) { if (isStackTraceElementInteresting(stackTraceElement)) { @@ -422,7 +411,7 @@ public class TracingBroker implements TracingDOMDataBroker { } } - private boolean isStackTraceElementInteresting(StackTraceElement element) { + private boolean isStackTraceElementInteresting(final StackTraceElement element) { final String className = element.getClassName(); return !className.startsWith(getClass().getPackage().getName()) && !className.startsWith(CloseTracked.class.getPackage().getName())