Added Google Guava as dependency. Replaced Map<K,List<V> for SAL listeners. 98/98/1
authorTony Tkacik <ttkacik@cisco.com>
Wed, 3 Apr 2013 08:51:04 +0000 (10:51 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Wed, 3 Apr 2013 09:39:42 +0000 (11:39 +0200)
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
opendaylight/sal/yang-prototype/sal/pom.xml
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BrokerUtils.java [deleted file]
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationModule.java
opendaylight/sal/yang-prototype/sal/sal-broker-impl/pom.xml
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/BrokerImpl.java
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/Utils.java [deleted file]
opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/notify/NotificationModule.java

index 2c494e6bb94704ff73753ad047d9e59f0e241574..1b633b4a25ae78f1cb32710a3c9590921e987fb2 100644 (file)
                <module>sal-core-demo</module>\r
        </modules>\r
 \r
                <module>sal-core-demo</module>\r
        </modules>\r
 \r
-       <dependencies>\r
+       <dependencyManagement>\r
+               <dependencies>\r
+                       <dependency>\r
+                               <groupId>com.google.guava</groupId>\r
+                               <artifactId>guava</artifactId>\r
+                               <version>14.0.1</version>\r
+                               <type>jar</type>\r
+                       </dependency>\r
+                       <dependency>\r
+                               <groupId>org.slf4j</groupId>\r
+                               <artifactId>slf4j-api</artifactId>\r
+                               <version>1.7.2</version>\r
+                       </dependency>\r
+               </dependencies>\r
+       </dependencyManagement>\r
 \r
 \r
+       <dependencies>\r
                <dependency>\r
                        <groupId>junit</groupId>\r
                        <artifactId>junit</artifactId>\r
                <dependency>\r
                        <groupId>junit</groupId>\r
                        <artifactId>junit</artifactId>\r
                        <optional>true</optional>\r
                </dependency>\r
                <dependency>\r
                        <optional>true</optional>\r
                </dependency>\r
                <dependency>\r
-                       <groupId>org.slf4j</groupId>\r
-                       <artifactId>slf4j-api</artifactId>\r
-                       <version>1.7.2</version>\r
-               </dependency>\r
-               <dependency>\r
-                       <groupId>org.slf4j</groupId>\r
-                       <artifactId>slf4j-simple</artifactId>\r
-                       <version>1.7.2</version>\r
+                       <groupId>org.mockito</groupId>\r
+                       <artifactId>mockito-all</artifactId>\r
+                       <version>1.9.5</version>\r
+                       <scope>test</scope>\r
                </dependency>\r
        </dependencies>\r
        <build>\r
                </dependency>\r
        </dependencies>\r
        <build>\r
index 9c5552edbd8278a88763eb251c34822889f6b3a5..f126744652b78f8a4b87cf14a3b8adf5852c0137 100644 (file)
@@ -1,35 +1,41 @@
-<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">\r
-  <modelVersion>4.0.0</modelVersion>\r
-  <parent>\r
-    <groupId>org.opendaylight.controller</groupId>\r
-    <artifactId>sal</artifactId>\r
-    <version>1.0-SNAPSHOT</version>\r
-  </parent>\r
-   <artifactId>sal-binding-broker-impl</artifactId>\r
-   \r
-   \r
-   \r
-   <dependencies>\r
-       <dependency>\r
-               <groupId>org.opendaylight.controller</groupId>\r
-               <artifactId>sal-binding-api</artifactId>\r
-               <version>1.0-SNAPSHOT</version>\r
-       </dependency>\r
-               <dependency>\r
-               <groupId>org.opendaylight.controller</groupId>\r
-               <artifactId>sal-binding-spi</artifactId>\r
-               <version>1.0-SNAPSHOT</version>\r
-       </dependency>\r
-       <dependency>\r
-               <groupId>org.opendaylight.controller</groupId>\r
-               <artifactId>sal-core-api</artifactId>\r
-               <version>1.0-SNAPSHOT</version>\r
-       </dependency>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <parent>\r
+               <groupId>org.opendaylight.controller</groupId>\r
+               <artifactId>sal</artifactId>\r
+               <version>1.0-SNAPSHOT</version>\r
+       </parent>\r
+       <artifactId>sal-binding-broker-impl</artifactId>\r
 \r
 \r
-       <dependency>\r
-               <groupId>org.slf4j</groupId>\r
-               <artifactId>slf4j-api</artifactId>\r
-               <version>1.6.4</version>\r
-       </dependency>\r
-   </dependencies>\r
+\r
+\r
+       <dependencies>\r
+               <dependency>\r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>sal-binding-api</artifactId>\r
+                       <version>1.0-SNAPSHOT</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>sal-binding-spi</artifactId>\r
+                       <version>1.0-SNAPSHOT</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.opendaylight.controller</groupId>\r
+                       <artifactId>sal-core-api</artifactId>\r
+                       <version>1.0-SNAPSHOT</version>\r
+               </dependency>\r
+\r
+               <dependency>\r
+                       <groupId>org.slf4j</groupId>\r
+                       <artifactId>slf4j-api</artifactId>\r
+               </dependency>\r
+\r
+               <dependency>\r
+                       <groupId>com.google.guava</groupId>\r
+                       <artifactId>guava</artifactId>\r
+                       <type>jar</type>\r
+               </dependency>\r
+       </dependencies>\r
 </project>
\ No newline at end of file
 </project>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BrokerUtils.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BrokerUtils.java
deleted file mode 100644 (file)
index e174559..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 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;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class BrokerUtils {
-    private BrokerUtils() {
-        
-    }
-    
-    
-    public static <K,V> void addToMap(Map<Class<? extends K>, List<V>> map, Class<? extends K> key, V value) {
-        List<V> list = map.get(key);
-        if (list == null) {
-            list = new ArrayList<V>();
-            map.put(key, list);
-        }
-        list.add(value);
-    }
-
-    public static <K,V> void removeFromMap(Map<Class<? extends K>, List<V>> map, Class<? extends K> key,
-            V value) {
-        List<V> list = map.get(key);
-        if (list == null) {
-            return;
-        }
-        list.remove(value);
-        if (list.isEmpty()) {
-            map.remove(key);
-        }
-    }
-}
index f029a2f9f4bdcb3ec872338b0a56323c5511dd43..89c44643edc1bb995f5f1f60cdd0ce5fcba8b9c3 100644 (file)
-/*
- * Copyright (c) 2013 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;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareService;
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerSession;
-import org.opendaylight.controller.sal.binding.spi.SALBindingModule;
-import org.opendaylight.controller.sal.binding.spi.Mapper;
-import org.opendaylight.controller.sal.binding.spi.MappingProvider;
-import org.opendaylight.controller.sal.binding.spi.MappingProvider.MappingExtensionFactory;
-
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.yang.binding.DataObject;
-import org.opendaylight.controller.yang.binding.Notification;
-import org.opendaylight.controller.yang.binding.NotificationListener;
-import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.data.api.CompositeNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NotificationModule implements SALBindingModule {
-
-    private ProviderSession biSession;
-    private org.opendaylight.controller.sal.core.api.notify.NotificationProviderService biNotifyService;
-    private BindingAwareBroker broker;
-    private MappingProvider mappingProvider;
-
-    private Map<Class<? extends Notification>, List<NotificationListener>> listeners = new HashMap<Class<? extends Notification>, List<NotificationListener>>();
-    private Set<QName> biNotifications = new HashSet<QName>();
-    private static final Logger log = LoggerFactory
-            .getLogger(NotificationModule.class);
-    private final BindingIndependentListener biListener = new BindingIndependentListener();
-
-    @Override
-    public Set<Class<? extends BindingAwareService>> getProvidedServices() {
-
-        Set<Class<? extends BindingAwareService>> ret = new HashSet<Class<? extends BindingAwareService>>();
-        ret.add(NotificationService.class);
-        ret.add(NotificationProviderService.class);
-        return ret;
-    }
-
-    @Override
-    public <T extends BindingAwareService> T getServiceForSession(
-            Class<T> service, ConsumerSession session) {
-        if (service == null)
-            throw new IllegalArgumentException("Service should not be null");
-        if (session == null)
-            throw new IllegalArgumentException("Session should not be null");
-
-        if (NotificationProviderSession.class.equals(service)) {
-            if (session instanceof org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderSession) {
-                @SuppressWarnings("unchecked")
-                T ret = (T) new NotificationProviderSession(session);
-                return ret;
-            } else {
-                throw new IllegalArgumentException(
-                        "NotificationProviderService is available only to ProviderSession");
-            }
-        }
-
-        if (NotificationService.class.equals(service)) {
-            @SuppressWarnings("unchecked")
-            T ret = (T) new NotificationSession(session);
-            return ret;
-        }
-        return null;
-    }
-
-    @Override
-    public Set<Class<? extends org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality>> getSupportedProviderFunctionality() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public void setBroker(BindingAwareBroker broker) {
-        this.broker = broker;
-    }
-
-    @Override
-    public void setMappingProvider(MappingProvider provider) {
-        this.mappingProvider = provider;
-    }
-
-    @Override
-    public void onBISessionAvailable(ProviderSession session) {
-        biSession = session;
-        if (biSession != null) {
-            biNotifyService = session
-                    .getService(org.opendaylight.controller.sal.core.api.notify.NotificationProviderService.class);
-        }
-    }
-
-    private void notify(Notification notification) {
-        notifyBindingIndependent(notification);
-        notifyBindingAware(notification);
-    }
-
-    private void notifyBindingAware(Notification notification) {
-        Class<? extends Notification> type = notification.getClass();
-        List<NotificationListener> toNotify = listeners.get(type);
-
-        // Invocation of notification on registered listeners
-        if (toNotify != null) {
-
-            // We get factory for Notification Invoker
-            MappingExtensionFactory<NotificationInvoker> invokerFactory = mappingProvider
-                    .getExtensionFactory(NotificationInvoker.class);
-
-            // We get generated invoker for NoficiationListener interface
-            // associated to Notification Type
-            NotificationInvoker invoker = invokerFactory.forClass(type);
-            for (NotificationListener listener : toNotify) {
-                try {
-                    // Invoker invokes the right method on subtype of
-                    // NotificationListener
-                    // associated to the type of notification
-                    invoker.notify(notification, listener);
-                } catch (Exception e) {
-
-                }
-            }
-        }
-    }
-
-    private void notifyBindingIndependent(Notification notification) {
-        Class<? extends Notification> type = notification.getClass();
-
-        if (biSession == null) {
-            return;
-        }
-        if (biSession.isClosed()) {
-            return;
-        }
-        if (biNotifyService == null) {
-            return;
-        }
-
-        // FIXME: Somehow we need to resolve this for class hierarchy.
-        // probably use type.getInterfaces()
-        Mapper<? extends Notification> mapper = mappingProvider.getMapper(type);
-        CompositeNode domNotification = mapper.domFromObject(notification);
-
-        biNotifyService.sendNotification(domNotification);
-    }
-
-    private void addBAListener(Class<? extends Notification> notificationType,
-            NotificationListener listener) {
-
-        BrokerUtils.addToMap(listeners, notificationType, listener);
-        Mapper<? extends Notification> mapper = mappingProvider
-                .getMapper(notificationType);
-        QName biType = mapper.getQName();
-        if (false == biNotifications.contains(biType)) {
-            // The listener is not registered for binding independent
-            // notification
-            biNotifications.add(biType);
-
-            if (biNotifyService != null) {
-                biNotifyService.addNotificationListener(biType, biListener);
-            }
-        }
-
-    }
-
-    private void removeBAListener(
-            Class<? extends Notification> notificationType,
-            NotificationListener listener) {
-        BrokerUtils.removeFromMap(listeners, notificationType, listener);
-    }
-
-    private class NotificationSession implements NotificationService {
-        private final ConsumerSession session;
-
-        public NotificationSession(ConsumerSession session) {
-            this.session = session;
-        }
-
-        private Map<Class<? extends Notification>, List<NotificationListener>> sessionListeners = new HashMap<Class<? extends Notification>, List<NotificationListener>>();
-
-        @Override
-        public void addNotificationListener(
-                Class<? extends Notification> notificationType,
-                NotificationListener listener) {
-
-            NotificationModule.this.addBAListener(notificationType, listener);
-            BrokerUtils.addToMap(sessionListeners, notificationType, listener);
-
-        }
-
-        @Override
-        public void removeNotificationListener(
-                Class<? extends Notification> notificationType,
-                NotificationListener listener) {
-            BrokerUtils.removeFromMap(sessionListeners, notificationType,
-                    listener);
-            NotificationModule.this
-                    .removeBAListener(notificationType, listener);
-        }
-
-    }
-
-    private class NotificationProviderSession extends NotificationSession
-            implements NotificationProviderService {
-
-        public NotificationProviderSession(ConsumerSession session) {
-            super(session);
-        }
-
-        @Override
-        public void notify(Notification notification) {
-            NotificationModule.this.notify(notification);
-        }
-
-    }
-
-    private class BindingIndependentListener
-            implements
-            org.opendaylight.controller.sal.core.api.notify.NotificationListener {
-
-        @Override
-        public Set<QName> getSupportedNotifications() {
-            return biNotifications;
-        }
-
-        @Override
-        public void onNotification(CompositeNode notification) {
-            NotificationModule.this
-                    .onBindingIndependentNotification(notification);
-        }
-
-    }
-
-    private void onBindingIndependentNotification(CompositeNode biNotification) {
-        QName biType = biNotification.getNodeType();
-
-        Mapper<DataObject> mapper = mappingProvider.getMapper(biType);
-        if (mapper == null) {
-            log.info("Received notification does not have a binding defined.");
-            return;
-        }
-        Class<DataObject> type = mapper.getDataObjectClass();
-
-        // We check if the received QName / type is really Notification
-        if (Notification.class.isAssignableFrom(type)) {
-            Notification notification = (Notification) mapper
-                    .objectFromDom(biNotification);
-            notifyBindingAware(notification);
-        } else {
-            // The generated type for this QName does not inherits from
-            // notification something went wrong - generated APIs and/or 
-            // provider sending notification
-            // which was incorectly described in the YANG schema.
-            log.error("Received notification " + biType
-                    + " is not binded as notification");
-        }
-
-    }
-}
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.sal.binding.impl;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;\r
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;\r
+import org.opendaylight.controller.sal.binding.api.NotificationService;\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerSession;\r
+import org.opendaylight.controller.sal.binding.spi.SALBindingModule;\r
+import org.opendaylight.controller.sal.binding.spi.Mapper;\r
+import org.opendaylight.controller.sal.binding.spi.MappingProvider;\r
+import org.opendaylight.controller.sal.binding.spi.MappingProvider.MappingExtensionFactory;\r
+\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
+import org.opendaylight.controller.yang.binding.DataObject;\r
+import org.opendaylight.controller.yang.binding.Notification;\r
+import org.opendaylight.controller.yang.binding.NotificationListener;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.collect.HashMultimap;\r
+import com.google.common.collect.Multimap;\r
+\r
+public class NotificationModule implements SALBindingModule {\r
+\r
+    private ProviderSession biSession;\r
+    private org.opendaylight.controller.sal.core.api.notify.NotificationProviderService biNotifyService;\r
+    private MappingProvider mappingProvider;\r
+\r
+    private Multimap<Class<? extends Notification>, NotificationListener> listeners = HashMultimap\r
+            .create();\r
+    private Set<QName> biNotifications = new HashSet<QName>();\r
+    private static final Logger log = LoggerFactory\r
+            .getLogger(NotificationModule.class);\r
+    private final BindingIndependentListener biListener = new BindingIndependentListener();\r
+    private BindingAwareBroker broker;\r
+\r
+    @Override\r
+    public Set<Class<? extends BindingAwareService>> getProvidedServices() {\r
+\r
+        Set<Class<? extends BindingAwareService>> ret = new HashSet<Class<? extends BindingAwareService>>();\r
+        ret.add(NotificationService.class);\r
+        ret.add(NotificationProviderService.class);\r
+        return ret;\r
+    }\r
+\r
+    @Override\r
+    public <T extends BindingAwareService> T getServiceForSession(\r
+            Class<T> service, ConsumerSession session) {\r
+        if (service == null)\r
+            throw new IllegalArgumentException("Service should not be null");\r
+        if (session == null)\r
+            throw new IllegalArgumentException("Session should not be null");\r
+\r
+        if (NotificationProviderSession.class.equals(service)) {\r
+            if (session instanceof org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderSession) {\r
+                @SuppressWarnings("unchecked")\r
+                T ret = (T) new NotificationProviderSession(session);\r
+                return ret;\r
+            } else {\r
+                throw new IllegalArgumentException(\r
+                        "NotificationProviderService is available only to ProviderSession");\r
+            }\r
+        }\r
+\r
+        if (NotificationService.class.equals(service)) {\r
+            @SuppressWarnings("unchecked")\r
+            T ret = (T) new NotificationSession(session);\r
+            return ret;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public Set<Class<? extends org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality>> getSupportedProviderFunctionality() {\r
+        return Collections.emptySet();\r
+    }\r
+\r
+    @Override\r
+    public void setBroker(BindingAwareBroker broker) {\r
+        this.broker = broker;\r
+    }\r
+\r
+    @Override\r
+    public void setMappingProvider(MappingProvider provider) {\r
+        this.mappingProvider = provider;\r
+    }\r
+\r
+    @Override\r
+    public void onBISessionAvailable(ProviderSession session) {\r
+        biSession = session;\r
+        if (biSession != null) {\r
+            biNotifyService = session\r
+                    .getService(org.opendaylight.controller.sal.core.api.notify.NotificationProviderService.class);\r
+        }\r
+    }\r
+\r
+    private void notify(Notification notification) {\r
+        notifyBindingIndependent(notification);\r
+        notifyBindingAware(notification);\r
+    }\r
+\r
+    private void notifyBindingAware(Notification notification) {\r
+        Class<? extends Notification> type = notification.getClass();\r
+        Collection<NotificationListener> toNotify = listeners.get(type);\r
+\r
+        // Invocation of notification on registered listeners\r
+        if (toNotify != null) {\r
+\r
+            // We get factory for Notification Invoker\r
+            MappingExtensionFactory<NotificationInvoker> invokerFactory = mappingProvider\r
+                    .getExtensionFactory(NotificationInvoker.class);\r
+\r
+            // We get generated invoker for NoficiationListener interface\r
+            // associated to Notification Type\r
+            NotificationInvoker invoker = invokerFactory.forClass(type);\r
+            for (NotificationListener listener : toNotify) {\r
+                try {\r
+                    // Invoker invokes the right method on subtype of\r
+                    // NotificationListener\r
+                    // associated to the type of notification\r
+                    invoker.notify(notification, listener);\r
+                } catch (Exception e) {\r
+\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    private void notifyBindingIndependent(Notification notification) {\r
+        Class<? extends Notification> type = notification.getClass();\r
+\r
+        if (biSession == null) {\r
+            return;\r
+        }\r
+        if (biSession.isClosed()) {\r
+            return;\r
+        }\r
+        if (biNotifyService == null) {\r
+            return;\r
+        }\r
+\r
+        // FIXME: Somehow we need to resolve this for class hierarchy.\r
+        // probably use type.getInterfaces()\r
+        Mapper<? extends Notification> mapper = mappingProvider\r
+                .mapperForClass(type);\r
+        CompositeNode domNotification = mapper.domFromObject(notification);\r
+\r
+        biNotifyService.sendNotification(domNotification);\r
+    }\r
+\r
+    private void addBAListener(Class<? extends Notification> notificationType,\r
+            NotificationListener listener) {\r
+\r
+        listeners.put(notificationType, listener);\r
+        Mapper<? extends Notification> mapper = mappingProvider\r
+                .mapperForClass(notificationType);\r
+        QName biType = mapper.getQName();\r
+        if (false == biNotifications.contains(biType)) {\r
+            // The listener is not registered for binding independent\r
+            // notification\r
+            biNotifications.add(biType);\r
+\r
+            if (biNotifyService != null) {\r
+                biNotifyService.addNotificationListener(biType, biListener);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    private void removeBAListener(\r
+            Class<? extends Notification> notificationType,\r
+            NotificationListener listener) {\r
+        listeners.remove(notificationType, listener);\r
+    }\r
+\r
+    private class NotificationSession implements NotificationService {\r
+        private final ConsumerSession session;\r
+        private Multimap<Class<? extends Notification>, NotificationListener> sessionListeners = HashMultimap\r
+                .create();\r
+\r
+        public NotificationSession(ConsumerSession session) {\r
+            this.session = session;\r
+        }\r
+\r
+        @Override\r
+        public void addNotificationListener(\r
+                Class<? extends Notification> notificationType,\r
+                NotificationListener listener) {\r
+\r
+            NotificationModule.this.addBAListener(notificationType, listener);\r
+            sessionListeners.put(notificationType, listener);\r
+\r
+        }\r
+\r
+        @Override\r
+        public void removeNotificationListener(\r
+                Class<? extends Notification> notificationType,\r
+                NotificationListener listener) {\r
+            sessionListeners.remove(notificationType, listener);\r
+            NotificationModule.this\r
+                    .removeBAListener(notificationType, listener);\r
+        }\r
+\r
+    }\r
+\r
+    private class NotificationProviderSession extends NotificationSession\r
+            implements NotificationProviderService {\r
+\r
+        public NotificationProviderSession(ConsumerSession session) {\r
+            super(session);\r
+        }\r
+\r
+        @Override\r
+        public void notify(Notification notification) {\r
+            NotificationModule.this.notify(notification);\r
+        }\r
+\r
+    }\r
+\r
+    private class BindingIndependentListener\r
+            implements\r
+            org.opendaylight.controller.sal.core.api.notify.NotificationListener {\r
+\r
+        @Override\r
+        public Set<QName> getSupportedNotifications() {\r
+            return biNotifications;\r
+        }\r
+\r
+        @Override\r
+        public void onNotification(CompositeNode notification) {\r
+            NotificationModule.this\r
+                    .onBindingIndependentNotification(notification);\r
+        }\r
+\r
+    }\r
+\r
+    private void onBindingIndependentNotification(CompositeNode biNotification) {\r
+        QName biType = biNotification.getNodeType();\r
+\r
+        Mapper<DataObject> mapper = mappingProvider.mapperForQName(biType);\r
+        if (mapper == null) {\r
+            log.info("Received notification does not have a binding defined.");\r
+            return;\r
+        }\r
+        Class<DataObject> type = mapper.getDataObjectClass();\r
+\r
+        // We check if the received QName / type is really Notification\r
+        if (Notification.class.isAssignableFrom(type)) {\r
+            Notification notification = (Notification) mapper\r
+                    .objectFromDom(biNotification);\r
+            notifyBindingAware(notification);\r
+        } else {\r
+            // The generated type for this QName does not inherits from\r
+            // notification something went wrong - generated APIs and/or\r
+            // provider sending notification\r
+            // which was incorectly described in the YANG schema.\r
+            log.error("Received notification " + biType\r
+                    + " is not binded as notification");\r
+        }\r
+\r
+    }\r
+}\r
index 131c00dc2ab30ae7264240931bf0ec566bda7c4e..d81c6ac2ff9ad30a523c6814bf06effea2563330 100644 (file)
                <dependency>\r
                        <groupId>org.slf4j</groupId>\r
                        <artifactId>slf4j-api</artifactId>\r
                <dependency>\r
                        <groupId>org.slf4j</groupId>\r
                        <artifactId>slf4j-api</artifactId>\r
-                       <version>1.6.4</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>com.google.guava</groupId>\r
+                       <artifactId>guava</artifactId>\r
+                       <type>jar</type>\r
                </dependency>\r
        </dependencies>
 </project>
\ No newline at end of file
                </dependency>\r
        </dependencies>
 </project>
\ No newline at end of file
index 97879fb969d9a96ede9e04c806f06798bd1e63ea..84bc0569504272704d3ea68605d42f6c13de0afe 100644 (file)
@@ -12,7 +12,6 @@ import java.util.HashMap;
 import java.util.HashSet;\r
 import java.util.Map;\r
 import java.util.Set;\r
 import java.util.HashSet;\r
 import java.util.Map;\r
 import java.util.Set;\r
-import java.util.concurrent.ExecutorService;\r
 import java.util.concurrent.Future;\r
 \r
 import org.opendaylight.controller.sal.core.api.Broker;\r
 import java.util.concurrent.Future;\r
 \r
 import org.opendaylight.controller.sal.core.api.Broker;\r
diff --git a/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/Utils.java b/opendaylight/sal/yang-prototype/sal/sal-broker-impl/src/main/java/org/opendaylight/controller/sal/core/impl/Utils.java
deleted file mode 100644 (file)
index 810049f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.controller.sal.core.impl;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.opendaylight.controller.yang.common.QName;\r
-\r
-\r
-public class Utils {\r
-\r
-    public static <T> void addToMap(Map<QName, List<T>> map, QName key, T value) {\r
-        List<T> list = map.get(key);\r
-        if (list == null) {\r
-            list = new ArrayList<T>();\r
-            map.put(key, list);\r
-        }\r
-        list.add(value);\r
-    }\r
-\r
-    public static <T> void removeFromMap(Map<QName, List<T>> map, QName key,\r
-            T value) {\r
-        List<T> list = map.get(key);\r
-        if (list == null) {\r
-            return;\r
-        }\r
-        list.remove(value);\r
-        if (list.isEmpty()) {\r
-            map.remove(key);\r
-        }\r
-    }\r
-}\r
-
index fd19e7e6bc2ef50bd8c787bcdee94a04be810189..8f9632be9e3a843a1d15f5b38c78640cbfe883e2 100644 (file)
@@ -7,10 +7,9 @@
  */\r
 package org.opendaylight.controller.sal.core.impl.notify;\r
 \r
  */\r
 package org.opendaylight.controller.sal.core.impl.notify;\r
 \r
+import java.util.Collection;\r
 import java.util.Collections;\r
 import java.util.Collections;\r
-import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.HashSet;\r
-import java.util.List;\r
 import java.util.Map;\r
 import java.util.Map.Entry;\r
 import java.util.Set;\r
 import java.util.Map;\r
 import java.util.Map.Entry;\r
 import java.util.Set;\r
@@ -24,28 +23,30 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.core.api.notify.NotificationProviderService;\r
 import org.opendaylight.controller.sal.core.api.notify.NotificationService;\r
 import org.opendaylight.controller.sal.core.impl.BrokerServiceImpl;\r
 import org.opendaylight.controller.sal.core.api.notify.NotificationProviderService;\r
 import org.opendaylight.controller.sal.core.api.notify.NotificationService;\r
 import org.opendaylight.controller.sal.core.impl.BrokerServiceImpl;\r
-import org.opendaylight.controller.sal.core.impl.Utils;\r
 import org.opendaylight.controller.sal.core.spi.BrokerModule;\r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
 import org.opendaylight.controller.sal.core.spi.BrokerModule;\r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
-\r
+import com.google.common.collect.HashMultimap;\r
+import com.google.common.collect.ImmutableSet;\r
+import com.google.common.collect.Multimap;\r
 \r
 public class NotificationModule implements BrokerModule {\r
     private static Logger log = LoggerFactory\r
             .getLogger(NotificationModule.class);\r
 \r
 \r
 public class NotificationModule implements BrokerModule {\r
     private static Logger log = LoggerFactory\r
             .getLogger(NotificationModule.class);\r
 \r
-    private Map<QName, List<NotificationListener>> listeners = new HashMap<QName, List<NotificationListener>>();\r
+    private Multimap<QName, NotificationListener> listeners = HashMultimap\r
+            .create();\r
+\r
+    private static final Set<Class<? extends BrokerService>> providedServices = ImmutableSet\r
+            .of((Class<? extends BrokerService>) NotificationService.class,\r
+                    NotificationProviderService.class);\r
 \r
     @Override\r
     public Set<Class<? extends BrokerService>> getProvidedServices() {\r
 \r
     @Override\r
     public Set<Class<? extends BrokerService>> getProvidedServices() {\r
-        // FIXME Refactor\r
-        Set<Class<? extends BrokerService>> ret = new HashSet<Class<? extends BrokerService>>();\r
-        ret.add(NotificationService.class);\r
-        ret.add(NotificationProviderService.class);\r
-        return ret;\r
+        return providedServices;\r
     }\r
 \r
     @Override\r
     }\r
 \r
     @Override\r
@@ -77,7 +78,7 @@ public class NotificationModule implements BrokerModule {
 \r
     private void sendNotification(CompositeNode notification) {\r
         QName type = notification.getNodeType();\r
 \r
     private void sendNotification(CompositeNode notification) {\r
         QName type = notification.getNodeType();\r
-        List<NotificationListener> toNotify = listeners.get(type);\r
+        Collection<NotificationListener> toNotify = listeners.get(type);\r
         log.info("Publishing notification " + type);\r
 \r
         if (toNotify == null) {\r
         log.info("Publishing notification " + type);\r
 \r
         if (toNotify == null) {\r
@@ -109,7 +110,8 @@ public class NotificationModule implements BrokerModule {
     private class NotificationConsumerSessionImpl extends BrokerServiceImpl\r
             implements NotificationService {\r
 \r
     private class NotificationConsumerSessionImpl extends BrokerServiceImpl\r
             implements NotificationService {\r
 \r
-        Map<QName, List<NotificationListener>> consumerListeners = new HashMap<QName, List<NotificationListener>>();\r
+        private Multimap<QName, NotificationListener> consumerListeners = HashMultimap\r
+                .create();\r
         private boolean closed = false;\r
 \r
         @Override\r
         private boolean closed = false;\r
 \r
         @Override\r
@@ -124,8 +126,8 @@ public class NotificationModule implements BrokerModule {
                 throw new IllegalArgumentException("Listener must not be null.");\r
             }\r
 \r
                 throw new IllegalArgumentException("Listener must not be null.");\r
             }\r
 \r
-            Utils.addToMap(consumerListeners, notification, listener);\r
-            Utils.addToMap(listeners, notification, listener);\r
+            consumerListeners.put(notification, listener);\r
+            listeners.put(notification, listener);\r
             log.info("Registered listener for notification: " + notification);\r
         }\r
 \r
             log.info("Registered listener for notification: " + notification);\r
         }\r
 \r
@@ -140,17 +142,18 @@ public class NotificationModule implements BrokerModule {
             if (listener == null) {\r
                 throw new IllegalArgumentException("Listener must not be null.");\r
             }\r
             if (listener == null) {\r
                 throw new IllegalArgumentException("Listener must not be null.");\r
             }\r
-            Utils.removeFromMap(consumerListeners, notification, listener);\r
-            Utils.removeFromMap(listeners, notification, listener);\r
+            consumerListeners.remove(notification, listener);\r
+            listeners.remove(notification, listener);\r
         }\r
 \r
         @Override\r
         public void closeSession() {\r
             closed = true;\r
         }\r
 \r
         @Override\r
         public void closeSession() {\r
             closed = true;\r
-            Set<Entry<QName, List<NotificationListener>>> toRemove = consumerListeners\r
-                    .entrySet();\r
-            for (Entry<QName, List<NotificationListener>> entry : toRemove) {\r
-                listeners.get(entry.getKey()).removeAll(entry.getValue());\r
+            Map<QName, Collection<NotificationListener>> toRemove = consumerListeners\r
+                    .asMap();\r
+            for (Entry<QName, Collection<NotificationListener>> entry : toRemove\r
+                    .entrySet()) {\r
+                listeners.remove(entry.getKey(), entry.getValue());\r
             }\r
         }\r
 \r
             }\r
         }\r
 \r
@@ -179,4 +182,3 @@ public class NotificationModule implements BrokerModule {
         return Collections.emptySet();\r
     }\r
 }\r
         return Collections.emptySet();\r
     }\r
 }\r
-