Deprecate old MD-SAL APIs for removal
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / compat / HeliumNotificationProviderServiceWithInterestListeners.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.md.sal.binding.compat;
9
10 import com.google.common.collect.Sets;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.util.Collections;
13 import java.util.Iterator;
14 import java.util.Set;
15 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
16 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationServiceAdapter;
17 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
18 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
19 import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListener;
20 import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListenerRegistry;
21 import org.opendaylight.controller.sal.binding.api.NotificationListener;
22 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
23 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
24 import org.opendaylight.yangtools.concepts.ListenerRegistration;
25 import org.opendaylight.yangtools.util.ListenerRegistry;
26 import org.opendaylight.yangtools.yang.binding.Notification;
27 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 @Deprecated(forRemoval = true)
32 public class HeliumNotificationProviderServiceWithInterestListeners extends HeliumNotificationProviderServiceAdapter {
33
34     private static final Logger LOG = LoggerFactory.getLogger(
35             HeliumNotificationProviderServiceWithInterestListeners.class);
36
37     private final ListenerRegistry<NotificationInterestListener> interestListeners = ListenerRegistry.create();
38     private final ListenerRegistration<Listener> domListener;
39     private final DOMNotificationService domService;
40     private final BindingToNormalizedNodeCodec codec;
41
42     public HeliumNotificationProviderServiceWithInterestListeners(
43             final BindingDOMNotificationPublishServiceAdapter publishService,
44             final BindingDOMNotificationServiceAdapter listenService,
45             final DOMNotificationSubscriptionListenerRegistry registry) {
46         super(publishService, listenService);
47         this.codec = publishService.getCodecRegistry();
48         this.domListener = registry.registerSubscriptionListener(new Listener());
49         this.domService = listenService.getDomService();
50     }
51
52     @Override
53     public ListenerRegistration<NotificationInterestListener> registerInterestListener(
54             final NotificationInterestListener listener) {
55         notifyListener(listener, translate(domListener.getInstance().getAllObserved()));
56         return interestListeners.register(listener);
57     }
58
59     private Set<Class<? extends Notification>> translate(final Set<SchemaPath> added) {
60         return codec.getNotificationClasses(added);
61     }
62
63     @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
64             justification = "https://github.com/spotbugs/spotbugs/issues/811")
65     @SuppressWarnings("checkstyle:IllegalCatch")
66     private void notifyAllListeners(final Set<SchemaPath> added) {
67         final Iterator<? extends ListenerRegistration<? extends NotificationInterestListener>> listeners =
68                 interestListeners.getRegistrations().iterator();
69         if (listeners.hasNext()) {
70             final Set<Class<? extends Notification>> baEvent = translate(added);
71             while (listeners.hasNext()) {
72                 final NotificationInterestListener listenerRef = listeners.next().getInstance();
73                 try {
74                     notifyListener(listenerRef, baEvent);
75                 } catch (RuntimeException  e) {
76                     LOG.warn("Unhandled exception during invoking listener {}", listenerRef, e);
77                 }
78             }
79         }
80     }
81
82     @Override
83     public <T extends Notification> ListenerRegistration<NotificationListener<T>> registerNotificationListener(
84             final Class<T> type, final NotificationListener<T> listener) {
85
86         final FunctionalNotificationListenerAdapter<T> adapter =
87                 new FunctionalNotificationListenerAdapter<>(codec, type, listener);
88         final SchemaPath domType = SchemaPath.create(true, BindingReflections.findQName(type));
89         final ListenerRegistration<?> domReg = domService.registerNotificationListener(adapter, domType);
90         return new AbstractListenerRegistration<NotificationListener<T>>(listener) {
91             @Override
92             protected void removeRegistration() {
93                 domReg.close();
94             }
95         };
96     }
97
98     private static void notifyListener(final NotificationInterestListener listener,
99             final Set<Class<? extends Notification>> baEvent) {
100         for (final Class<? extends Notification> event: baEvent) {
101             listener.onNotificationSubscribtion(event);
102         }
103     }
104
105     private final class Listener implements DOMNotificationSubscriptionListener {
106
107         private volatile Set<SchemaPath> allObserved = Collections.emptySet();
108
109         @Override
110         public void onSubscriptionChanged(final Set<SchemaPath> currentTypes) {
111             final Set<SchemaPath> added = Sets.difference(currentTypes, allObserved).immutableCopy();
112             notifyAllListeners(added);
113             allObserved = Sets.union(allObserved, added).immutableCopy();
114         }
115
116         Set<SchemaPath> getAllObserved() {
117             return allObserved;
118         }
119     }
120
121     @Override
122     public void close() {
123         super.close();
124         domListener.close();
125     }
126 }