2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.md.sal.binding.compat;
10 import com.google.common.collect.Sets;
11 import java.util.Collections;
12 import java.util.Iterator;
14 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
15 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationServiceAdapter;
16 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
17 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
18 import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListener;
19 import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListenerRegistry;
20 import org.opendaylight.controller.sal.binding.api.NotificationListener;
21 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
22 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
23 import org.opendaylight.yangtools.concepts.ListenerRegistration;
24 import org.opendaylight.yangtools.util.ListenerRegistry;
25 import org.opendaylight.yangtools.yang.binding.Notification;
26 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 public class HeliumNotificationProviderServiceWithInterestListeners extends HeliumNotificationProviderServiceAdapter {
32 private static final Logger LOG = LoggerFactory.getLogger(
33 HeliumNotificationProviderServiceWithInterestListeners.class);
35 private final ListenerRegistry<NotificationInterestListener> interestListeners = ListenerRegistry.create();
36 private final ListenerRegistration<Listener> domListener;
37 private final DOMNotificationService domService;
38 private final BindingToNormalizedNodeCodec codec;
40 public HeliumNotificationProviderServiceWithInterestListeners(
41 final BindingDOMNotificationPublishServiceAdapter publishService,
42 final BindingDOMNotificationServiceAdapter listenService,
43 final DOMNotificationSubscriptionListenerRegistry registry) {
44 super(publishService, listenService);
45 this.codec = publishService.getCodecRegistry();
46 this.domListener = registry.registerSubscriptionListener(new Listener());
47 this.domService = listenService.getDomService();
51 public ListenerRegistration<NotificationInterestListener> registerInterestListener(
52 final NotificationInterestListener listener) {
53 notifyListener(listener, translate(domListener.getInstance().getAllObserved()));
54 return interestListeners.register(listener);
57 private Set<Class<? extends Notification>> translate(final Set<SchemaPath> added) {
58 return codec.getNotificationClasses(added);
61 @SuppressWarnings("checkstyle:IllegalCatch")
62 private void notifyAllListeners(final Set<SchemaPath> added) {
63 final Iterator<? extends ListenerRegistration<? extends NotificationInterestListener>> listeners =
64 interestListeners.getRegistrations().iterator();
65 if (listeners.hasNext()) {
66 final Set<Class<? extends Notification>> baEvent = translate(added);
67 while (listeners.hasNext()) {
68 final NotificationInterestListener listenerRef = listeners.next().getInstance();
70 notifyListener(listenerRef, baEvent);
71 } catch (RuntimeException e) {
72 LOG.warn("Unhandled exception during invoking listener {}", listenerRef, e);
79 public <T extends Notification> ListenerRegistration<NotificationListener<T>> registerNotificationListener(
80 final Class<T> type, final NotificationListener<T> listener) {
82 final FunctionalNotificationListenerAdapter<T> adapter =
83 new FunctionalNotificationListenerAdapter<>(codec, type, listener);
84 final SchemaPath domType = SchemaPath.create(true, BindingReflections.findQName(type));
85 final ListenerRegistration<?> domReg = domService.registerNotificationListener(adapter, domType);
86 return new AbstractListenerRegistration<NotificationListener<T>>(listener) {
88 protected void removeRegistration() {
94 private static void notifyListener(final NotificationInterestListener listener,
95 final Set<Class<? extends Notification>> baEvent) {
96 for (final Class<? extends Notification> event: baEvent) {
97 listener.onNotificationSubscribtion(event);
101 private final class Listener implements DOMNotificationSubscriptionListener {
103 private volatile Set<SchemaPath> allObserved = Collections.emptySet();
106 public void onSubscriptionChanged(final Set<SchemaPath> currentTypes) {
107 final Set<SchemaPath> added = Sets.difference(currentTypes, allObserved).immutableCopy();
108 notifyAllListeners(added);
109 allObserved = Sets.union(allObserved, added).immutableCopy();
112 Set<SchemaPath> getAllObserved() {
118 public void close() {