<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>
--- /dev/null
+<?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>
--- /dev/null
+/*
+ * 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 {
+
+}
--- /dev/null
+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;
+ }
+ }
+}
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
<module>mdsal-it-base</module>
<module>mdsal-it-parent</module>
+ <!-- Debug utils -->
+ <module>mdsal-trace</module>
+
</modules>
<scm>