ELAN: skip remote unicast MACs
[netvirt.git] / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / ha / listeners / HAListeners.java
1 /*
2  * Copyright (c) 2017 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.ha.listeners;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import javax.annotation.PreDestroy;
13 import javax.inject.Inject;
14 import javax.inject.Singleton;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
17 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
18 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalMcastCmd;
19 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalUcastCmd;
20 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LogicalSwitchesCmd;
21 import org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand;
22 import org.opendaylight.netvirt.elan.l2gw.ha.commands.PhysicalLocatorCmd;
23 import org.opendaylight.netvirt.elan.l2gw.ha.commands.RemoteMcastCmd;
24 import org.opendaylight.netvirt.elan.l2gw.ha.commands.RemoteUcastCmd;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAttributes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
37 import org.opendaylight.yangtools.yang.binding.ChildOf;
38 import org.opendaylight.yangtools.yang.binding.DataObject;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40
41 @Singleton
42 public class HAListeners implements AutoCloseable {
43     private static final InstanceIdentifier<TerminationPoint> PHYSICAL_PORT_IID =
44         InstanceIdentifier.create(NetworkTopology.class)
45             .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
46             .child(Node.class).child(TerminationPoint.class);
47
48     private final DataBroker broker;
49     private final List<HwvtepNodeDataListener<?>> listeners = new ArrayList<>();
50
51     @Inject
52     public HAListeners(DataBroker broker) {
53         this.broker = broker;
54         registerListener(LocalMcastMacs.class, new LocalMcastCmd());
55         registerListener(RemoteMcastMacs.class, new RemoteMcastCmd());
56         registerListener(LocalUcastMacs.class, new LocalUcastCmd());
57         registerListener(RemoteUcastMacs.class, new RemoteUcastCmd());
58         registerListener(LogicalSwitches.class, new LogicalSwitchesCmd());
59
60         PhysicalLocatorCmd physicalLocatorCmd = new PhysicalLocatorCmd();
61         listeners.add(new PhysicalLocatorListener(broker, physicalLocatorCmd,
62                 ResourceBatchingManager.ShardResource.CONFIG_TOPOLOGY));
63         listeners.add(new PhysicalLocatorListener(broker, physicalLocatorCmd,
64                 ResourceBatchingManager.ShardResource.OPERATIONAL_TOPOLOGY));
65     }
66
67     @Override
68     @PreDestroy
69     public void close() throws Exception {
70         for (HwvtepNodeDataListener listener : listeners) {
71             listener.close();
72         }
73     }
74
75     private <T extends ChildOf<HwvtepGlobalAttributes>> void registerListener(Class<T> clazz,
76                                                                               MergeCommand mergeCommand) {
77         listeners.add(new GlobalAugmentationListener(broker, clazz, HwvtepNodeDataListener.class, mergeCommand,
78                 ResourceBatchingManager.ShardResource.CONFIG_TOPOLOGY));
79         listeners.add(new GlobalAugmentationListener(broker, clazz, HwvtepNodeDataListener.class, mergeCommand,
80                 ResourceBatchingManager.ShardResource.OPERATIONAL_TOPOLOGY));
81     }
82
83     private static class GlobalAugmentationListener<T extends DataObject
84             & ChildOf<HwvtepGlobalAttributes>> extends HwvtepNodeDataListener<T> {
85
86         GlobalAugmentationListener(DataBroker broker, Class<T> clazz, Class<HwvtepNodeDataListener<T>> eventClazz,
87                                    MergeCommand mergeCommand,
88                                    ResourceBatchingManager.ShardResource datastoreType) {
89             super(broker, clazz, eventClazz, mergeCommand, datastoreType);
90         }
91
92         @Override
93         protected InstanceIdentifier<T> getWildCardPath() {
94             return InstanceIdentifier.create(NetworkTopology.class)
95                     .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
96                     .child(Node.class).augmentation(HwvtepGlobalAugmentation.class).child(clazz);
97         }
98     }
99
100     private static class PhysicalLocatorListener extends HwvtepNodeDataListener<TerminationPoint> {
101
102         PhysicalLocatorListener(DataBroker broker,
103                                 MergeCommand mergeCommand, ResourceBatchingManager.ShardResource datastoreType) {
104             super(broker, TerminationPoint.class, (Class)PhysicalLocatorListener.class, mergeCommand, datastoreType);
105         }
106
107         @Override
108         protected InstanceIdentifier getWildCardPath() {
109             return PHYSICAL_PORT_IID;
110         }
111
112         @Override
113         protected void remove(InstanceIdentifier<TerminationPoint> identifier, TerminationPoint dataRemoved) {
114             if (!isGlobalNode(identifier)) {
115                 return;
116             }
117             super.remove(identifier, dataRemoved);
118         }
119
120         @Override
121         protected void update(InstanceIdentifier<TerminationPoint> identifier, TerminationPoint before,
122                               TerminationPoint after) {
123             if (!isGlobalNode(identifier)) {
124                 return;
125             }
126             super.update(identifier, before, after);
127         }
128
129         @Override
130         protected void add(InstanceIdentifier<TerminationPoint> identifier, TerminationPoint added) {
131             if (!isGlobalNode(identifier)) {
132                 return;
133             }
134             super.add(identifier, added);
135         }
136
137         boolean isGlobalNode(InstanceIdentifier<TerminationPoint> identifier) {
138             return !identifier.firstKeyOf(Node.class).getNodeId().getValue()
139                     .contains(HwvtepSouthboundConstants.PSWITCH_URI_PREFIX);
140         }
141     }
142 }