-/*
- * 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