Merge "Do not override jsr305 version"
[controller.git] / opendaylight / md-sal / messagebus-impl / src / main / java / org / opendaylight / controller / messagebus / app / impl / EventSourceManager.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
9 package org.opendaylight.controller.messagebus.app.impl;
10
11 import org.opendaylight.controller.config.yang.messagebus.app.impl.NamespaceToStream;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
14 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.mdsal.DataStore;
17 import org.opendaylight.controller.mdsal.MdSAL;
18 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.EventSourceService;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNode;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 public final class EventSourceManager implements DataChangeListener {
32     private static final Logger LOGGER = LoggerFactory.getLogger(EventSourceManager.class);
33     private static final InstanceIdentifier<Node> INVENTORY_PATH = InstanceIdentifier.create(Nodes.class)
34                                                                                      .child(Node.class);
35     private final DataStore dataStore;
36     private final MdSAL mdSal;
37     private final EventSourceTopology eventSourceTopology;
38     private final Map<String, String> streamMap;
39
40     public EventSourceManager(DataStore dataStore,
41                               MdSAL mdSal,
42                               EventSourceTopology eventSourceTopology,
43                               List<NamespaceToStream> namespaceMapping) {
44         this.dataStore = dataStore;
45         this.mdSal = mdSal;
46         this.eventSourceTopology = eventSourceTopology;
47         this.streamMap = namespaceToStreamMapping(namespaceMapping);
48     }
49
50     private Map namespaceToStreamMapping(List<NamespaceToStream> namespaceMapping) {
51         Map<String, String> streamMap = new HashMap<>(namespaceMapping.size());
52
53         for (NamespaceToStream nToS  : namespaceMapping) {
54             streamMap.put(nToS.getUrnPrefix(), nToS.getStreamName());
55         }
56
57         return streamMap;
58     }
59
60     public void mdsalReady() {
61         dataStore.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
62                                              INVENTORY_PATH,
63                                              this,
64                                              DataBroker.DataChangeScope.SUBTREE);
65
66         LOGGER.info("EventSourceManager initialized.");
67     }
68
69     @Override
70     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> event) {
71         //FIXME: Prevent creating new event source on subsequent changes in inventory, like disconnect.
72         LOGGER.debug("[DataChangeEvent<InstanceIdentifier<?>, DataObject>: {}]", event);
73
74         Node node = Util.getAffectedNode(event);
75         // we listen on node tree, therefore we should rather throw IllegalStateException when node is null
76         if ( node == null ) {
77             LOGGER.debug("OnDataChanged Event. Node is null.");
78             return;
79         }
80         if ( isNetconfNode(node) == false ) {
81             LOGGER.debug("OnDataChanged Event. Not a Netconf node.");
82             return;
83         }
84         if ( isEventSource(node) == false ) {
85             LOGGER.debug("OnDataChanged Event. Node an EventSource node.");
86             return;
87         }
88
89         NetconfEventSource netconfEventSource = new NetconfEventSource(mdSal,
90                                                                        node.getKey().getId().getValue(),
91                                                                        streamMap);
92         mdSal.addRpcImplementation(node, EventSourceService.class, netconfEventSource);
93
94         InstanceIdentifier<NetconfNode> nodeInstanceIdentifier =
95                 InstanceIdentifier.create(Nodes.class)
96                         .child(Node.class, node.getKey())
97                         .augmentation(NetconfNode.class);
98
99         dataStore.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
100                 nodeInstanceIdentifier,
101                 netconfEventSource,
102                 DataBroker.DataChangeScope.SUBTREE);
103
104         eventSourceTopology.insert(node);
105     }
106
107     private boolean isNetconfNode(Node node)  {
108         return node.getAugmentation(NetconfNode.class) != null ;
109     }
110
111     public boolean isEventSource(Node node) {
112         NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
113
114         return isEventSource(netconfNode);
115     }
116
117     private boolean isEventSource(NetconfNode node) {
118         for (String capability : node.getInitialCapability()) {
119             if(capability.startsWith("urn:ietf:params:xml:ns:netconf:notification")) {
120                 return true;
121             }
122         }
123
124         return false;
125     }
126 }