2 * Copyright (C) 2015 Red Hat, Inc.
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
10 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
12 import com.google.common.collect.Lists;
13 import java.util.List;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
22 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
23 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
24 import org.opendaylight.ovsdb.utils.mdsal.node.NodeUtils;
25 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
30 import org.opendaylight.yangtools.concepts.ListenerRegistration;
31 import org.opendaylight.yangtools.yang.binding.DataObject;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 public class FlowCapableNodeDataChangeListener implements DataChangeListener, AutoCloseable {
37 private static final Logger LOG = LoggerFactory.getLogger(FlowCapableNodeDataChangeListener.class);
38 private ListenerRegistration<DataChangeListener> registration;
39 private final Object nodeCacheLock = new Object();
40 private List<Node> nodeCache = Lists.newArrayList();
41 private PipelineOrchestrator pipelineOrchestrator = null;
42 private NodeCacheManager nodeCacheManager = null;
44 public static final InstanceIdentifier<FlowCapableNode> createFlowCapableNodePath () {
45 return InstanceIdentifier.builder(Nodes.class)
47 .augmentation(FlowCapableNode.class)
51 public FlowCapableNodeDataChangeListener (DataBroker dataBroker) {
52 LOG.info("Registering FlowCapableNodeChangeListener");
53 registration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
54 createFlowCapableNodePath(), this, AsyncDataBroker.DataChangeScope.BASE);
58 public void close () throws Exception {
63 public void onDataChanged (AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
64 LOG.debug(">>>> onDataChanged: {}", changes);
65 checkMemberInitialization();
67 for (InstanceIdentifier instanceIdentifier : changes.getRemovedPaths()) {
68 DataObject originalDataObject = changes.getOriginalData().get(instanceIdentifier);
69 if (originalDataObject instanceof Node) {
70 Node node = (Node) originalDataObject;
71 String openflowId = node.getId().getValue();
72 LOG.info(">>>>> removed iiD: {} - NodeKey: {}", instanceIdentifier, openflowId);
73 Node openFlowNode = NodeUtils.getOpenFlowNode(openflowId);
74 if (removeNodeFromCache(openFlowNode)) {
75 notifyNodeRemoved(openFlowNode);
80 for (Map.Entry<InstanceIdentifier<?>, DataObject> created : changes.getCreatedData().entrySet()) {
81 InstanceIdentifier<?> iID = created.getKey();
82 String openflowId = iID.firstKeyOf(Node.class, NodeKey.class).getId().getValue();
83 LOG.info(">>>>> created iiD: {} - first: {} - NodeKey: {}",
84 iID, iID.firstIdentifierOf(Node.class), openflowId);
85 Node openFlowNode = NodeUtils.getOpenFlowNode(openflowId);
86 if (addNodeToCache(openFlowNode)) {
87 notifyNodeCreated(openFlowNode);
89 notifyNodeUpdated(openFlowNode);
93 for (Map.Entry<InstanceIdentifier<?>, DataObject> updated : changes.getUpdatedData().entrySet()) {
94 InstanceIdentifier<?> iID = updated.getKey();
95 String openflowId = iID.firstKeyOf(Node.class, NodeKey.class).getId().getValue();
96 LOG.info(">>>>> updated iiD: {} - first: {} - NodeKey: {}",
97 iID, iID.firstIdentifierOf(Node.class), openflowId);
98 Node openFlowNode = NodeUtils.getOpenFlowNode(openflowId);
99 if (addNodeToCache(openFlowNode)) {
100 notifyNodeCreated(openFlowNode);
102 notifyNodeUpdated(openFlowNode);
107 public void notifyFlowCapableNodeEvent (String openFlowId, Action action) {
108 LOG.debug("Notification of flow capable node {}, action {}", openFlowId, action);
109 checkMemberInitialization();
111 Node openFlowNode = NodeUtils.getOpenFlowNode(openFlowId);
112 if (action == Action.DELETE) {
113 notifyNodeRemoved(openFlowNode);
115 if (addNodeToCache(openFlowNode)) {
116 notifyNodeCreated(openFlowNode);
118 notifyNodeUpdated(openFlowNode);
124 * This method returns the true if node was added to the nodeCache. If param node
125 * is already in the cache, this method is expected to return false.
127 * @param openFlowNode the node to be added to the cache, if needed
128 * @return whether new node entry was added to cache
130 private Boolean addNodeToCache (Node openFlowNode) {
131 synchronized (nodeCacheLock) {
132 if (nodeCache.contains(openFlowNode)) {
135 return nodeCache.add(openFlowNode);
140 * This method returns the true if node was removed from the nodeCache. If param node
141 * is not in the cache, this method is expected to return false.
143 * @param openFlowNode the node to be removed from the cache, if needed
144 * @return whether new node entry was removed from cache
146 private Boolean removeNodeFromCache (Node openFlowNode) {
147 synchronized (nodeCacheLock) {
148 return nodeCache.remove(openFlowNode);
152 private void notifyNodeUpdated (Node openFlowNode) {
153 final String openflowId = openFlowNode.getId().getValue();
154 LOG.debug("notifyNodeUpdated: Node {} from Controller's inventory Service", openflowId);
156 // TODO: will do something amazing here, someday
159 private void notifyNodeCreated (Node openFlowNode) {
160 final String openflowId = openFlowNode.getId().getValue();
161 LOG.info("notifyNodeCreated: Node {} from Controller's inventory Service", openflowId);
163 if (pipelineOrchestrator != null) {
164 //pipelineOrchestrator.enqueue(openflowId);
166 if (nodeCacheManager != null) {
167 //nodeCacheManager.nodeAdded(openflowId);
171 private void notifyNodeRemoved (Node openFlowNode) {
172 LOG.info("notifyNodeRemoved: Node {} from Controller's inventory Service",
173 openFlowNode.getId().getValue());
175 if (nodeCacheManager != null) {
176 //nodeCacheManager.nodeRemoved(openFlowNode);
180 private void checkMemberInitialization () {
182 * Obtain local ref to members, if needed. Having these local saves us from calling getGlobalInstance
185 if (pipelineOrchestrator == null) {
186 pipelineOrchestrator =
187 (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
189 if (nodeCacheManager == null) {
190 nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);