Bulk merge of l2gw changes
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / listeners / HwvtepPhysicalSwitchChildListener.java
1 /*
2  * Copyright © 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netvirt.elan.l2gw.listeners;
9
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;
36
37
38 @Singleton
39 public class HwvtepPhysicalSwitchChildListener extends
40     AbstractClusteredAsyncDataTreeChangeListener<PhysicalSwitchAugmentation> {
41
42     private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchChildListener.class);
43
44     static HwvtepHACache hwvtepHACache = HwvtepHACache.getInstance();
45
46     private final L2GatewayCache l2GatewayCache;
47     private final ElanClusterUtils elanClusterUtils;
48     private final StaleVlanBindingsCleaner staleVlanBindingsCleaner;
49     private final DataBroker dataBroker;
50
51     @Inject
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));
61
62         this.l2GatewayCache = l2GatewayCache;
63         this.elanClusterUtils = elanClusterUtils;
64         this.staleVlanBindingsCleaner = staleVlanBindingsCleaner;
65         this.dataBroker = dataBroker;
66         init();
67     }
68
69     public void init() {
70         ResourceBatchingManager.getInstance().registerDefaultBatchHandlers(this.dataBroker);
71         LOG.info("Registering HwvtepPhysicalSwitchChildListener");
72         super.register();
73     }
74
75     @Override
76     public void remove(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
77                           PhysicalSwitchAugmentation del) {
78     }
79
80     @Override
81     public void update(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
82                           PhysicalSwitchAugmentation original,
83                           PhysicalSwitchAugmentation update) {
84     }
85
86     @Override
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);
92
93
94             final String psName = getPsName(identifier);
95             L2GatewayDevice l2GwDevice = l2GatewayCache.get(psName);
96             if (l2GwDevice != null) {
97                 final String physName = l2GwDevice.getDeviceName();
98
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();
105                 });
106             }
107         }
108     }
109
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)));
115         }
116         return null;
117     }
118
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
123                     .length());
124         }
125         return null;
126     }
127 }