2 * Copyright (c) 2016 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
9 package org.opendaylight.vpnservice.elan.l2gw.listeners;
11 import java.util.ArrayList;
12 import java.util.List;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.elanmanager.utils.ElanL2GwCacheUtils;
19 import org.opendaylight.vpnservice.datastoreutils.AsyncClusteredDataChangeListenerBase;
20 import org.opendaylight.vpnservice.elan.internal.ElanInstanceManager;
21 import org.opendaylight.vpnservice.elan.l2gw.utils.ElanL2GatewayUtils;
22 import org.opendaylight.vpnservice.elan.l2gw.utils.L2GatewayConnectionUtils;
23 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
24 import org.opendaylight.vpnservice.neutronvpn.api.l2gw.L2GatewayDevice;
25 import org.opendaylight.vpnservice.neutronvpn.api.l2gw.utils.L2GatewayCacheUtils;
26 import org.opendaylight.vpnservice.utils.hwvtep.HwvtepSouthboundConstants;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
45 import com.google.common.base.Optional;
47 public class HwvtepNodeListener
48 extends AsyncClusteredDataChangeListenerBase<Node, HwvtepNodeListener> {
49 private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeListener.class);
51 private DataBroker dataBroker;
52 private ItmRpcService itmRpcService;
53 ElanInstanceManager elanInstanceManager;
55 public HwvtepNodeListener(final DataBroker dataBroker, ElanInstanceManager elanInstanceManager,
56 ItmRpcService itmRpcService) {
57 super(Node.class, HwvtepNodeListener.class);
58 this.dataBroker = dataBroker;
59 this.itmRpcService = itmRpcService;
60 this.elanInstanceManager = elanInstanceManager;
64 protected InstanceIdentifier<Node> getWildCardPath() {
65 return InstanceIdentifier.create(NetworkTopology.class)
66 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class);
70 protected HwvtepNodeListener getDataChangeListener() {
71 return HwvtepNodeListener.this;
75 protected DataChangeScope getDataChangeScope() {
76 return AsyncDataBroker.DataChangeScope.BASE;
80 protected void remove(InstanceIdentifier<Node> key, Node nodeDeleted) {
81 String nodeId = nodeDeleted.getNodeId().getValue();
82 LOG.debug("Received Node Remove Event for {}", nodeId);
84 PhysicalSwitchAugmentation psAugmentation = nodeDeleted.getAugmentation(PhysicalSwitchAugmentation.class);
85 if (psAugmentation != null) {
86 String psName = psAugmentation.getHwvtepNodeName().getValue();
87 LOG.info("Physical switch {} removed from node {} event received", psName, nodeId);
89 L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
90 if (l2GwDevice != null) {
91 if (!L2GatewayConnectionUtils.isGatewayAssociatedToL2Device(l2GwDevice)) {
92 L2GatewayCacheUtils.removeL2DeviceFromCache(psName);
93 LOG.debug("{} details removed from L2Gateway Cache", psName);
95 LOG.debug("{} details are not removed from L2Gateway Cache as it has L2Gateway refrence", psName);
98 l2GwDevice.setConnected(false);
99 ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(psName);
101 LOG.error("Unable to find L2 Gateway details for {}", psName);
104 LOG.trace("Received Node Remove Event for {} is not related to Physical switch; it's not processed",
110 protected void update(InstanceIdentifier<Node> key, Node nodeBefore, Node nodeAfter) {
111 if (LOG.isTraceEnabled()) {
112 LOG.trace("Received Node Update Event: Node Before: {}, Node After: {}", nodeBefore, nodeAfter);
117 protected void add(InstanceIdentifier<Node> key, Node nodeAdded) {
118 String nodeId = nodeAdded.getNodeId().getValue();
119 LOG.debug("Received Node Add Event for {}", nodeId);
121 PhysicalSwitchAugmentation psAugmentation = nodeAdded.getAugmentation(PhysicalSwitchAugmentation.class);
122 if (psAugmentation != null) {
123 String psName = psAugmentation.getHwvtepNodeName().getValue();
124 LOG.info("Physical switch {} added to node {} event received", psName, nodeId);
126 L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
127 if (l2GwDevice == null) {
128 LOG.debug("{} details are not present in L2Gateway Cache; added now!", psName);
130 l2GwDevice = new L2GatewayDevice();
131 l2GwDevice.setDeviceName(psName);
132 L2GatewayCacheUtils.addL2DeviceToCache(psName, l2GwDevice);
134 LOG.debug("{} details are present in L2Gateway Cache and same reference used for updates", psName);
137 l2GwDevice.setConnected(true);
138 String hwvtepNodeId = getManagedByNodeId(psAugmentation.getManagedBy());
139 l2GwDevice.setHwvtepNodeId(hwvtepNodeId);
140 List<TunnelIps> tunnelIps = psAugmentation.getTunnelIps();
141 if (tunnelIps != null) {
142 for (TunnelIps tunnelIp : tunnelIps) {
143 IpAddress tunnelIpAddr = tunnelIp.getTunnelIpsKey();
144 l2GwDevice.addTunnelIp(tunnelIpAddr);
145 if (L2GatewayConnectionUtils.isGatewayAssociatedToL2Device(l2GwDevice)) {
146 if (LOG.isDebugEnabled()) {
147 LOG.debug("L2Gateway {} associated for {} physical switch; creating ITM tunnels for {}",
148 l2GwDevice.getL2GatewayIds(), psName, tunnelIpAddr);
151 // It's a pre-provision scenario
152 // Initiate ITM tunnel creation
153 ElanL2GatewayUtils.createItmTunnels(itmRpcService, hwvtepNodeId, psName, tunnelIpAddr);
155 // Initiate Logical switch creation for associated L2
156 // Gateway Connections
157 List<L2gatewayConnection> l2GwConns = getAssociatedL2GwConnections(dataBroker,
158 l2GwDevice.getL2GatewayIds());
159 if (l2GwConns != null) {
160 LOG.debug("L2GatewayConnections associated for {} physical switch", psName);
162 for (L2gatewayConnection l2GwConn : l2GwConns) {
163 LOG.trace("L2GatewayConnection {} changes executed on physical switch {}",
164 l2GwConn.getL2gatewayId(), psName);
166 L2GatewayConnectionUtils.addL2GatewayConnection(l2GwConn, psName);
169 //TODO handle deleted l2gw connections while the device is offline
174 if (LOG.isTraceEnabled()) {
175 LOG.trace("L2Gateway cache updated with below details: {}", l2GwDevice);
178 LOG.trace("Received Node Add Event for {} is not related to Physical switch; it's not processed", nodeId);
182 private List<L2gatewayConnection> getAssociatedL2GwConnections(DataBroker broker, List<Uuid> l2GatewayIds) {
183 List<L2gatewayConnection> l2GwConnections = null;
184 List<L2gatewayConnection> allL2GwConns = getAllL2gatewayConnections(broker);
185 if (allL2GwConns != null) {
186 l2GwConnections = new ArrayList<L2gatewayConnection>();
187 for (Uuid l2GatewayId : l2GatewayIds) {
188 for (L2gatewayConnection l2GwConn : allL2GwConns) {
189 if (l2GwConn.getL2gatewayId().equals(l2GatewayId)) {
190 l2GwConnections.add(l2GwConn);
195 return l2GwConnections;
198 protected List<L2gatewayConnection> getAllL2gatewayConnections(DataBroker broker) {
199 InstanceIdentifier<L2gatewayConnections> inst = InstanceIdentifier.create(Neutron.class)
200 .child(L2gatewayConnections.class);
201 Optional<L2gatewayConnections> l2GwConns = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
202 if (l2GwConns.isPresent()) {
203 return l2GwConns.get().getL2gatewayConnection();
208 private String getManagedByNodeId(HwvtepGlobalRef globalRef) {
209 InstanceIdentifier<?> instId = globalRef.getValue();
210 return instId.firstKeyOf(Node.class, NodeKey.class).getNodeId().getValue();