2 * Copyright © 2020 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.listeners;
10 import java.util.Collections;
11 import javax.inject.Inject;
12 import javax.inject.Singleton;
13 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
14 import org.opendaylight.genius.utils.hwvtep.HwvtepHACache;
15 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
16 import org.opendaylight.infrautils.utils.concurrent.Executors;
17 import org.opendaylight.mdsal.binding.api.DataBroker;
18 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
19 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
20 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
21 import org.opendaylight.netvirt.elan.l2gw.utils.StaleVlanBindingsCleaner;
22 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
23 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
24 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
25 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredAsyncDataTreeChangeListener;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
39 public class HwvtepPhysicalSwitchChildListener extends
40 AbstractClusteredAsyncDataTreeChangeListener<PhysicalSwitchAugmentation> {
42 private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchChildListener.class);
44 static HwvtepHACache hwvtepHACache = HwvtepHACache.getInstance();
46 private final L2GatewayCache l2GatewayCache;
47 private final ElanClusterUtils elanClusterUtils;
48 private final StaleVlanBindingsCleaner staleVlanBindingsCleaner;
49 private final DataBroker dataBroker;
52 public HwvtepPhysicalSwitchChildListener(L2GatewayCache l2GatewayCache,
53 ElanClusterUtils elanClusterUtils,
54 StaleVlanBindingsCleaner staleVlanBindingsCleaner,
55 DataBroker dataBroker) {
56 super(dataBroker, DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
57 InstanceIdentifier.create(NetworkTopology.class)
58 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class)
59 .augmentation(PhysicalSwitchAugmentation.class)),
60 Executors.newListeningSingleThreadExecutor("HwvtepPhysicalSwitchChildListener", LOG));
62 this.l2GatewayCache = l2GatewayCache;
63 this.elanClusterUtils = elanClusterUtils;
64 this.staleVlanBindingsCleaner = staleVlanBindingsCleaner;
65 this.dataBroker = dataBroker;
70 ResourceBatchingManager.getInstance().registerDefaultBatchHandlers(this.dataBroker);
71 LOG.info("Registering HwvtepPhysicalSwitchChildListener");
76 public void remove(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
77 PhysicalSwitchAugmentation del) {
81 public void update(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
82 PhysicalSwitchAugmentation original,
83 PhysicalSwitchAugmentation update) {
87 public void add(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
88 PhysicalSwitchAugmentation add) {
89 if (HwvtepHACache.getInstance().isHAEnabledDevice(identifier)) {
90 InstanceIdentifier<Node> childGlobalNodeIid = getManagedByNodeIid(identifier);
91 InstanceIdentifier<Node> globalNodeIid = hwvtepHACache.getParent(childGlobalNodeIid);
94 final String psName = getPsName(identifier);
95 L2GatewayDevice l2GwDevice = l2GatewayCache.get(psName);
96 if (l2GwDevice != null) {
97 final String physName = l2GwDevice.getDeviceName();
99 elanClusterUtils.runOnlyInOwnerNode(psName, "Stale entry cleanup on hwvtep disconnect", () -> {
100 String psNodeId = globalNodeIid.firstKeyOf(Node.class).getNodeId().getValue()
101 + HwvtepHAUtil.PHYSICALSWITCH + physName;
102 InstanceIdentifier<Node> psIid = HwvtepHAUtil.convertToInstanceIdentifier(psNodeId);
103 staleVlanBindingsCleaner.scheduleStaleCleanup(physName, globalNodeIid, psIid);
104 return Collections.emptyList();
110 private InstanceIdentifier<Node> getManagedByNodeIid(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
111 String psNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
112 if (psNodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
113 psNodeId = psNodeId.substring(0, psNodeId.indexOf(HwvtepHAUtil.PHYSICALSWITCH));
114 return identifier.firstIdentifierOf(Topology.class).child(Node.class, new NodeKey(new NodeId(psNodeId)));
119 private String getPsName(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
120 String psNodeId = identifier.firstKeyOf(Node.class).getNodeId().getValue();
121 if (psNodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
122 return psNodeId.substring(psNodeId.indexOf(HwvtepHAUtil.PHYSICALSWITCH) + HwvtepHAUtil.PHYSICALSWITCH