2 * Copyright (c) 2019 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.southbound;
11 import java.util.Collection;
12 import java.util.concurrent.ConcurrentHashMap;
13 import java.util.concurrent.ConcurrentMap;
15 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
18 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
26 import org.opendaylight.yangtools.concepts.ListenerRegistration;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 public class OvsdbOperGlobalListener implements ClusteredDataTreeChangeListener<Node>, AutoCloseable {
33 private static final Logger LOG = LoggerFactory.getLogger(OvsdbOperGlobalListener.class);
34 private ListenerRegistration<OvsdbOperGlobalListener> registration;
35 private DataBroker db;
36 public static final ConcurrentMap<InstanceIdentifier<Node>, Node> OPER_NODE_CACHE = new ConcurrentHashMap<>();
37 private final OvsdbConnectionManager ovsdbConnectionManager;
38 private final TransactionInvoker txInvoker;
41 OvsdbOperGlobalListener(DataBroker db, OvsdbConnectionManager ovsdbConnectionManager,
42 TransactionInvoker txInvoker) {
43 LOG.info("Registering OvsdbOperGlobalListener");
45 this.ovsdbConnectionManager = ovsdbConnectionManager;
46 this.txInvoker = txInvoker;
50 public void registerListener() {
51 DataTreeIdentifier<Node> treeId =
52 new DataTreeIdentifier<Node>(LogicalDatastoreType.OPERATIONAL, getWildcardPath());
53 registration = db.registerDataTreeChangeListener(treeId, this);
58 if (registration != null) {
60 LOG.info("OVSDB Oper Node listener has been closed.");
65 @SuppressWarnings("checkstyle:IllegalCatch")
66 public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
67 changes.forEach((change) -> {
69 InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
70 DataObjectModification<Node> mod = change.getRootNode();
71 Node addNode = getCreated(mod);
72 if (addNode != null) {
73 OPER_NODE_CACHE.put(key, addNode);
74 LOG.info("Node added to oper {}", SouthboundUtil.getOvsdbNodeId(key));
76 Node removedNode = getRemoved(mod);
77 if (removedNode != null) {
78 OPER_NODE_CACHE.remove(key);
79 LOG.info("Node deleted from oper {}", SouthboundUtil.getOvsdbNodeId(key));
81 OvsdbConnectionInstance connectionInstance = ovsdbConnectionManager.getConnectionInstance(key);
82 if (connectionInstance != null && connectionInstance.isActive()
83 && connectionInstance.getHasDeviceOwnership() != null
84 && connectionInstance.getHasDeviceOwnership()) {
85 //Oops some one deleted the node held by me This should never happen.
86 //put the node back in oper
87 txInvoker.invoke(transaction -> {
88 transaction.put(LogicalDatastoreType.OPERATIONAL, key, removedNode);
94 Node modifiedNode = getUpdated(mod);
95 if (modifiedNode != null) {
96 OPER_NODE_CACHE.put(key, modifiedNode);
98 } catch (Exception e) {
99 LOG.error("Failed to handle oper node ", e);
106 private Node getCreated(DataObjectModification<Node> mod) {
107 if ((mod.getModificationType() == DataObjectModification.ModificationType.WRITE)
108 && (mod.getDataBefore() == null)) {
109 return mod.getDataAfter();
114 private Node getRemoved(DataObjectModification<Node> mod) {
115 if (mod.getModificationType() == DataObjectModification.ModificationType.DELETE) {
116 return mod.getDataBefore();
121 private Node getUpdated(DataObjectModification<Node> mod) {
123 switch (mod.getModificationType()) {
124 case SUBTREE_MODIFIED:
125 node = mod.getDataAfter();
128 if (mod.getDataBefore() != null) {
129 node = mod.getDataAfter();
138 private InstanceIdentifier<Node> getWildcardPath() {
139 InstanceIdentifier<Node> path = InstanceIdentifier
140 .create(NetworkTopology.class)
141 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))