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