639997d404edc1c5fb5bed2e911bbff0b401c077
[netconf.git] /
1 /*
2  * Copyright (c) 2022 Opendaylight, 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.restconf.nb.rfc8040.streams;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.Set;
13 import org.eclipse.jdt.annotation.NonNull;
14 import org.opendaylight.mdsal.dom.api.DOMMountPointListener;
15 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
16 import org.opendaylight.mdsal.dom.api.DOMNotificationService;
17 import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
18 import org.opendaylight.yangtools.concepts.ListenerRegistration;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
21 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * {@link DeviceNotificationListenerAdaptor} is responsible to track events on notifications.
27  */
28 public final class DeviceNotificationListenerAdaptor extends AbstractNotificationListenerAdaptor
29         implements DOMMountPointListener {
30     private static final Logger LOG = LoggerFactory.getLogger(DeviceNotificationListenerAdaptor.class);
31
32     private final @NonNull EffectiveModelContext effectiveModel;
33     private final @NonNull DOMMountPointService mountPointService;
34     private final @NonNull YangInstanceIdentifier instanceIdentifier;
35
36     private ListenerRegistration<DOMMountPointListener> reg;
37
38     DeviceNotificationListenerAdaptor(final String streamName, final NotificationOutputType outputType,
39             final ListenersBroker listenersBroker, final EffectiveModelContext effectiveModel,
40             final DOMMountPointService mountPointService, final YangInstanceIdentifier instanceIdentifier) {
41         super(streamName, outputType, listenersBroker);
42         this.effectiveModel = requireNonNull(effectiveModel);
43         this.mountPointService = requireNonNull(mountPointService);
44         this.instanceIdentifier = requireNonNull(instanceIdentifier);
45     }
46
47     public synchronized void listen(final DOMNotificationService notificationService, final Set<Absolute> paths) {
48         if (!isListening()) {
49             setRegistration(notificationService.registerNotificationListener(this, paths));
50             reg = mountPointService.registerProvisionListener(this);
51         }
52     }
53
54     private synchronized void resetListenerRegistration() {
55         if (reg != null) {
56             reg.close();
57             reg = null;
58         }
59     }
60
61     @Override
62     EffectiveModelContext effectiveModel() {
63         return effectiveModel;
64     }
65
66     @Override
67     public void onMountPointCreated(final YangInstanceIdentifier path) {
68         // No-op
69     }
70
71     @Override
72     public void onMountPointRemoved(final YangInstanceIdentifier path) {
73         if (instanceIdentifier.equals(path)) {
74             getSubscribers().forEach(subscriber -> {
75                 if (subscriber.isConnected()) {
76                     subscriber.sendDataMessage("Device disconnected");
77                 }
78                 if (subscriber instanceof SSESessionHandler sseSessionHandler) {
79                     try {
80                         sseSessionHandler.close();
81                     } catch (IllegalStateException e) {
82                         LOG.warn("Ignoring exception while closing sse session");
83                     }
84                 }
85             });
86             listenersBroker.removeAndCloseDeviceNotificationListener(this);
87             resetListenerRegistration();
88         }
89     }
90 }