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.HashMap;
13 import java.util.concurrent.ExecutionException;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
18 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
19 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
22 import org.opendaylight.genius.datastoreutils.TaskRetryLooper;
23 import org.opendaylight.genius.utils.hwvtep.HwvtepHACache;
24 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
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 public 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 ListenerRegistration<HwvtepNodeBaseListener> registration;
46 public HwvtepNodeBaseListener(LogicalDatastoreType datastoreType, DataBroker dataBroker) throws Exception {
48 registerListener(datastoreType, db);
51 public void registerListener(LogicalDatastoreType dsType, final DataBroker db) throws Exception {
52 final DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(dsType, getWildcardPath());
53 TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
54 registration = looper.loopUntilNoException(() ->
55 db.registerDataTreeChangeListener(treeId, HwvtepNodeBaseListener.this));
59 public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
60 HAJobScheduler.getInstance().submitJob(() -> {
61 ReadWriteTransaction tx = getTx();
63 processConnectedNodes(changes, tx);
64 processUpdatedNodes(changes, tx);
65 processDisconnectedNodes(changes, tx);
67 } catch (InterruptedException e1) {
68 LOG.error("InterruptedException " + e1.getMessage());
69 } catch (ExecutionException e2) {
70 LOG.error("ExecutionException" + e2.getMessage());
71 } catch (ReadFailedException e3) {
72 LOG.error("ReadFailedException" + e3.getMessage());
77 private void processUpdatedNodes(Collection<DataTreeModification<Node>> changes,
78 ReadWriteTransaction tx)
79 throws ReadFailedException, ExecutionException, InterruptedException {
80 for (DataTreeModification<Node> change : changes) {
81 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
82 final DataObjectModification<Node> mod = change.getRootNode();
83 String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
84 Node updated = HwvtepHAUtil.getUpdated(mod);
85 Node original = HwvtepHAUtil.getOriginal(mod);
86 if (updated != null && original != null) {
87 if (updated != null && original != null) {
88 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
89 onGlobalNodeUpdate(key, updated, original, tx);
91 onPsNodeUpdate(key, updated, original, tx);
98 private void processDisconnectedNodes(Collection<DataTreeModification<Node>> changes,
99 ReadWriteTransaction tx)
100 throws InterruptedException, ExecutionException, ReadFailedException {
102 for (DataTreeModification<Node> change : changes) {
103 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
104 final DataObjectModification<Node> mod = change.getRootNode();
105 Node deleted = HwvtepHAUtil.getRemoved(mod);
106 String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
107 if (deleted != null) {
108 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
109 LOG.info("Handle global node delete {}", deleted.getNodeId().getValue());
110 onGlobalNodeDelete(key, deleted, tx);
112 LOG.error("Handle ps node node delete {}", deleted.getNodeId().getValue());
113 onPsNodeDelete(key, deleted, tx);
119 void processConnectedNodes(Collection<DataTreeModification<Node>> changes,
120 ReadWriteTransaction tx)
121 throws ReadFailedException, ExecutionException,
122 InterruptedException {
123 Map<String, Boolean> processedNodes = new HashMap<>();
124 for (DataTreeModification<Node> change : changes) {
125 InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
126 DataObjectModification<Node> mod = change.getRootNode();
127 Node node = HwvtepHAUtil.getCreated(mod);
128 String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
130 if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
131 LOG.info("Handle global node add {}", node.getNodeId().getValue());
132 onGlobalNodeAdd(key, node, tx);
134 LOG.error("Handle ps node add {}", node.getNodeId().getValue());
135 onPsNodeAdd(key, node, tx);
141 private InstanceIdentifier<Node> getWildcardPath() {
142 InstanceIdentifier<Node> path = InstanceIdentifier
143 .create(NetworkTopology.class)
144 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
150 public void close() throws Exception {
151 if (registration != null) {
152 registration.close();
156 ReadWriteTransaction getTx() {
157 return db.newReadWriteTransaction();
161 void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx)
162 throws InterruptedException, ExecutionException, ReadFailedException {
165 void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
166 throws ReadFailedException {
170 void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx) {
174 void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
175 throws ReadFailedException, InterruptedException, ExecutionException {
179 void onGlobalNodeUpdate(InstanceIdentifier<Node> key, Node updated, Node original, ReadWriteTransaction tx)
180 throws ReadFailedException, InterruptedException, ExecutionException {
184 void onPsNodeUpdate(InstanceIdentifier<Node> key, Node updated, Node original, ReadWriteTransaction tx)
185 throws ReadFailedException, InterruptedException, ExecutionException {