import org.opendaylight.netconf.mapping.api.SessionAwareNetconfOperation;
import org.opendaylight.netconf.notifications.NetconfNotificationListener;
import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
import org.opendaylight.netconf.util.messages.SubtreeFilter;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yangtools.concepts.Registration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
static final String CREATE_SUBSCRIPTION = "create-subscription";
private final NetconfNotificationRegistry notifications;
- private final List<NotificationListenerRegistration> subscriptions = new ArrayList<>();
+ private final List<Registration> subscriptions = new ArrayList<>();
private NetconfSession netconfSession;
public CreateSubscription(final String netconfSessionIdForReporting,
getNetconfSessionIdForReporting());
}
- final NotificationListenerRegistration notificationListenerRegistration = notifications
- .registerNotificationListener(streamNameType, new NotificationSubscription(netconfSession, filter));
- subscriptions.add(notificationListenerRegistration);
+ subscriptions.add(notifications.registerNotificationListener(streamNameType,
+ new NotificationSubscription(netconfSession, filter)));
return document.createElement(XmlNetconfConstants.OK);
}
public void close() {
netconfSession = null;
// Unregister from notification streams
- for (final NotificationListenerRegistration subscription : subscriptions) {
- subscription.close();
- }
+ subscriptions.forEach(Registration::close);
+ subscriptions.clear();
}
private static class NotificationSubscription implements NetconfNotificationListener {
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.PreDestroy;
import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
import org.opendaylight.netconf.notifications.NetconfNotificationListener;
import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
import org.opendaylight.netconf.notifications.NotificationPublisherRegistration;
import org.opendaylight.netconf.notifications.YangLibraryPublisherRegistration;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
// since the listeners/publishers can block the whole notification processing
@GuardedBy("this")
- private final Multimap<StreamNameType, GenericNotificationListenerReg> notificationListeners =
- HashMultimap.create();
+ private final Multimap<StreamNameType, ListenerReg> notificationListeners = HashMultimap.create();
@GuardedBy("this")
private final Set<StreamListenerReg> streamListeners = new HashSet<>();
@Override
public synchronized void close() {
// Unregister all listeners
- // Use new list to avoid ConcurrentModificationException
- for (final GenericNotificationListenerReg listenerReg : new ArrayList<>(notificationListeners.values())) {
- listenerReg.close();
- }
+ // Use new list to avoid ConcurrentModificationException when the registration removes itself
+ List.copyOf(notificationListeners.values()).forEach(ListenerReg::close);
notificationListeners.clear();
// Unregister all publishers
LOG.debug("Notification of type {} detected: {}", stream, notification);
}
- for (final GenericNotificationListenerReg listenerReg : notificationListeners.get(stream)) {
- listenerReg.getListener().onNotification(stream, notification);
+ for (var listenerReg : notificationListeners.get(stream)) {
+ listenerReg.getInstance().onNotification(stream, notification);
}
}
@Override
- public synchronized NotificationListenerRegistration registerNotificationListener(
- final StreamNameType stream,
+ public synchronized Registration registerNotificationListener(final StreamNameType stream,
final NetconfNotificationListener listener) {
- requireNonNull(stream);
- requireNonNull(listener);
-
+ final var reg = new ListenerReg(listener, stream);
LOG.trace("Notification listener registered for stream: {}", stream);
-
- final GenericNotificationListenerReg reg = new GenericNotificationListenerReg(listener, stream) {
- @Override
- public void close() {
- synchronized (NetconfNotificationManager.this) {
- LOG.trace("Notification listener unregistered for stream: {}", stream);
- super.close();
- }
- }
- };
-
notificationListeners.put(stream, reg);
return reg;
}
}
}
- private class GenericNotificationListenerReg implements NotificationListenerRegistration {
- private final NetconfNotificationListener listener;
- private final StreamNameType listenedStream;
+ private final class ListenerReg extends AbstractObjectRegistration<NetconfNotificationListener> {
+ private final StreamNameType stream;
- GenericNotificationListenerReg(final NetconfNotificationListener listener,
- final StreamNameType listenedStream) {
- this.listener = listener;
- this.listenedStream = listenedStream;
- }
-
- public NetconfNotificationListener getListener() {
- return listener;
+ ListenerReg(final @NonNull NetconfNotificationListener instance, final @NonNull StreamNameType stream) {
+ super(instance);
+ this.stream = requireNonNull(stream);
}
@Override
- public void close() {
- notificationListeners.remove(listenedStream, this);
+ protected void removeRegistration() {
+ synchronized (NetconfNotificationManager.this) {
+ LOG.trace("Notification listener unregistered for stream: {}", stream);
+ notificationListeners.remove(stream, this);
+ }
}
}
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.opendaylight.netconf.notifications.NetconfNotificationListener;
import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yangtools.concepts.Registration;
import org.w3c.dom.Element;
@RunWith(MockitoJUnitRunner.StrictStubs.class)
@Before
public void setUp() {
doReturn(true).when(notificationRegistry).isStreamAvailable(any(StreamNameType.class));
- doReturn(mock(NotificationListenerRegistration.class)).when(notificationRegistry)
+ doReturn(mock(Registration.class)).when(notificationRegistry)
.registerNotificationListener(any(StreamNameType.class), any(NetconfNotificationListener.class));
}
import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration;
import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
import org.opendaylight.netconf.notifications.NetconfNotificationListener;
-import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
doNothing().when(listener).onNotification(any(StreamNameType.class), any(NotificationMessage.class));
- final NotificationListenerRegistration notificationListenerRegistration = netconfNotificationManager
- .registerNotificationListener(NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener);
+
final NetconfCapabilityChange notification = capabilityChangedBuilder.build();
- baseNotificationPublisherRegistration.onCapabilityChanged(notification);
- verify(listener).onNotification(any(StreamNameType.class), any(NotificationMessage.class));
+ try (var reg = netconfNotificationManager.registerNotificationListener(
+ NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener)) {
+ baseNotificationPublisherRegistration.onCapabilityChanged(notification);
- notificationListenerRegistration.close();
+ verify(listener).onNotification(any(StreamNameType.class), any(NotificationMessage.class));
+ }
baseNotificationPublisherRegistration.onCapabilityChanged(notification);
verifyNoMoreInteractions(listener);
*/
package org.opendaylight.netconf.notifications;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+import org.opendaylight.yangtools.concepts.Registration;
public interface NetconfNotificationRegistry {
/**
* Add listener for a certain notification type.
*/
- NotificationListenerRegistration registerNotificationListener(StreamNameType stream,
- NetconfNotificationListener listener);
+ @NonNull Registration registerNotificationListener(@NonNull StreamNameType stream,
+ @NonNull NetconfNotificationListener listener);
/**
* Check stream availability.
+++ /dev/null
-/*
- * Copyright (c) 2015 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.netconf.notifications;
-
-/**
- * Manages the registration of a single listener.
- */
-public interface NotificationListenerRegistration extends NotificationRegistration {
-
-}