Merge "TCP_Flag extension model additions for OFPXMC_NXM_1 class"
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / sal / binding / impl / NotificationBrokerImpl.java
1 /**
2  * Copyright (c) 2013 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.sal.binding.impl;
9
10 import java.util.Set;
11 import java.util.concurrent.ExecutorService;
12
13 import org.opendaylight.controller.sal.binding.api.NotificationListener;
14 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
15 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
16 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker;
17 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
18 import org.opendaylight.yangtools.concepts.ListenerRegistration;
19 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
20 import org.opendaylight.yangtools.yang.binding.Notification;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import com.google.common.base.Preconditions;
25
26 public class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {
27     private static final Logger LOG = LoggerFactory.getLogger(NotificationBrokerImpl.class);
28
29     private final ListenerRegistry<NotificationInterestListener> interestListeners =
30             ListenerRegistry.create();
31     private final GenerationalListenerMap listeners = new GenerationalListenerMap();
32     private final ExecutorService executor;
33
34     public NotificationBrokerImpl(final ExecutorService executor) {
35         this.executor = Preconditions.checkNotNull(executor);
36     }
37
38     @Override
39     public void publish(final Notification notification) {
40         publish(notification, executor);
41     }
42
43     @Override
44     public void publish(final Notification notification, final ExecutorService service) {
45         for (NotificationListenerRegistration<?> r : listeners.listenersFor(notification)) {
46             service.submit(new NotifyTask(r, notification));
47         }
48     }
49
50     private final void addRegistrations(final NotificationListenerRegistration<?>... registrations) {
51         listeners.addRegistrations(registrations);
52         for (NotificationListenerRegistration<?> reg : registrations) {
53             announceNotificationSubscription(reg.getType());
54         }
55     }
56
57     private void announceNotificationSubscription(final Class<? extends Notification> notification) {
58         for (final ListenerRegistration<NotificationInterestListener> listener : interestListeners) {
59             try {
60                 listener.getInstance().onNotificationSubscribtion(notification);
61             } catch (Exception e) {
62                 LOG.warn("Listener {} reported unexpected error on notification {}",
63                         listener.getInstance(), notification, e);
64             }
65         }
66     }
67
68     @Override
69     public ListenerRegistration<NotificationInterestListener> registerInterestListener(final NotificationInterestListener interestListener) {
70         final ListenerRegistration<NotificationInterestListener> registration = this.interestListeners.register(interestListener);
71         for (final Class<? extends Notification> notification : listeners.getKnownTypes()) {
72             interestListener.onNotificationSubscribtion(notification);
73         }
74         return registration;
75     }
76
77     @Override
78     public <T extends Notification> NotificationListenerRegistration<T> registerNotificationListener(final Class<T> notificationType, final NotificationListener<T> listener) {
79         final NotificationListenerRegistration<T> reg = new AbstractNotificationListenerRegistration<T>(notificationType, listener) {
80             @Override
81             protected void removeRegistration() {
82                 listeners.removeRegistrations(this);
83             }
84         };
85
86         addRegistrations(reg);
87         return reg;
88     }
89
90     @Override
91     public ListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(final org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
92         final NotificationInvoker invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener);
93         final Set<Class<? extends Notification>> types = invoker.getSupportedNotifications();
94         final NotificationListenerRegistration<?>[] regs = new NotificationListenerRegistration<?>[types.size()];
95
96         // Populate the registrations...
97         int i = 0;
98         for (Class<? extends Notification> type : types) {
99             regs[i] = new AggregatedNotificationListenerRegistration<Notification, Object>(type, invoker.getInvocationProxy(), regs) {
100                 @Override
101                 protected void removeRegistration() {
102                     // Nothing to do, will be cleaned up by parent (below)
103                 }
104             };
105             ++i;
106         }
107
108         // ... now put them to use ...
109         addRegistrations(regs);
110
111         // ... finally return the parent registration
112         return new AbstractListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener>(listener) {
113             @Override
114             protected void removeRegistration() {
115                 listeners.removeRegistrations(regs);
116                 for (ListenerRegistration<?> reg : regs) {
117                     reg.close();
118                 }
119             }
120         };
121     }
122
123     @Override
124     public void close() {
125     }
126
127 }