Merge "Add javadoc generation for yang modules in netconf subsystem"
authorEd Warnicke <eaw@cisco.com>
Thu, 30 Jan 2014 11:02:43 +0000 (11:02 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 30 Jan 2014 11:02:43 +0000 (11:02 +0000)
24 files changed:
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java
opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java
opendaylight/web/troubleshoot/src/main/resources/js/page.js

index fa6f94bfedf1354b19c0004bec249272baf695a9..521ec23859e0656ed15bb6db2e7095bbcafbf89c 100644 (file)
                 <artifactId>maven-jar-plugin</artifactId>
                 <version>2.4</version>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.8.1</version>
-                <configuration>
-                    <stylesheet>maven</stylesheet>
-                    <failOnError>false</failOnError>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>aggregate</goal>
-                        </goals>
-                        <phase>site</phase>
-                    </execution>
-                </executions>
-            </plugin>
             <plugin>
                 <!-- FIXME: BUG-272: remove this configuration override -->
                 <groupId>org.apache.maven.plugins</groupId>
index cb201c5fd16bd8800d83a4cdd286a619430c31eb..c28b03eb65a092817917956cc9794a8267c41479 100644 (file)
@@ -7,14 +7,17 @@
  */
 package org.opendaylight.controller.sal.binding.api;
 
+import java.util.EventListener;
 import java.util.concurrent.ExecutorService;
 
 import org.opendaylight.controller.md.sal.common.api.notify.NotificationPublishService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 public interface NotificationProviderService extends NotificationService, NotificationPublishService<Notification> {
 
+
     /**
      * Deprecated. Use {@link #publish(Notification)}.
      * 
@@ -34,7 +37,8 @@ public interface NotificationProviderService extends NotificationService, Notifi
     /**
      * Publishes a notification.
      * 
-     * @param Notification notification to publish.
+     * @param Notification
+     *            notification to publish.
      * 
      */
     @Override
@@ -46,4 +50,12 @@ public interface NotificationProviderService extends NotificationService, Notifi
      */
     @Override
     void publish(Notification notification, ExecutorService service);
+
+    ListenerRegistration<NotificationInterestListener> registerInterestListener(
+            NotificationInterestListener interestListener);
+
+    public interface NotificationInterestListener extends EventListener {
+
+        void onNotificationSubscribtion(Class<? extends Notification> notificationType);
+    }
 }
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java
new file mode 100644 (file)
index 0000000..d7cb926
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, 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.sal.binding.api.data;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.yangtools.concepts.Delegator;
+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.common.RpcResult;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Synchronized wrapper for DataModificationTransaction.
+ * 
+ * To get instance of synchronized wrapper use {@link #from(DataModificationTransaction)}
+ *
+ */
+public final class SynchronizedTransaction implements DataModificationTransaction,Delegator<DataModificationTransaction> {
+
+    private final DataModificationTransaction delegate;
+    
+    private SynchronizedTransaction(DataModificationTransaction delegate) {
+        this.delegate = delegate;
+    }
+
+    /**
+     * Returns synchronized wrapper on supplied transaction.
+     * 
+     * @param transaction Transaction for which synchronized wrapper should be created.
+     * @return Synchronized wrapper over transaction.
+     */
+    public static final SynchronizedTransaction from(DataModificationTransaction transaction) {
+        Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
+        if (transaction instanceof SynchronizedTransaction) {
+            return (SynchronizedTransaction) transaction;
+        }
+        return new SynchronizedTransaction(transaction);
+    }
+
+    @Override
+    public synchronized Map<InstanceIdentifier<? extends DataObject>, DataObject> getCreatedOperationalData() {
+        return delegate.getCreatedOperationalData();
+    }
+
+    @Override
+    public synchronized Map<InstanceIdentifier<? extends DataObject>, DataObject> getCreatedConfigurationData() {
+        return delegate.getCreatedConfigurationData();
+    }
+
+    @Override
+    public synchronized DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        return delegate.readOperationalData(path);
+    }
+
+    @Override
+    public synchronized TransactionStatus getStatus() {
+        return delegate.getStatus();
+    }
+
+    @Override
+    public synchronized Map<InstanceIdentifier<? extends DataObject>, DataObject> getUpdatedOperationalData() {
+        return delegate.getUpdatedOperationalData();
+    }
+
+    @Deprecated
+    public synchronized void putRuntimeData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
+        delegate.putRuntimeData(path, data);
+    }
+
+    @Override
+    public synchronized Object getIdentifier() {
+        return delegate.getIdentifier();
+    }
+
+    @Override
+    public synchronized DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        return delegate.readConfigurationData(path);
+    }
+
+    @Override
+    public synchronized Future<RpcResult<TransactionStatus>> commit() {
+        return delegate.commit();
+    }
+
+    @Override
+    public synchronized void putOperationalData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
+        delegate.putOperationalData(path, data);
+    }
+
+    @Override
+    public synchronized void putConfigurationData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
+        delegate.putConfigurationData(path, data);
+    }
+
+    @Override
+    public synchronized Map<InstanceIdentifier<? extends DataObject>, DataObject> getUpdatedConfigurationData() {
+        return delegate.getUpdatedConfigurationData();
+    }
+
+    @Deprecated
+    public synchronized void removeRuntimeData(InstanceIdentifier<? extends DataObject> path) {
+        delegate.removeRuntimeData(path);
+    }
+
+    @Override
+    public synchronized void removeOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        delegate.removeOperationalData(path);
+    }
+
+    @Override
+    public synchronized void removeConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        delegate.removeConfigurationData(path);
+    }
+
+    @Override
+    public synchronized Set<InstanceIdentifier<? extends DataObject>> getRemovedConfigurationData() {
+        return delegate.getRemovedConfigurationData();
+    }
+
+    @Override
+    public synchronized Set<InstanceIdentifier<? extends DataObject>> getRemovedOperationalData() {
+        return delegate.getRemovedOperationalData();
+    }
+
+    @Override
+    public synchronized Map<InstanceIdentifier<? extends DataObject>, DataObject> getOriginalConfigurationData() {
+        return delegate.getOriginalConfigurationData();
+    }
+
+    @Override
+    public synchronized ListenerRegistration<DataTransactionListener> registerListener(DataTransactionListener listener) {
+        return delegate.registerListener(listener);
+    }
+
+    @Override
+    public synchronized Map<InstanceIdentifier<? extends DataObject>, DataObject> getOriginalOperationalData() {
+        return delegate.getOriginalOperationalData();
+    }
+
+    @Override
+    public synchronized DataModificationTransaction getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((delegate == null) ? 0 : delegate.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()){
+            return false;
+        }
+        SynchronizedTransaction other = (SynchronizedTransaction) obj;
+        if (delegate == null) {
+            if (other.delegate != null) {
+                return false;
+            }
+        } else if (!delegate.equals(other.delegate)) {
+            return false;
+        }
+        return true;
+    }
+}
+
index 52aa8d029066b3093a90300f6bb078886b2b3d7b..d997af59126833190b26696e752dfcc7061fe352 100644 (file)
@@ -21,14 +21,20 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration
 import org.opendaylight.yangtools.concepts.Registration\r
 import org.opendaylight.yangtools.yang.binding.Notification\r
 import org.slf4j.LoggerFactory\r
-import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder\rimport com.google.common.collect.Multimaps
-
-class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder\rimport com.google.common.collect.Multimaps\r
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry\r
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener\r
 \r
+class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {\r
+    \r
+    val ListenerRegistry<NotificationInterestListener> interestListeners = ListenerRegistry.create;\r
+    \r
     val Multimap<Class<? extends Notification>, NotificationListener<?>> listeners;\r
 \r
     @Property\r
     var ExecutorService executor;\r
+    \r
+    val logger = LoggerFactory.getLogger(NotificationBrokerImpl)\r
 \r
     new() {\r
         listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create())\r
@@ -101,14 +107,26 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab
         NotificationListener<T> listener) {\r
         val reg = new GenericNotificationRegistration<T>(notificationType, listener, this);\r
         listeners.put(notificationType, listener);\r
+        announceNotificationSubscription(notificationType);\r
         return reg;\r
     }\r
+    \r
+    def announceNotificationSubscription(Class<? extends Notification> notification) {\r
+        for (listener : interestListeners) {\r
+            try {\r
+                listener.instance.onNotificationSubscribtion(notification);\r
+            } catch (Exception e) {\r
+                logger.error("", e.message)\r
+            }\r
+        }\r
+    }\r
 \r
     override registerNotificationListener(\r
         org.opendaylight.yangtools.yang.binding.NotificationListener listener) {\r
         val invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener);\r
         for (notifyType : invoker.supportedNotifications) {\r
             listeners.put(notifyType, invoker.invocationProxy)\r
+            announceNotificationSubscription(notifyType)\r
         }\r
         val registration = new GeneratedListenerRegistration(listener, invoker,this);\r
         return registration as Registration<org.opendaylight.yangtools.yang.binding.NotificationListener>;\r
@@ -128,6 +146,14 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab
         //FIXME: implement properly.\r
     }\r
     \r
+    override registerInterestListener(NotificationInterestListener interestListener) {\r
+        val registration = interestListeners.register(interestListener);\r
+        \r
+        for(notification : listeners.keySet) {\r
+            interestListener.onNotificationSubscribtion(notification);\r
+        }\r
+        return registration\r
+    }\r
 }\r
 \r
 class GenericNotificationRegistration<T extends Notification> extends AbstractObjectRegistration<NotificationListener<T>> implements ListenerRegistration<NotificationListener<T>> {\r
index a21b3f1a614f9a06299687ce324b3e96f71ab84d..978c79ea02752b1a6d19e3fbc953dc80e50c011c 100644 (file)
@@ -80,12 +80,14 @@ public class BindingDomConnectorDeployer {
         connector.startDataForwarding();
     }
 
-    public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) {
+    public static void startNotificationForwarding(BindingIndependentConnector connector, 
+            NotificationProviderService baService, NotificationPublishService domService) {
         if(connector.isNotificationForwarding()) {
             return;
         }
-
-        // FIXME
+        connector.setBindingNotificationService(baService);
+        connector.setDomNotificationService(domService);
+        connector.startNotificationForwarding();
     }
 
     //
index aaed12f740ea7224c540fdc936f544308ccb1a3e..5630664a678e8387426bb6a2b2ff88957b0654e8 100644 (file)
@@ -17,6 +17,7 @@ import java.lang.reflect.Proxy;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -37,6 +38,8 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
@@ -55,6 +58,8 @@ import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
@@ -65,6 +70,7 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -93,7 +99,7 @@ public class BindingIndependentConnector implements //
 
     private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
 
-    @SuppressWarnings( "deprecation")
+    @SuppressWarnings("deprecation")
     private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
@@ -101,7 +107,6 @@ public class BindingIndependentConnector implements //
 
     private final static Method EQUALS_METHOD;
 
-
     private BindingIndependentMappingService mappingService;
 
     private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
@@ -146,10 +151,13 @@ public class BindingIndependentConnector implements //
 
     private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter;
 
+    private NotificationProviderService baNotifyService;
+
+    private NotificationPublishService domNotificationService;
 
     static {
         try {
-        EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
+            EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -311,7 +319,7 @@ public class BindingIndependentConnector implements //
                 baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance());
                 baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance());
             }
-            if(biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) {
+            if (biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) {
                 biRouter = (org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) biRpcRegistry;
             }
             rpcForwarding = true;
@@ -320,7 +328,11 @@ public class BindingIndependentConnector implements //
 
     public void startNotificationForwarding() {
         checkState(!notificationForwarding, "Connector is already forwarding notifications.");
-        notificationForwarding = true;
+        if (baNotifyService != null && domNotificationService != null) {
+            baNotifyService.registerInterestListener(new DomToBindingNotificationForwarder());
+
+            notificationForwarding = true;
+        }
     }
 
     protected void setMappingService(BindingIndependentMappingService mappingService) {
@@ -616,7 +628,7 @@ public class BindingIndependentConnector implements //
                 }
                 createDefaultDomForwarder();
             } catch (Exception e) {
-                LOG.error("Could not forward Rpcs of type {}", service.getName(),e);
+                LOG.error("Could not forward Rpcs of type {}", service.getName(), e);
             }
             registrations = registrationsBuilder.build();
         }
@@ -635,13 +647,13 @@ public class BindingIndependentConnector implements //
 
         @Override
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            if(EQUALS_METHOD.equals(method)) {
+            if (EQUALS_METHOD.equals(method)) {
                 return false;
             }
             RpcInvocationStrategy strategy = strategiesByMethod.get(method);
             checkState(strategy != null);
             checkArgument(args.length <= 2);
-            if(args.length == 1) {
+            if (args.length == 1) {
                 checkArgument(args[0] instanceof DataObject);
                 return strategy.forwardToDomBroker((DataObject) args[0]);
             }
@@ -719,9 +731,10 @@ public class BindingIndependentConnector implements //
                     RpcInvocationStrategy strategy = null;
                     if (outputClass.isPresent()) {
                         if (inputClass.isPresent()) {
-                            strategy = new DefaultInvocationStrategy(rpc,targetMethod, outputClass.get(), inputClass.get());
+                            strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass
+                                    .get());
                         } else {
-                            strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod);
+                            strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod);
                         }
                     } else if(inputClass.isPresent()){
                         strategy = new NoOutputInvocationStrategy(rpc,targetMethod, inputClass.get());
@@ -740,7 +753,7 @@ public class BindingIndependentConnector implements //
         protected final Method targetMethod;
         protected final QName rpc;
 
-        public RpcInvocationStrategy(QName rpc,Method targetMethod) {
+        public RpcInvocationStrategy(QName rpc, Method targetMethod) {
             this.targetMethod = targetMethod;
             this.rpc = rpc;
         }
@@ -766,19 +779,25 @@ public class BindingIndependentConnector implements //
         @SuppressWarnings({ "rawtypes", "unchecked" })
         public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class<?> outputClass,
                 Class<? extends DataContainer> inputClass) {
-            super(rpc,targetMethod);
+            super(rpc, targetMethod);
             this.outputClass = new WeakReference(outputClass);
             this.inputClass = new WeakReference(inputClass);
         }
 
+        @SuppressWarnings("unchecked")
         @Override
         public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
             DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
-            Future<RpcResult<?>> result = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
-            if (result == null) {
+            Future<RpcResult<?>> futureResult = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
+            if (futureResult == null) {
                 return Rpcs.getRpcResult(false);
             }
-            RpcResult<?> bindingResult = result.get();
+            RpcResult<?> bindingResult = futureResult.get();
+            final Object resultObj = bindingResult.getResult();
+            if (resultObj instanceof DataObject) {
+                final CompositeNode output = mappingService.toDataDom((DataObject)resultObj);
+                return Rpcs.getRpcResult(true, output, Collections.<RpcError>emptySet());
+            }
             return Rpcs.getRpcResult(true);
         }
 
@@ -786,16 +805,16 @@ public class BindingIndependentConnector implements //
         public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
             if(biRouter != null) {
                 CompositeNode xml = mappingService.toDataDom(input);
-                CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
+                CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
                 RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
                 Object baResultValue = null;
-                if(result.getResult() != null) {
+                if (result.getResult() != null) {
                     baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult());
                 }
                 RpcResult<?> baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors());
-                return Futures.<RpcResult<?>>immediateFuture(baResult);
+                return Futures.<RpcResult<?>> immediateFuture(baResult);
             }
-            return Futures.<RpcResult<?>>immediateFuture(Rpcs.getRpcResult(false));
+            return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
         }
 
     }
@@ -803,7 +822,7 @@ public class BindingIndependentConnector implements //
     private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy {
 
         public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) {
-            super(rpc,targetMethod);
+            super(rpc, targetMethod);
         }
 
         public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
@@ -874,4 +893,54 @@ public class BindingIndependentConnector implements //
     public BindingIndependentMappingService getMappingService() {
         return mappingService;
     }
+
+    public void setBindingNotificationService(NotificationProviderService baService) {
+        this.baNotifyService = baService;
+
+    }
+
+    public void setDomNotificationService(NotificationPublishService domService) {
+        this.domNotificationService = domService;
+    }
+    
+    private class DomToBindingNotificationForwarder implements NotificationInterestListener, NotificationListener {
+
+        private ConcurrentMap<QName, WeakReference<Class<? extends Notification>>> notifications = new ConcurrentHashMap<>();
+        private Set<QName> supportedNotifications = new HashSet<>();
+        
+        @Override
+        public Set<QName> getSupportedNotifications() {
+            return Collections.unmodifiableSet(supportedNotifications);
+        }
+
+        @Override
+        public void onNotification(CompositeNode notification) {
+            QName qname = notification.getNodeType();
+            WeakReference<Class<? extends Notification>> potential = notifications.get(qname);
+            if (potential != null) {
+                Class<? extends Notification> potentialClass = potential.get();
+                if (potentialClass != null) {
+                    final DataContainer baNotification = mappingService.dataObjectFromDataDom(potentialClass,
+                            notification);
+                    
+                    if (baNotification instanceof Notification) {
+                        baNotifyService.publish((Notification) baNotification);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onNotificationSubscribtion(Class<? extends Notification> notificationType) {
+            QName qname = BindingReflections.findQName(notificationType);
+            if (qname != null) {
+                WeakReference<Class<? extends Notification>> already = notifications.putIfAbsent(qname,
+                        new WeakReference<Class<? extends Notification>>(notificationType));
+                if (already == null) {
+                    domNotificationService.addNotificationListener(qname, this);
+                    supportedNotifications.add(qname);
+                }
+            }
+        }
+    }
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java
deleted file mode 100644 (file)
index 7b94845..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, 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.sal.binding.impl.connect.dom;
-
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
-import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public class BindingIndependentMountPointForwarder {
-
-    private MountProvisionService domMountService;
-    private MountProviderService baMountService;
-    private BindingIndependentMappingService mappingService;
-
-    private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
-    private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
-
-    private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors;
-    private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded;
-    private ListenerRegistration<MountProvisionListener> domListenerRegistration;
-    private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
-
-    public MountProvisionService getDomMountService() {
-        return domMountService;
-    }
-
-    public void setDomMountService(MountProvisionService domMountService) {
-        this.domMountService = domMountService;
-    }
-
-    public void start() {
-        if(domMountService != null && baMountService != null) {
-            domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
-            baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager);
-        }
-    }
-
-    private void tryToDeployConnector(InstanceIdentifier<?> baPath,
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
-        if(previous != null) {
-            return;
-        }
-        MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath);
-        MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath);
-        BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
-        connectors.put(baPath, connector);
-        connector.startDataForwarding();
-        connector.startRpcForwarding();
-        connector.startNotificationForwarding();
-    }
-
-    private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
-            MountProvisionInstance domMountPoint) {
-        BindingIndependentConnector connector = new BindingIndependentConnector();
-
-        connector.setBindingDataService(baMountPoint);
-        connector.setBindingRpcRegistry(baMountPoint);
-        //connector.setBindingNotificationBroker(baMountPoint);
-
-        connector.setDomDataService(domMountPoint);
-        connector.setDomRpcRegistry(domMountPoint);
-        //connector.setDomNotificationBroker(domMountPoint);
-        return connector;
-    }
-
-    public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
-        InstanceIdentifier<?> baPath;
-        try {
-            baPath = mappingService.fromDataDom(domPath);
-            BindingIndependentConnector potentialConnector = connectors.get(baPath);
-            if(potentialConnector != null) {
-                return;
-            }
-            tryToDeployConnector(baPath,domPath);
-        } catch (DeserializationException e) {
-
-        }
-    }
-
-    public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
-        BindingIndependentConnector potentialConnector =connectors.get(baPath);
-        if(potentialConnector != null) {
-            return;
-        }
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath);
-        tryToDeployConnector(baPath, domPath);
-    }
-
-    public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
-        // FIXME: Implement closeMountPoint
-    }
-
-    public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
-        // FIXME: Implement closeMountPoint
-    }
-
-    private class DomMountPointForwardingManager implements MountProvisionListener {
-
-        @Override
-        public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
-            tryToDeployDomForwarder(path);
-        }
-
-        @Override
-        public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
-            undeployDomForwarder(path);
-        }
-    }
-
-    private class BindingMountPointForwardingManager implements
-            org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
-
-        @Override
-        public void onMountPointCreated(InstanceIdentifier<?> path) {
-            tryToDeployBindingForwarder(path);
-        }
-
-        @Override
-        public void onMountPointRemoved(InstanceIdentifier<?> path) {
-            undeployBindingForwarder(path);
-        }
-    }
-}
index c90f6fdb470d17e5d2ea55b4a9e08ea435411f56..8c74008990614ea07bba2499508c7d6143a15c4a 100644 (file)
@@ -108,7 +108,7 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem
         BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint);
         BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint);
         // connector.setDomNotificationBroker(domMountPoint);
-        return connector;
+        return mountConnector;
     }
 
     public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
index 2a8ebe869c76e8a4faead7f00f84b6005502d3ec..c7d6640ce1eb6c53df124c5338290519f4843e14 100644 (file)
@@ -99,4 +99,10 @@ public abstract class AbstractBindingSalProviderInstance<D extends DataProviderS
             L listener) {
         return getRpcRegistryChecked().registerRouteChangeListener(listener);
     }
+    
+    @Override
+    public ListenerRegistration<NotificationInterestListener> registerInterestListener(
+            NotificationInterestListener interestListener) {
+        return getNotificationBrokerChecked().registerInterestListener(interestListener);
+    }
 }
index 927975ca53bbb06bb661225ee70f3e7bcad175b9..2c3b0188f48096d34ea45485fe34ec1a1711efe1 100644 (file)
@@ -45,6 +45,8 @@ import org.slf4j.LoggerFactory
 \r
 import static com.google.common.base.Preconditions.*\rimport org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent
 import com.google.common.collect.Multimaps
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
 
 abstract class AbstractDataBroker<P extends Path<P>, D, DCL extends DataChangeListener<P, D>> implements DataModificationTransactionFactory<P, D>, //\r
 DataReader<P, D>, //\r
@@ -70,16 +72,20 @@ DataProvisionService<P, D> {
 \r
     Multimap<P, DataChangeListenerRegistration<P, D, DCL>> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create());\r
     Multimap<P, DataCommitHandlerRegistrationImpl<P, D>> commitHandlers = Multimaps.synchronizedSetMultimap(HashMultimap.create());\r
+    
+    private val Lock registrationLock = new ReentrantLock;
     \r
     val ListenerRegistry<RegistrationListener<DataCommitHandlerRegistration<P,D>>> commitHandlerRegistrationListeners = new ListenerRegistry();\r
     public new() {\r
     }\r
 \r
     protected def /*Iterator<Entry<Collection<DataChangeListenerRegistration<P,D,DCL>>,D>>*/ affectedCommitHandlers(\r
-        HashSet<P> paths) {\r
-        return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] //\r
-        .transformAndConcat[value] //\r
-        .transform[instance].toList()\r
+        HashSet<P> paths) {
+        return withLock(registrationLock) [|\r
+            return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] //\r
+                .transformAndConcat[value] //\r
+                .transform[instance].toList()
+        ]\r
     }\r
 \r
     override final readConfigurationData(P path) {\r
@@ -88,43 +94,56 @@ DataProvisionService<P, D> {
 \r
     override final readOperationalData(P path) {\r
         return dataReadRouter.readOperationalData(path);\r
-    }\r
-\r
-    override final registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler) {\r
-        val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this);\r
-        commitHandlers.put(path, registration)\r
-        LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path);\r
-        for(listener : commitHandlerRegistrationListeners) {\r
-            try {\r
-                listener.instance.onRegister(registration);\r
-            } catch (Exception e) {\r
-                LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e);\r
-            }\r
-        }\r
-        return registration;\r
+    }
+    
+    private static def <T> withLock(Lock lock,Callable<T> method) {
+        lock.lock
+        try {
+            return method.call
+        } finally {
+            lock.unlock
+        }
+    } \r
+\r
+    override final registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler) {
+        return withLock(registrationLock) [|\r
+            val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this);\r
+            commitHandlers.put(path, registration)\r
+            LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path);\r
+            for(listener : commitHandlerRegistrationListeners) {\r
+                try {\r
+                    listener.instance.onRegister(registration);\r
+                } catch (Exception e) {\r
+                    LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e);\r
+                }\r
+            }
+            return registration;
+        ]\r
     }\r
 \r
     override final def registerDataChangeListener(P path, DCL listener) {\r
-        val reg = new DataChangeListenerRegistration(path, listener, this);\r
-        listeners.put(path, reg);\r
-        val initialConfig = dataReadRouter.readConfigurationData(path);\r
-        val initialOperational = dataReadRouter.readOperationalData(path);\r
-        val event = createInitialListenerEvent(path,initialConfig,initialOperational);\r
-        listener.onDataChanged(event);\r
-        return reg;\r
+        return withLock(registrationLock) [|
+            val reg = new DataChangeListenerRegistration(path, listener, this);\r
+            listeners.put(path, reg);\r
+            val initialConfig = dataReadRouter.readConfigurationData(path);\r
+            val initialOperational = dataReadRouter.readOperationalData(path);\r
+            val event = createInitialListenerEvent(path,initialConfig,initialOperational);\r
+            listener.onDataChanged(event);\r
+            return reg;
+        ]\r
     }\r
 \r
     final def registerDataReader(P path, DataReader<P, D> reader) {\r
-\r
-        val confReg = dataReadRouter.registerConfigurationReader(path, reader);\r
-        val dataReg = dataReadRouter.registerOperationalReader(path, reader);\r
-\r
-        return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg));\r
+        return withLock(registrationLock) [|\r
+            val confReg = dataReadRouter.registerConfigurationReader(path, reader);\r
+            val dataReg = dataReadRouter.registerOperationalReader(path, reader);\r
+    \r
+            return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg));
+        ]\r
     }\r
     \r
     override registerCommitHandlerListener(RegistrationListener<DataCommitHandlerRegistration<P, D>> commitHandlerListener) {\r
         val ret = commitHandlerRegistrationListeners.register(commitHandlerListener);\r
-        \r
         return ret;\r
     }\r
     \r
@@ -133,21 +152,25 @@ DataProvisionService<P, D> {
         \r
     }\r
 \r
-    protected final def removeListener(DataChangeListenerRegistration<P, D, DCL> registration) {\r
-        listeners.remove(registration.path, registration);\r
+    protected final def removeListener(DataChangeListenerRegistration<P, D, DCL> registration) {
+        return withLock(registrationLock) [|\r
+            listeners.remove(registration.path, registration);
+        ]\r
     }\r
 \r
     protected final def removeCommitHandler(DataCommitHandlerRegistrationImpl<P, D> registration) {\r
-        commitHandlers.remove(registration.path, registration);\r
-        \r
-         LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path);\r
-        for(listener : commitHandlerRegistrationListeners) {\r
-            try {\r
-                listener.instance.onUnregister(registration);\r
-            } catch (Exception e) {\r
-                LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e);\r
-            }\r
-        }\r
+        return withLock(registrationLock) [|
+            commitHandlers.remove(registration.path, registration);\r
+             LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path);\r
+            for(listener : commitHandlerRegistrationListeners) {\r
+                try {\r
+                    listener.instance.onUnregister(registration);\r
+                } catch (Exception e) {\r
+                    LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e);\r
+                }\r
+            }
+            return null;
+        ]\r
     }\r
 \r
     protected final def getActiveCommitHandlers() {\r
@@ -155,12 +178,14 @@ DataProvisionService<P, D> {
     }\r
 \r
     protected def /*Iterator<Entry<Collection<DataChangeListenerRegistration<P,D,DCL>>,D>>*/ affectedListenersWithInitialState(\r
-        HashSet<P> paths) {\r
-        return FluentIterable.from(listeners.asMap.entrySet).filter[key.isAffectedBy(paths)].transform [\r
-            val operationalState = readOperationalData(key)\r
-            val configurationState = readConfigurationData(key)\r
-            return new ListenerStateCapture(key, value, operationalState, configurationState)\r
-        ].toList()\r
+        HashSet<P> paths) {
+        return withLock(registrationLock) [|\r
+            return FluentIterable.from(listeners.asMap.entrySet).filter[key.isAffectedBy(paths)].transform [\r
+                val operationalState = readOperationalData(key)\r
+                val configurationState = readConfigurationData(key)\r
+                return new ListenerStateCapture(key, value, operationalState, configurationState)\r
+            ].toList()
+        ]\r
     }\r
 \r
     protected def boolean isAffectedBy(P key, Set<P> paths) {\r
@@ -267,12 +292,13 @@ package class TwoPhaseCommit<P extends Path<P>, D, DCL extends DataChangeListene
         affectedPaths.addAll(transaction.createdOperationalData.keySet);\r
         affectedPaths.addAll(transaction.updatedOperationalData.keySet);\r
         affectedPaths.addAll(transaction.removedOperationalData);\r
-\r
+
         val listeners = dataBroker.affectedListenersWithInitialState(affectedPaths);\r
 \r
         val transactionId = transaction.identifier;\r
 \r
         log.trace("Transaction: {} Started.",transactionId);\r
+        log.trace("Transaction: {} Affected Subtrees:",transactionId,affectedPaths);
         // requesting commits\r
         val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.affectedCommitHandlers(affectedPaths);\r
         val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();\r
@@ -283,6 +309,7 @@ package class TwoPhaseCommit<P extends Path<P>, D, DCL extends DataChangeListene
         } catch (Exception e) {\r
             log.error("Transaction: {} Request Commit failed", transactionId,e);\r
             dataBroker.failedTransactionsCount.andIncrement\r
+            transaction.changeStatus(TransactionStatus.FAILED)
             return rollback(handlerTransactions, e);\r
         }\r
         val List<RpcResult<Void>> results = new ArrayList();\r
@@ -293,11 +320,13 @@ package class TwoPhaseCommit<P extends Path<P>, D, DCL extends DataChangeListene
             listeners.publishDataChangeEvent();\r
         } catch (Exception e) {\r
             log.error("Transaction: {} Finish Commit failed",transactionId, e);\r
-            dataBroker.failedTransactionsCount.andIncrement\r
+            dataBroker.failedTransactionsCount.andIncrement
+            transaction.changeStatus(TransactionStatus.FAILED)\r
             return rollback(handlerTransactions, e);\r
         }\r
         log.trace("Transaction: {} Finished successfully.",transactionId);\r
-        dataBroker.finishedTransactionsCount.andIncrement;\r
+        dataBroker.finishedTransactionsCount.andIncrement;
+        transaction.changeStatus(TransactionStatus.COMMITED)\r
         return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());\r
 \r
     }\r
index 098cd922ed268e59f5c424541716d2125b48bf78..023f906a67e90f495ae610ff0190687ecab54462 100644 (file)
@@ -44,7 +44,6 @@ class MountPointManagerImpl implements MountProvisionService {
     def registerMountPoint(MountPointImpl impl) {
         //dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
         //dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
-        
     }
     
     override registerProvisionListener(MountProvisionListener listener) {
index 763407f23a671476c7f47a9c8f7e3d63e0b2b128..0b184fc86ec0720193210bd8b0a997235caddca8 100644 (file)
@@ -40,14 +40,15 @@ public class NotificationRouterImpl implements NotificationRouter {
     private static Logger log = LoggerFactory.getLogger(NotificationRouterImpl.class);
 
     private Multimap<QName, Registration<NotificationListener>> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.<QName, Registration<NotificationListener>>create());
-
+//    private Registration<NotificationListener> defaultListener;
+    
     private void sendNotification(CompositeNode notification) {
-        QName type = notification.getNodeType();
-        Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
+        final QName type = notification.getNodeType();
+        final Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
         log.trace("Publishing notification " + type);
 
-        if (toNotify == null) {
-            // No listeners were registered - returns.
+        if ((toNotify == null) || toNotify.isEmpty()) {
+            log.debug("No listener registered for handling of notification {}", type);
             return;
         }
 
@@ -59,17 +60,17 @@ public class NotificationRouterImpl implements NotificationRouter {
                 log.error("Uncaught exception in NotificationListener", e);
             }
         }
-
     }
 
     @Override
     public void publish(CompositeNode notification) {
         sendNotification(notification);
     }
-
+    
     @Override
     public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
         ListenerRegistration ret = new ListenerRegistration(notification, listener);
+        listeners.put(notification, ret);
         return ret;
     }
 
index 87cbf13ea0fe2c3db0dffab3435a8566c5bd345e..69fe4aa1904e57ac83512400eaf6a3688a8da3ea 100644 (file)
@@ -78,17 +78,11 @@ class NetconfDeviceListener extends NetconfClientSessionListener {
      */
     public void onNotification(final NetconfClientSession session, final NetconfMessage message) {
         this.device.logger.debug("Received NETCONF notification.", message);
-        CompositeNode _notificationBody = null;
-        CompositeNode _compositeNode = null;
+        CompositeNode domNotification = null;
         if (message != null) {
-            _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext());
+            domNotification = NetconfMapping.toNotificationNode(message, device.getSchemaContext());
         }
-        if (_compositeNode != null) {
-            _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode);
-        }
-        final CompositeNode domNotification = _notificationBody;
-        boolean _notEquals = (!Objects.equal(domNotification, null));
-        if (_notEquals) {
+        if (domNotification != null) {
             MountProvisionInstance _mountInstance = null;
             if (this.device != null) {
                 _mountInstance = this.device.getMountInstance();
index 965df60cfb5f7ae8e6b5fa0823cf22977367eb58..76a5506df3f163a2c0ccab2f1515102c6a9b58bb 100644 (file)
@@ -33,6 +33,8 @@ import com.google.common.base.Preconditions
 import com.google.common.base.Optional
 import org.opendaylight.yangtools.yang.model.api.SchemaContext
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import java.util.Set
 
 class NetconfMapping {
 
@@ -103,7 +105,19 @@ class NetconfMapping {
     }
 
     static def CompositeNode toCompositeNode(NetconfMessage message,Optional<SchemaContext> ctx) {
-        return null//message.toRpcResult().result;
+        //TODO: implement general normalization to normalize incoming Netconf Message 
+        // for Schema Context counterpart
+        return null
+    }
+    
+    static def CompositeNode toNotificationNode(NetconfMessage message,Optional<SchemaContext> ctx) {
+        if (ctx.present) {
+            val schemaContext = ctx.get
+            val notifications = schemaContext.notifications
+            val document = message.document
+            return XmlDocumentUtils.notificationToDomNodes(document, Optional.<Set<NotificationDefinition>>fromNullable(notifications))
+        }
+        return null
     }
 
     static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional<SchemaContext> ctx) {
@@ -134,11 +148,11 @@ class NetconfMapping {
             if(isDataRetrievalReply(rpc)) {
                 
                 val xmlData = message.document.dataSubtree
-                val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions))
+                val dataNodes = XmlDocumentUtils.toDomNodes(xmlData, Optional.of(context.get.dataDefinitions))
                 
                 val it = ImmutableCompositeNode.builder()
                 setQName(NETCONF_RPC_REPLY_QNAME)
-                add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes));
+                add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME, dataNodes));
                 
                 rawRpc = it.toInstance;
                 //sys(xmlData)
index 357b599ec75917bb7f4e9cbc91fe458c8fec8845..226eff44e133a7ad311253740d6d77ea28a1d411 100644 (file)
@@ -134,7 +134,7 @@ class JsonMapper {
 
     private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
-            if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
+            if (node.getNodeType().equals(dsn.getQName())) {
                 return dsn;
             } else if (dsn instanceof ChoiceNode) {
                 for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
@@ -252,14 +252,18 @@ class JsonMapper {
             result.append("/");
 
             writeModuleNameAndIdentifier(result, identityValue);
-            if (identityValue.getPredicates() != null) {
+            if (identityValue.getPredicates() != null && !identityValue.getPredicates().isEmpty()) {
                 for (Predicate predicate : identityValue.getPredicates()) {
                     IdentityValue identityValuePredicate = predicate.getName();
                     result.append("[");
-                    writeModuleNameAndIdentifier(result, identityValuePredicate);
-                    result.append("=\"");
+                    if (identityValuePredicate == null) {
+                        result.append(".");
+                    } else {
+                        writeModuleNameAndIdentifier(result, identityValuePredicate);
+                    }
+                    result.append("='");
                     result.append(predicate.getValue());
-                    result.append("\"");
+                    result.append("'");
                     result.append("]");
                 }
             }
@@ -300,10 +304,16 @@ class JsonMapper {
         String nameForOutput = node.getNodeType().getLocalName();
         if (schema.isAugmenting()) {
             ControllerContext contContext = ControllerContext.getInstance();
-            CharSequence moduleName;
-            moduleName = contContext.toRestconfIdentifier(schema.getQName());
+            CharSequence moduleName = null;
+            if (mountPoint == null) {
+                moduleName = contContext.toRestconfIdentifier(schema.getQName());
+            } else {
+                moduleName = contContext.toRestconfIdentifier(mountPoint, schema.getQName());
+            }
             if (moduleName != null) {
                 nameForOutput = moduleName.toString();
+            } else {
+                logger.info("Module '{}' was not found in schema from mount point", schema.getQName());
             }
         }
         writer.name(nameForOutput);
index 7d32194b1f386ca1a7e228ea25de24dbf6dc15e1..2dfe5062c89af5b2f0151dfee3721d0ba7486521 100644 (file)
@@ -216,13 +216,20 @@ class ControllerContext implements SchemaServiceListener {
         var module = uriToModuleName.get(qname.namespace)
         if (module === null) {
             val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
-            if(moduleSchema === null) throw new IllegalArgumentException()
+            if(moduleSchema === null) return null
             uriToModuleName.put(qname.namespace, moduleSchema.name)
             module = moduleSchema.name;
         }
         return '''«module»:«qname.localName»''';
     }
 
+    def CharSequence toRestconfIdentifier(MountInstance mountPoint, QName qname) {
+        val moduleSchema = mountPoint?.schemaContext.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
+        if(moduleSchema === null) return null
+        val module = moduleSchema.name;
+        return '''«module»:«qname.localName»''';
+    }
+
     private static dispatch def DataSchemaNode childByQName(ChoiceNode container, QName name) {
         for (caze : container.cases) {
             val ret = caze.childByQName(name)
index 4f643fe34d02461a00a71ceef4f53da24670e75c..d6b530039eb681cf831956b9e61a83aad106ac64 100644 (file)
@@ -212,6 +212,11 @@ public class RestCodec {
                     List<Predicate> predicates = keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument)
                             .getKeyValues());
                     identityValue.setPredicates(predicates);
+                } else if (pathArgument instanceof NodeWithValue && identityValue != null) {
+                    List<Predicate> predicates = new ArrayList<>();
+                    String value = String.valueOf(((NodeWithValue) pathArgument).getValue());
+                    predicates.add(new Predicate(null, value));
+                    identityValue.setPredicates(predicates);
                 }
                 identityValuesDTO.add(identityValue);
             }
index f3612969b92b2a95fd97be226aa1b30b43794c0d..318159063ab481454298b738d3fc8ceb18b7fdff 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Set;
 import javax.ws.rs.WebApplicationException;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
@@ -51,6 +52,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
      * Test of json output when as input are specified composite node with empty
      * data + YANG file
      */
+    @Ignore
     @Test
     public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
         CompositeNode compositeNode = prepareCompositeNodeWithEmpties();
index d664001d8c42cba422cb44c0864271a1ce2a7be3..392f444cf2def8ae783c4dba0fa95b0d740746d3 100644 (file)
@@ -17,6 +17,7 @@ import java.util.regex.Pattern;
 import javax.ws.rs.WebApplicationException;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
@@ -32,6 +33,7 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
         dataLoad("/cnsn-to-json/identityref", 2, "identityref-module", "cont");
     }
 
+    @Ignore
     @Test
     public void identityrefToJsonTest() {
         String json = null;
@@ -51,6 +53,7 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
         assertTrue(mtch.matches());
     }
 
+    @Ignore
     @Test
     public void identityrefToJsonWithoutQNameTest() {
         String json = null;
index baefd93d18ceec72c96449954525b9fd4da4062c..54664ae069a98e8ccc7dc120767e0e74dd570ec2 100644 (file)
@@ -18,6 +18,7 @@ import java.util.regex.Pattern;
 import javax.ws.rs.WebApplicationException;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
@@ -35,6 +36,7 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS
         dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
     }
 
+    @Ignore
     @Test
     public void dataFromSeveralModulesToJsonTest() throws WebApplicationException, IOException, URISyntaxException {
         SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
index 7da572f45cc8197215bce13cdaed92d8101631f7..9723af7671e41dc75fd5de5521bee3fa6606817a 100644 (file)
@@ -28,6 +28,7 @@ import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
@@ -57,6 +58,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
     }
 
+    @Ignore
     @Test
     public void saveCnSnToJson() throws WebApplicationException, IOException, URISyntaxException {
         CompositeNode cnSn = prepareCnSn();
index 19f25944b45f0ce34a94c9224ce4b107da4f467b..5f264abc2cb41cf68939ec323e54c7064707a515 100644 (file)
@@ -412,8 +412,6 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
                 cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key));
             }
             NodeStatisticsAger nsa = cache.get(notification.getId());
-            FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flowRule);
-            cache.get(notification.getId()).updateFlowStats(flowStatsEntry);
                 
             //Augment the data to the flow node
 
@@ -466,6 +464,11 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
                         flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
                         sucLogger.debug("Found matching flow in the datastore, augmenting statistics");
                         foundOriginalFlow = true;
+                        // Update entry with timestamp of latest response 
+                        flow.setKey(existingFlow.getKey());
+                        FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build());
+                        cache.get(notification.getId()).updateFlowStats(flowStatsEntry);
+
                         it.putOperationalData(flowRef, flowBuilder.build());
                         it.commit();
                     }
@@ -490,6 +493,12 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
                             flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
                             sucLogger.debug("Found matching unaccounted flow in the operational datastore, augmenting statistics");
                             foundOriginalFlow = true;
+                            
+                            // Update entry with timestamp of latest response 
+                            flow.setKey(existingFlow.getKey());
+                            FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build());
+                            cache.get(notification.getId()).updateFlowStats(flowStatsEntry);
+
                             it.putOperationalData(flowRef, flowBuilder.build());
                             it.commit();
                             break;
@@ -498,9 +507,9 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
                 }
             }
             if(!foundOriginalFlow){
-                long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"0"+Integer.toString(this.unaccountedFlowsCounter)));
+                String flowKey = "#UF$TABLE*"+Short.toString(tableId)+"*"+Integer.toString(this.unaccountedFlowsCounter);
                 this.unaccountedFlowsCounter++;
-                FlowKey newFlowKey = new FlowKey(new FlowId(Long.toString(flowKey)));
+                FlowKey newFlowKey = new FlowKey(new FlowId(flowKey));
                 InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
                         .augmentation(FlowCapableNode.class)
                         .child(Table.class, new TableKey(tableId))
@@ -508,6 +517,12 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
                 flowBuilder.setKey(newFlowKey);
                 flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
                 sucLogger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow",flowBuilder.build());
+                
+                // Update entry with timestamp of latest response 
+                flow.setKey(newFlowKey);
+                FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build());
+                cache.get(notification.getId()).updateFlowStats(flowStatsEntry);
+
                 it.putOperationalData(flowRef, flowBuilder.build());
                 it.commit();
             }
index e46b89ac2afe3fa2f46604f5a7f3fde2298181b3..6d79f3cb05cc7faf2469e3144fb6be44d9d21e81 100644 (file)
@@ -62,7 +62,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 public class Troubleshoot implements IDaylightWeb {
     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
     private static final List<String> flowStatsColumnNames = Arrays.asList("Node", "In Port",
-            "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
+            "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst","ToS Bits",
             "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
             "Time (s)", "Timeout (s)",
             "Priority");
@@ -229,6 +229,7 @@ public class Troubleshoot implements IDaylightWeb {
 
     private Map<String, String> convertPortsStatistics(
             NodeConnectorStatistics ncStats, String containerName) {
+
         Map<String, String> row = new HashMap<String, String>();
 
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
@@ -325,6 +326,12 @@ public class Troubleshoot implements IDaylightWeb {
         } else {
             row.put(MatchType.NW_DST.id(), "*");
         }
+        if (match.isPresent(MatchType.NW_TOS)) {
+            row.put(MatchType.NW_TOS.id(), ((Byte) flow.getMatch()
+                        .getField(MatchType.NW_TOS).getValue()).toString());
+        } else {
+            row.put(MatchType.NW_TOS.id(), "*");
+        }
         if (match.isPresent(MatchType.NW_PROTO)) {
             row.put(MatchType.NW_PROTO.id(),
                     IPProtocols.getProtocolName(((Byte) flow.getMatch()
index a8673b0031d7246bedcfb3285a90519694b48efb..4b5e51a0718377e449c799dd807cc2cf798992ec 100644 (file)
@@ -373,6 +373,11 @@ one.f.troubleshooting.existingNodes = {
                             label: 'NW Dst',
                             sortable: true
                         },
+                        {
+                            property: 'nwTOS',
+                            label: 'ToS Bits',
+                            sortable: true
+                        },
                         {
                             property: 'nwProto',
                             label: 'NW Proto',
@@ -437,6 +442,7 @@ one.f.troubleshooting.existingNodes = {
                     entry.push(value["dlVlan"]);
                     entry.push(value["nwSrc"]);
                     entry.push(value["nwDst"]);
+                    entry.push(value["nwTOS"]);
                     entry.push(value["nwProto"]);
                     entry.push(value["tpSrc"]);
                     entry.push(value["tpDst"]);