2 * Copyright (c) 2017 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.hwvtepsouthbound;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.HashSet;
15 import java.util.List;
17 import java.util.Objects;
19 import java.util.Timer;
20 import java.util.TimerTask;
21 import java.util.concurrent.Callable;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ExecutionException;
25 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
28 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
29 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
30 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.ovsdb.lib.message.TableUpdates;
33 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
40 import org.opendaylight.yangtools.concepts.ListenerRegistration;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public class HwvtepOperGlobalListener implements ClusteredDataTreeChangeListener<Node>, AutoCloseable {
48 private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperGlobalListener.class);
50 private Timer timer = new Timer();
51 private ListenerRegistration<HwvtepOperGlobalListener> registration;
52 private HwvtepConnectionManager hcm;
53 private DataBroker db;
54 private Map<YangInstanceIdentifier, Node> connectedNodes = new ConcurrentHashMap<>();
56 HwvtepOperGlobalListener(DataBroker db, HwvtepConnectionManager hcm) {
57 LOG.info("Registering HwvtepOperGlobalListener");
63 private void registerListener(final DataBroker db) {
64 final DataTreeIdentifier<Node> treeId =
65 new DataTreeIdentifier<Node>(LogicalDatastoreType.OPERATIONAL, getWildcardPath());
67 registration = db.registerDataTreeChangeListener(treeId, HwvtepOperGlobalListener.this);
68 } catch (final Exception e) {
69 LOG.error("HwvtepDataChangeListener registration failed", e);
74 public void close() throws Exception {
75 if(registration != null) {
81 public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
82 changes.forEach( (change) -> {
83 InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
84 DataObjectModification<Node> mod = change.getRootNode();
85 InstanceIdentifier<Node> nodeIid = change.getRootPath().getRootIdentifier();
86 YangInstanceIdentifier entityId =
87 HwvtepSouthboundUtil.getInstanceIdentifierCodec().getYangInstanceIdentifier(nodeIid);
88 Node node = getCreated(mod);
90 connectedNodes.put(entityId, node);
92 node = getRemoved(mod);
94 connectedNodes.remove(entityId);
95 HwvtepConnectionInstance connectionInstance = hcm.getConnectionInstanceFromNodeIid(nodeIid);
96 if (Objects.equals(connectionInstance.getConnectionInfo().getRemotePort(),
97 HwvtepSouthboundUtil.getRemotePort(node))) {
98 //Oops some one deleted the node held by me This should never happen
100 connectionInstance.refreshOperNode();
101 } catch (ExecutionException | InterruptedException e) {
102 LOG.error("Failed to refresh operational nodes ", e);
110 private Node getCreated(DataObjectModification<Node> mod) {
111 if((mod.getModificationType() == ModificationType.WRITE)
112 && (mod.getDataBefore() == null)){
113 return mod.getDataAfter();
118 private Node getRemoved(DataObjectModification<Node> mod) {
119 if(mod.getModificationType() == ModificationType.DELETE){
120 return mod.getDataBefore();
125 public Map<YangInstanceIdentifier, Node> getConnectedNodes() {
126 return Collections.unmodifiableMap(connectedNodes);
129 private InstanceIdentifier<Node> getWildcardPath() {
130 InstanceIdentifier<Node> path = InstanceIdentifier
131 .create(NetworkTopology.class)
132 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))