2 * Copyright © 2016, 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
8 package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
10 import java.util.Collection;
11 import java.util.concurrent.ExecutionException;
12 import javax.annotation.PreDestroy;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
15 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
18 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
21 import org.opendaylight.genius.datastoreutils.TaskRetryLooper;
22 import org.opendaylight.genius.utils.hwvtep.HwvtepHACache;
23 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
24 import org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction;
25 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
30 import org.opendaylight.yangtools.concepts.ListenerRegistration;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<Node>, AutoCloseable {
37 private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeBaseListener.class);
38 private static final int STARTUP_LOOP_TICK = 500;
39 private static final int STARTUP_LOOP_MAX_RETRIES = 8;
41 static HwvtepHACache hwvtepHACache = HwvtepHACache.getInstance();
43 private final ListenerRegistration<HwvtepNodeBaseListener> registration;
44 private final DataBroker dataBroker;
46 public HwvtepNodeBaseListener(LogicalDatastoreType datastoreType, DataBroker dataBroker) throws Exception {
47 this.dataBroker = dataBroker;
49 final DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(datastoreType, getWildcardPath());
50 TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
51 registration = looper.loopUntilNoException(() ->
52 dataBroker.registerDataTreeChangeListener(treeId, HwvtepNodeBaseListener.this));
55 protected DataBroker getDataBroker() {
60 public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
61 HAJobScheduler.getInstance().submitJob(() -> {
62 ReadWriteTransaction tx = getTx();
64 processConnectedNodes(changes, tx);
65 processUpdatedNodes(changes, tx);
66 processDisconnectedNodes(changes, tx);
68 } catch (InterruptedException | ExecutionException | ReadFailedException e) {
69 LOG.error("Error processing data-tree changes", e);
74 private void processUpdatedNodes(Collection<DataTreeModification<Node>> changes,
75 ReadWriteTransaction tx)
76 throws ReadFailedException, ExecutionException, InterruptedException {
77 for (DataTreeModification<Node> change : changes) {
78 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
79 final DataObjectModification<Node> mod = change.getRootNode();
80 String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
81 Node updated = HwvtepHAUtil.getUpdated(mod);
82 Node original = HwvtepHAUtil.getOriginal(mod);
83 if (updated != null && original != null) {
84 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
85 onGlobalNodeUpdate(key, updated, original, mod, tx);
87 onPsNodeUpdate(updated, original, mod, tx);
93 private void processDisconnectedNodes(Collection<DataTreeModification<Node>> changes,
94 ReadWriteTransaction tx)
95 throws InterruptedException, ExecutionException, ReadFailedException {
97 for (DataTreeModification<Node> change : changes) {
98 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
99 final DataObjectModification<Node> mod = change.getRootNode();
100 Node deleted = HwvtepHAUtil.getRemoved(mod);
101 String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
102 if (deleted != null) {
103 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
104 LOG.trace("Handle global node delete {}", deleted.getNodeId().getValue());
105 onGlobalNodeDelete(key, deleted, tx);
107 LOG.trace("Handle ps node node delete {}", deleted.getNodeId().getValue());
108 onPsNodeDelete(key, deleted, tx);
114 void processConnectedNodes(Collection<DataTreeModification<Node>> changes,
115 ReadWriteTransaction tx)
116 throws ReadFailedException {
117 for (DataTreeModification<Node> change : changes) {
118 InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
119 DataObjectModification<Node> mod = change.getRootNode();
120 Node node = HwvtepHAUtil.getCreated(mod);
121 String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
123 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
124 LOG.trace("Handle global node add {}", node.getNodeId().getValue());
125 onGlobalNodeAdd(key, node, tx);
127 LOG.trace("Handle ps node add {}", node.getNodeId().getValue());
128 onPsNodeAdd(key, node, tx);
134 private InstanceIdentifier<Node> getWildcardPath() {
135 InstanceIdentifier<Node> path = InstanceIdentifier
136 .create(NetworkTopology.class)
137 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
144 public void close() {
145 if (registration != null) {
146 registration.close();
150 ReadWriteTransaction getTx() {
151 return new BatchedTransaction();
155 void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx)
156 throws ReadFailedException {
159 void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
160 throws ReadFailedException {
164 void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx) {
168 void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
169 throws ReadFailedException {
173 void onGlobalNodeUpdate(InstanceIdentifier<Node> key, Node updated, Node original,
174 DataObjectModification<Node> mod, ReadWriteTransaction tx)
175 throws ReadFailedException, InterruptedException, ExecutionException {
179 void onPsNodeUpdate(Node updated, Node original,
180 DataObjectModification<Node> mod, ReadWriteTransaction tx)
181 throws ReadFailedException, InterruptedException, ExecutionException {