mdsaltrace utility for debugging 12/49212/18
authorJosh <jhershbe@redhat.com>
Sun, 11 Dec 2016 08:47:46 +0000 (10:47 +0200)
committerMichael Vorburger <vorburger@redhat.com>
Thu, 11 May 2017 10:56:33 +0000 (10:56 +0000)
Moved back to controller per decision from kernel meeting
a few weeks ago.

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. It works by
operating as a "bump on the stack" between the application and actual
DataBroker, intercepting write and registration calls and writing to the
log.`

+ karaf4

Change-Id: Ie7d27901429f6e7bcac7ff62e49e4e3115f5915f
Signed-off-by: Josh <jhershbe@redhat.com>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
19 files changed:
opendaylight/md-sal/mdsal-artifacts/pom.xml
opendaylight/md-sal/mdsal-trace/api/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/api/src/main/java/org/opendaylight/controller/md/sal/trace/api/TracingDOMDataBroker.java [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/api/src/main/yang/mdsaltrace.yang [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/binding-impl/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/binding-impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/deploy-site.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/dom-impl/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingBroker.java [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingReadWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/dom-impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/features/features-mdsal-trace/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/features/features-mdsal-trace/src/main/features/features.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/features/features4-mdsal-trace/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/features/odl-mdsal-trace/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/features/pom.xml [new file with mode: 0644]
opendaylight/md-sal/mdsal-trace/pom.xml [new file with mode: 0644]
opendaylight/md-sal/pom.xml

index 28b6411..00e6fec 100644 (file)
                 <artifactId>sal-schema-service</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>mdsal-trace-api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>mdsal-trace-dom-impl</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>mdsal-trace-binding-impl</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- Test support -->
             <dependency>
diff --git a/opendaylight/md-sal/mdsal-trace/api/pom.xml b/opendaylight/md-sal/mdsal-trace/api/pom.xml
new file mode 100644 (file)
index 0000000..ea1f7bb
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.mdsal</groupId>
+    <artifactId>binding-parent</artifactId>
+    <version>0.11.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>mdsal-trace-api</artifactId>
+  <version>1.6.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>mdsal-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-broker-impl</artifactId>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <configuration>
+            <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+          </configuration>
+        </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/api/src/main/java/org/opendaylight/controller/md/sal/trace/api/TracingDOMDataBroker.java b/opendaylight/md-sal/mdsal-trace/api/src/main/java/org/opendaylight/controller/md/sal/trace/api/TracingDOMDataBroker.java
new file mode 100644 (file)
index 0000000..14d30b1
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.trace.api;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+/**
+ * Tagging interface so that the tracing broker service can be more explicitly imported.
+ */
+public interface TracingDOMDataBroker extends DOMDataBroker {
+
+}
diff --git a/opendaylight/md-sal/mdsal-trace/api/src/main/yang/mdsaltrace.yang b/opendaylight/md-sal/mdsal-trace/api/src/main/yang/mdsaltrace.yang
new file mode 100644 (file)
index 0000000..ce72da7
--- /dev/null
@@ -0,0 +1,28 @@
+module mdsaltrace {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:mdsaltrace";
+    prefix "mdsaltrace";
+
+    organization
+        "Red Hat, Inc.";
+
+    description
+        "Copyright (c) 2016 Red Hat, Inc. and others.  All rights reserved.
+
+        This program and the accompanying materials are made available under the
+        terms of the Eclipse Public License v1.0 which accompanies this distribution,
+        and is available at http://www.eclipse.org/legal/epl-v10.html";
+
+    revision "2016-09-08" {
+        description "Initial revision of mdsaltrace model";
+    }
+
+    container config {
+        leaf-list registration-watches {
+            type string;
+        }
+        leaf-list write-watches {
+            type string;
+        }
+    }
+}
diff --git a/opendaylight/md-sal/mdsal-trace/binding-impl/pom.xml b/opendaylight/md-sal/mdsal-trace/binding-impl/pom.xml
new file mode 100644 (file)
index 0000000..5e14745
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.7.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>mdsal-trace-binding-impl</artifactId>
+  <version>1.6.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <dependencyManagement>
+    <dependencies>
+       <dependency>
+         <groupId>org.opendaylight.controller</groupId>
+            <artifactId>mdsal-artifacts</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+      </dependencies>
+    </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsal-trace-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsal-trace-dom-impl</artifactId>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+    <build>
+    <plugins>
+        <plugin>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>maven-bundle-plugin</artifactId>
+            <extensions>true</extensions>
+            <configuration>
+            <instructions>
+                <Import-Package>
+                org.opendaylight.controller.md.sal.trace.api,org.opendaylight.mdsal.binding.generator.api,
+                org.opendaylight.controller.md.sal.trace.dom.impl,org.opendaylight.controller.md.sal.dom.api,
+                org.opendaylight.controller.md.sal.binding.api,
+                org.opendaylight.controller.md.sal.dom.broker.impl,org.opendaylight.controller.md.sal.binding.impl,
+                org.opendaylight.controller.sal.core.api.model,*
+                </Import-Package>
+                <Embed-Transitive>true</Embed-Transitive>
+            </instructions>
+            </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <configuration>
+            <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+          </configuration>
+        </plugin>
+    </plugins>
+    </build>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/binding-impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/opendaylight/md-sal/mdsal-trace/binding-impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml
new file mode 100644 (file)
index 0000000..dc79224
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+  xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+  odl:use-default-for-reference-types="true">
+
+  <reference id="tracingDefaultDOMBroker"
+      interface="org.opendaylight.controller.md.sal.trace.api.TracingDOMDataBroker"
+      odl:type="default" />
+
+  <reference id="classLoadingStrategy" interface="org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy"/>
+  <reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService" />
+
+  <bean id="mappingCodec"
+        class="org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory" factory-method="newInstance">
+    <argument ref="classLoadingStrategy"/>
+  </bean>
+
+  <bean id="mappingCodecListenerReg" class="org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory"
+           factory-method="registerInstance" destroy-method="close">
+    <argument ref="mappingCodec"/>
+    <argument ref="schemaService"/>
+  </bean>
+
+  <bean id="tracingBindingDataBroker" class="org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter">
+    <argument ref="tracingDefaultDOMBroker"/>
+    <argument ref="mappingCodec"/>
+  </bean>
+
+  <service id="tracingBindingDataBrokerSvc" ref="tracingBindingDataBroker"
+            interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+            odl:type="default" ranking="10"/>
+
+  <reference id="domPingPongDataBroker" interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"
+                                                                                            odl:type="pingpong"/>
+
+  <bean id="bindingTracingPingPongDataBroker" class="org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter">
+    <argument ref="domPingPongDataBroker"/>
+    <argument ref="mappingCodec"/>
+  </bean>
+
+  <service ref="bindingTracingPingPongDataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+                                                                                    odl:type="pingpong" ranking="10"/>
+</blueprint>
diff --git a/opendaylight/md-sal/mdsal-trace/deploy-site.xml b/opendaylight/md-sal/mdsal-trace/deploy-site.xml
new file mode 100644 (file)
index 0000000..6a72564
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=2 tabstop=2: -->
+<!--
+    Copyright (c) 2016 Red Hat and others.  All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v1.0 which accompanies this distribution,
+    and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.opendaylight.mdsal</groupId>
+  <artifactId>deploy-site</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <stream>latest</stream>
+    <nexus.site.url>dav:https://nexus.opendaylight.org/content/sites/site/${project.groupId}/${stream}/</nexus.site.url>
+  </properties>
+
+  <build>
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.wagon</groupId>
+         <artifactId>wagon-webdav-jackrabbit</artifactId>
+         <version>2.9</version>
+      </extension>
+    </extensions>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-site-plugin</artifactId>
+        <version>3.4</version>
+        <configuration>
+          <inputDirectory>${project.build.directory}/staged-site</inputDirectory>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <distributionManagement>
+    <site>
+      <id>opendaylight-site</id>
+      <url>${nexus.site.url}</url>
+    </site>
+  </distributionManagement>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/dom-impl/pom.xml b/opendaylight/md-sal/mdsal-trace/dom-impl/pom.xml
new file mode 100644 (file)
index 0000000..d0f7dd5
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.7.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>mdsal-trace-dom-impl</artifactId>
+  <version>1.6.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <dependencyManagement>
+    <dependencies>
+       <dependency>
+         <groupId>org.opendaylight.controller</groupId>
+            <artifactId>mdsal-artifacts</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+      </dependencies>
+    </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsal-trace-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-binding-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-core-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-broker-impl</artifactId>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+    <build>
+    <plugins>
+        <plugin>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>maven-bundle-plugin</artifactId>
+            <extensions>true</extensions>
+            <configuration>
+            <instructions>
+                <!--<Embed-Dependency>sal-broker-impl;type=!pom;inline=false</Embed-Dependency>-->
+                <Import-Package>
+                org.opendaylight.controller.md.sal.binding.api,
+                org.opendaylight.controller.md.sal.dom.broker.impl,org.opendaylight.controller.md.sal.binding.impl,
+                org.opendaylight.controller.sal.core.api.model,*
+                </Import-Package>
+                <Export-Package>org.opendaylight.controller.md.sal.trace.dom.impl</Export-Package>
+                <Embed-Transitive>true</Embed-Transitive>
+            </instructions>
+            </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <configuration>
+            <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+          </configuration>
+        </plugin>
+    </plugins>
+    </build>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingBroker.java b/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingBroker.java
new file mode 100644 (file)
index 0000000..c971ec3
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.trace.dom.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+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.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.controller.md.sal.trace.api.TracingDOMDataBroker;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+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;
+import org.slf4j.Logger;
+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.
+ * It works by operating as a "bump on the stack" between the application and actual DataBroker, intercepting write
+ * and registration calls and writing to the log.
+ * <h1>Wiring:</h1>
+ * TracingBroker is designed to be easy to use. In fact, for bundles using Blueprint to inject their DataBroker
+ * TracingBroker can be used without modifying your code at all in two simple steps:
+ * <ol>
+ * <li>
+ * Simply add the dependency "mdsaltrace-features" to
+ * your karaf pom:
+ * <pre>
+ * {@code
+ *  <dependency>
+ *    <groupId>org.opendaylight.controller</groupId>
+ *    <artifactId>mdsal-trace-features</artifactId>
+ *    <classifier>features</classifier>
+ *    <type>xml</type>
+ *    <scope>runtime</scope>
+ *    <version>0.1.5-SNAPSHOT</version>
+ *  </dependency>
+ * }
+ * </pre>
+ * </li>
+ * <li>
+ * Then just load the odl-mdsal-trace feature before your feature and you're done.
+ * </li>
+ * </ol>
+ * This works because the mdsaltrace-impl bundle registers its service implementing DOMDataBroker with a higher
+ * rank than sal-binding-broker. As such, any OSGi service lookup for DataBroker will receive the TracingBroker.
+ * <p> </p>
+ * <h1>Avoiding log bloat:</h1>
+ * TracingBroker can be configured to only print registrations or write ops pertaining to certain subtrees of the
+ * md-sal. This can be done in the code via the methods of this class or via a config file. TracingBroker uses a more
+ * convenient but non-standard representation of the instance identifiers. Each instance identifier segment's
+ * class.getSimpleName() is used separated by a '/'.
+ * <p> </p>
+ * <h1>Known issues</h1>
+ * <ul>
+ *     <li>
+ *        Filtering by paths. For some registrations the codec that converts back from the DOM to binding paths is
+ *        busted. As such, an aproximated path is used in the output. For now it is recommended not to use
+ *        watchRegistrations and allow all registrations to be logged.
+ *     </li>
+ * </ul>
+ *
+ */
+public class TracingBroker implements TracingDOMDataBroker {
+
+    static final Logger LOG = LoggerFactory.getLogger(TracingBroker.class);
+
+    private static final int STACK_TRACE_FIRST_RELEVANT_FRAME = 2;
+
+    private final BindingNormalizedNodeSerializer codec;
+    private final DOMDataBroker delegate;
+    private List<Watch> registrationWatches = new ArrayList<>();
+    private List<Watch> writeWatches = new ArrayList<>();
+
+
+    private class Watch {
+        final String iidString;
+        final LogicalDatastoreType store;
+
+        Watch(String iidString, LogicalDatastoreType storeOrNull) {
+            this.store = storeOrNull;
+            this.iidString = iidString;
+        }
+
+        private String toIidCompString(YangInstanceIdentifier iid) {
+            StringBuilder builder = new StringBuilder();
+            toPathString(iid, builder);
+            builder.append('/');
+            return builder.toString();
+        }
+
+        private boolean isParent(String parent, String child) {
+            return child.startsWith(parent);
+        }
+
+        public boolean subtreesOverlap(YangInstanceIdentifier iid, LogicalDatastoreType store,
+                                                                AsyncDataBroker.DataChangeScope scope) {
+            if (this.store != null && !this.store.equals(store)) {
+                return false;
+            }
+
+            String otherIidString = toIidCompString(iid);
+
+            switch (scope) {
+                case BASE:
+                    return isParent(iidString, otherIidString);
+                case ONE: //for now just treat like SUBTREE, even though it's not
+                case SUBTREE:
+                    return isParent(iidString, otherIidString) || isParent(otherIidString, iidString);
+                default:
+                    return false;
+            }
+        }
+
+        public boolean eventIsOfInterest(YangInstanceIdentifier iid, LogicalDatastoreType store) {
+            if (this.store != null && !this.store.equals(store)) {
+                return false;
+            }
+
+            return isParent(iidString, toPathString(iid));
+        }
+    }
+
+    public TracingBroker(DOMDataBroker delegate, Config config, BindingNormalizedNodeSerializer codec) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.codec = Objects.requireNonNull(codec);
+        configure(config);
+    }
+
+    private void configure(Config config) {
+        registrationWatches.clear();
+        List<String> paths = config.getRegistrationWatches();
+        if (paths != null) {
+            for (String path : paths) {
+                watchRegistrations(path, null);
+            }
+        }
+
+        writeWatches.clear();
+        paths = config.getWriteWatches();
+        if (paths != null) {
+            for (String path : paths) {
+                watchWrites(path, null);
+            }
+        }
+    }
+
+    /**
+     * Log registrations to this subtree of the md-sal.
+     * @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) {
+        registrationWatches.add(new Watch(iidString, store));
+    }
+
+    /**
+     * Log writes to this subtree of the md-sal.
+     * @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) {
+        Watch watch = new Watch(iidString, store);
+        writeWatches.add(watch);
+    }
+
+    private boolean isRegistrationWatched(YangInstanceIdentifier iid,
+                                                            LogicalDatastoreType store, DataChangeScope scope) {
+        if (registrationWatches.isEmpty()) {
+            return true;
+        }
+
+        for (Watch regInterest : registrationWatches) {
+            if (regInterest.subtreesOverlap(iid, store, scope)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    boolean isWriteWatched(YangInstanceIdentifier iid, LogicalDatastoreType store) {
+        if (writeWatches.isEmpty()) {
+            return true;
+        }
+
+        for (Watch watch : writeWatches) {
+            if (watch.eventIsOfInterest(iid, store)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    static void toPathString(InstanceIdentifier<? extends DataObject> iid, StringBuilder builder) {
+        for (InstanceIdentifier.PathArgument pathArg : iid.getPathArguments()) {
+            builder.append('/').append(pathArg.getType().getSimpleName());
+        }
+    }
+
+    String toPathString(YangInstanceIdentifier  yiid) {
+        StringBuilder sb = new StringBuilder();
+        toPathString(yiid, sb);
+        return sb.toString();
+    }
+
+
+    void toPathString(YangInstanceIdentifier yiid, StringBuilder sb) {
+        InstanceIdentifier iid = codec.fromYangInstanceIdentifier(yiid);
+        if (null == iid) {
+            reconstructIidPathString(yiid, sb);
+        } else {
+            toPathString(iid, sb);
+        }
+    }
+
+    private void reconstructIidPathString(YangInstanceIdentifier yiid, StringBuilder sb) {
+        sb.append("RECONSTRUCTED: ");
+        for (YangInstanceIdentifier.PathArgument pathArg : yiid.getPathArguments()) {
+            if (pathArg instanceof YangInstanceIdentifier.AugmentationIdentifier) {
+                sb.append('/').append("AUGMENTATION");
+                continue;
+            }
+            sb.append('/').append(pathArg.getNodeType().getLocalName());
+        }
+        sb.append(" ->->-> [[[ ").append(yiid.toString()).append(" ]]]");
+    }
+
+    String getStackSummary() {
+        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = STACK_TRACE_FIRST_RELEVANT_FRAME; i < stack.length; i++) {
+            StackTraceElement frame = stack[i];
+            sb.append("\n\t(TracingBroker)\t").append(frame.getClassName()).append('.').append(frame.getMethodName());
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public DOMDataReadWriteTransaction newReadWriteTransaction() {
+        return new TracingReadWriteTransaction(delegate.newReadWriteTransaction(), this);
+    }
+
+    @Override
+    public DOMDataWriteTransaction newWriteOnlyTransaction() {
+        return new TracingWriteTransaction(delegate.newWriteOnlyTransaction(), this);
+    }
+
+    @Override
+    public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(
+                                                        LogicalDatastoreType store, YangInstanceIdentifier yiid,
+                                                        DOMDataChangeListener listener, DataChangeScope scope) {
+        if (isRegistrationWatched(yiid, store, scope)) {
+            LOG.warn("Registration (registerDataChangeListener) for {} from {}",
+                    toPathString(yiid), getStackSummary());
+        }
+        return delegate.registerDataChangeListener(store, yiid, listener, scope);
+    }
+
+    @Override
+    public DOMTransactionChain createTransactionChain(TransactionChainListener transactionChainListener) {
+        return delegate.createTransactionChain(transactionChainListener);
+    }
+
+    @Override
+    public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+        return delegate.newReadOnlyTransaction();
+    }
+
+    @Nonnull
+    @Override
+    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+        Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> res = delegate.getSupportedExtensions();
+        DOMDataTreeChangeService treeChangeSvc = (DOMDataTreeChangeService) res.get(DOMDataTreeChangeService.class);
+        if (treeChangeSvc == null) {
+            return res;
+        }
+
+        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) {
+                if (isRegistrationWatched(domDataTreeIdentifier.getRootIdentifier(),
+                        domDataTreeIdentifier.getDatastoreType(), DataChangeScope.SUBTREE)) {
+                    LOG.warn("Registration (registerDataTreeChangeListener) for {} from {}",
+                            toPathString(domDataTreeIdentifier.getRootIdentifier()), getStackSummary());
+                }
+                return treeChangeSvc.registerDataTreeChangeListener(domDataTreeIdentifier, listener);
+            }
+        });
+
+        return res;
+    }
+}
diff --git a/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingReadWriteTransaction.java b/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..c906ef9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.trace.dom.impl;
+
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.Objects;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+
+class TracingReadWriteTransaction extends TracingWriteTransaction implements DOMDataReadWriteTransaction {
+
+    private final DOMDataReadWriteTransaction delegate;
+
+    TracingReadWriteTransaction(DOMDataReadWriteTransaction delegate, TracingBroker tracingBroker) {
+        super(delegate, tracingBroker);
+        this.delegate = Objects.requireNonNull(delegate);
+    }
+
+    @Override
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
+                                                            LogicalDatastoreType store, YangInstanceIdentifier yiid) {
+        return delegate.read(store, yiid);
+    }
+
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(LogicalDatastoreType store, YangInstanceIdentifier yiid) {
+        return delegate.exists(store, yiid);
+    }
+}
diff --git a/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingWriteTransaction.java b/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/java/org/opendaylight/controller/md/sal/trace/dom/impl/TracingWriteTransaction.java
new file mode 100644 (file)
index 0000000..a895e98
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.trace.dom.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+class TracingWriteTransaction implements DOMDataWriteTransaction {
+
+    private final DOMDataWriteTransaction delegate;
+    private final TracingBroker tracingBroker;
+    private final List<String> logs = new ArrayList<>();
+
+    TracingWriteTransaction(DOMDataWriteTransaction delegate, TracingBroker tracingBroker) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.tracingBroker = Objects.requireNonNull(tracingBroker);
+    }
+
+    private void recordOp(LogicalDatastoreType store, YangInstanceIdentifier yiid,
+                                                                            String method, NormalizedNode<?,?> node) {
+        if (!tracingBroker.isWriteWatched(yiid, store)) {
+            return;
+        }
+
+        Object value = null;
+        if (node != null) {
+            value = node.getValue();
+        }
+
+        if (value != null && value instanceof ImmutableSet && ((Set)value).isEmpty()) {
+            if (tracingBroker.LOG.isDebugEnabled()) {
+                tracingBroker.LOG.debug("Empty data set write to {}", tracingBroker.toPathString(yiid));
+            }
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Method \"").append(method);
+            sb.append("\" to ").append(store);
+            sb.append(" at ").append(tracingBroker.toPathString(yiid)).append('.');
+            sb.append(" Data: ");
+            if (node != null) {
+                sb.append(node.getValue());
+            } else {
+                sb.append("null");
+            }
+            sb.append(" Stack:").append(tracingBroker.getStackSummary());
+            synchronized (this) {
+                logs.add(sb.toString());
+            }
+        }
+    }
+
+    private synchronized void logOps() {
+        for (String log : logs) {
+            tracingBroker.LOG.warn(log);
+        }
+        logs.clear();
+    }
+
+    @Override
+    public void put(LogicalDatastoreType store, YangInstanceIdentifier yiid, NormalizedNode<?, ?> node) {
+        recordOp(store, yiid, "put", node);
+        delegate.put(store, yiid, node);
+    }
+
+    @Override
+    public void merge(LogicalDatastoreType store, YangInstanceIdentifier yiid, NormalizedNode<?, ?> node) {
+        recordOp(store, yiid, "merge", node);
+        delegate.merge(store, yiid, node);
+    }
+
+    @Override
+    public boolean cancel() {
+        logs.clear();
+        return delegate.cancel();
+    }
+
+    @Override
+    public void delete(LogicalDatastoreType store, YangInstanceIdentifier yiid) {
+        recordOp(store, yiid, "delete", null);
+        delegate.delete(store, yiid);
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        logOps();
+        return delegate.submit();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        logOps();
+        return delegate.commit();
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return delegate.getIdentifier();
+    }
+}
diff --git a/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/opendaylight/md-sal/mdsal-trace/dom-impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml
new file mode 100644 (file)
index 0000000..7535f95
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+  xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+  odl:use-default-for-reference-types="true">
+
+  <odl:clustered-app-config id="mdsalConfig"
+                            binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsaltrace.rev160908.Config">
+  </odl:clustered-app-config>
+
+  <reference id="codec"
+        interface="org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer"
+        odl:type="default" />
+
+  <reference id="realDefaultDOMBroker"
+      interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"
+      odl:type="default" />
+
+  <bean id="tracingDefaultDOMBroker" class="org.opendaylight.controller.md.sal.trace.dom.impl.TracingBroker">
+      <argument ref="realDefaultDOMBroker" />
+      <argument ref="mdsalConfig" />
+      <argument ref="codec" />
+  </bean>
+
+  <service id="tracingDefaultDOMBrokerSvc" ref="tracingDefaultDOMBroker" ranking="10" odl:type="default">
+    <interfaces>
+      <value>org.opendaylight.controller.md.sal.dom.api.DOMDataBroker</value>
+      <value>org.opendaylight.controller.md.sal.trace.api.TracingDOMDataBroker</value>
+    </interfaces>
+  </service>
+
+
+  <bean id="tracingPingPongDOMBroker" class="org.opendaylight.controller.md.sal.dom.broker.impl.PingPongDataBroker">
+    <argument ref="tracingDefaultDOMBroker" />
+  </bean>
+
+  <service id="tracingPingPongDOMBrokerSvc" ref="tracingPingPongDOMBroker"
+             interface="org.opendaylight.controller.md.sal.dom.api.DOMDataBroker"
+             ranking="10" odl:type="pingpong" />
+</blueprint>
diff --git a/opendaylight/md-sal/mdsal-trace/features/features-mdsal-trace/pom.xml b/opendaylight/md-sal/mdsal-trace/features/features-mdsal-trace/pom.xml
new file mode 100644 (file)
index 0000000..d6751a9
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>features-parent</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>mdsal-trace-features</artifactId>
+  <version>1.6.0-SNAPSHOT</version>
+  <name>${project.artifactId}</name>
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- project specific dependencies -->
+      <dependency>
+        <groupId>org.opendaylight.mdsal</groupId>
+        <artifactId>mdsal-artifacts</artifactId>
+        <version>2.3.0-SNAPSHOT</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>mdsal-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-mdsal</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsal-trace-dom-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsal-trace-binding-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsal-trace-api</artifactId>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/features/features-mdsal-trace/src/main/features/features.xml b/opendaylight/md-sal/mdsal-trace/features/features-mdsal-trace/src/main/features/features.xml
new file mode 100644 (file)
index 0000000..ac91121
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<features name="odl-mdsaltrace-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
+
+  <feature name='odl-mdsal-trace' version='${project.version}' description='OpenDaylight :: TracingBroker'>
+    <feature version='${project.version}'>odl-mdsal-broker</feature>
+    <feature version='${project.version}'>odl-mdsal-broker-local</feature>
+    <bundle>mvn:org.opendaylight.controller/mdsal-trace-api/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.controller/mdsal-trace-dom-impl/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.controller/mdsal-trace-binding-impl/{{VERSION}}</bundle>
+  </feature>
+</features>
diff --git a/opendaylight/md-sal/mdsal-trace/features/features4-mdsal-trace/pom.xml b/opendaylight/md-sal/mdsal-trace/features/features4-mdsal-trace/pom.xml
new file mode 100644 (file)
index 0000000..8fc80b4
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>feature-repo-parent</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>features4-mdsal-trace</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <name>OpenDaylight :: TracingBroker</name>
+    <packaging>feature</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>odl-mdsal-trace</artifactId>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/features/odl-mdsal-trace/pom.xml b/opendaylight/md-sal/mdsal-trace/features/odl-mdsal-trace/pom.xml
new file mode 100644 (file)
index 0000000..27d9c6d
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>odl-mdsal-trace</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <name>OpenDaylight :: TracingBroker</name>
+    <packaging>feature</packaging>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>mdsal-artifacts</artifactId>
+                <version>${project.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>odl-mdsal-broker</artifactId>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>odl-mdsal-broker-local</artifactId>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>mdsal-trace-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>mdsal-trace-dom-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>mdsal-trace-binding-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/features/pom.xml b/opendaylight/md-sal/mdsal-trace/features/pom.xml
new file mode 100644 (file)
index 0000000..72ac610
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>mdsal-trace-feature-aggregator</artifactId>
+  <version>1.6.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>features-mdsal-trace</module>
+    <module>odl-mdsal-trace</module>
+    <module>features4-mdsal-trace</module>
+  </modules>
+</project>
diff --git a/opendaylight/md-sal/mdsal-trace/pom.xml b/opendaylight/md-sal/mdsal-trace/pom.xml
new file mode 100644 (file)
index 0000000..215cdc8
--- /dev/null
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright © 2016 Red Hat and others. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>mdsal-trace-aggregator</artifactId>
+  <version>1.6.0-SNAPSHOT</version>
+  <name>mdsaltrace</name>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>api</module>
+    <module>dom-impl</module>
+    <module>binding-impl</module>
+    <module>features</module>
+  </modules>
+
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <!--
+          This profile is to ensure we only build javadocs reports
+          when we plan to deploy Maven site for our project.
+      -->
+      <id>maven-site</id>
+      <activation>
+        <file>
+          <exists>${user.dir}/deploy-site.xml</exists>
+        </file>
+      </activation>
+
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <inherited>false</inherited>
+            <executions>
+              <execution>
+                <id>aggregate</id>
+                <goals>
+                  <goal>aggregate</goal>
+                </goals>
+                <phase>package</phase>
+            </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-checkstyle-plugin</artifactId>
+            <configuration>
+              <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <!--
+      Maven Site Configuration
+
+      The following configuration is necessary for maven-site-plugin to
+      correctly identify the correct deployment path for OpenDaylight Maven
+      sites.
+  -->
+  <url>${odl.site.url}/${project.groupId}/${stream}/</url>
+
+  <distributionManagement>
+    <site>
+      <id>opendaylight-site</id>
+      <url>${nexus.site.url}/</url>
+    </site>
+  </distributionManagement>
+</project>
index 7734ded..1c4ad1c 100644 (file)
@@ -89,6 +89,9 @@
     <module>mdsal-it-base</module>
     <module>mdsal-it-parent</module>
 
+    <!-- Debug utils -->
+    <module>mdsal-trace</module>
+
   </modules>
 
   <scm>

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.