Bump versions by 0.1.0 for next dev cycle
[vpnservice.git] / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / vpnservice / elan / l2gw / listeners / HwvtepNodeListener.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.vpnservice.elan.l2gw.listeners;
10
11 import java.util.ArrayList;
12 import java.util.List;
13
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;
44
45 import com.google.common.base.Optional;
46
47 public class HwvtepNodeListener
48         extends AsyncClusteredDataChangeListenerBase<Node, HwvtepNodeListener> {
49     private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeListener.class);
50
51     private DataBroker dataBroker;
52     private ItmRpcService itmRpcService;
53     ElanInstanceManager elanInstanceManager;
54
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;
61     }
62
63     @Override
64     protected InstanceIdentifier<Node> getWildCardPath() {
65         return InstanceIdentifier.create(NetworkTopology.class)
66                 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class);
67     }
68
69     @Override
70     protected HwvtepNodeListener getDataChangeListener() {
71         return HwvtepNodeListener.this;
72     }
73
74     @Override
75     protected DataChangeScope getDataChangeScope() {
76         return AsyncDataBroker.DataChangeScope.BASE;
77     }
78
79     @Override
80     protected void remove(InstanceIdentifier<Node> key, Node nodeDeleted) {
81         String nodeId = nodeDeleted.getNodeId().getValue();
82         LOG.debug("Received Node Remove Event for {}", nodeId);
83
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);
88
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);
94                 } else {
95                     LOG.debug("{} details are not removed from L2Gateway Cache as it has L2Gateway refrence", psName);
96                 }
97
98                 l2GwDevice.setConnected(false);
99                 ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(psName);
100             } else {
101                 LOG.error("Unable to find L2 Gateway details for {}", psName);
102             }
103         } else {
104             LOG.trace("Received Node Remove Event for {} is not related to Physical switch; it's not processed",
105                     nodeId);
106         }
107     }
108
109     @Override
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);
113         }
114     }
115
116     @Override
117     protected void add(InstanceIdentifier<Node> key, Node nodeAdded) {
118         String nodeId = nodeAdded.getNodeId().getValue();
119         LOG.debug("Received Node Add Event for {}", nodeId);
120
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);
125
126             L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
127             if (l2GwDevice == null) {
128                 LOG.debug("{} details are not present in L2Gateway Cache; added now!", psName);
129
130                 l2GwDevice = new L2GatewayDevice();
131                 l2GwDevice.setDeviceName(psName);
132                 L2GatewayCacheUtils.addL2DeviceToCache(psName, l2GwDevice);
133             } else {
134                 LOG.debug("{} details are present in L2Gateway Cache and same reference used for updates", psName);
135             }
136
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);
149                         }
150
151                         // It's a pre-provision scenario
152                         // Initiate ITM tunnel creation
153                         ElanL2GatewayUtils.createItmTunnels(itmRpcService, hwvtepNodeId, psName, tunnelIpAddr);
154
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);
161
162                             for (L2gatewayConnection l2GwConn : l2GwConns) {
163                                 LOG.trace("L2GatewayConnection {} changes executed on physical switch {}",
164                                         l2GwConn.getL2gatewayId(), psName);
165
166                                 L2GatewayConnectionUtils.addL2GatewayConnection(l2GwConn, psName);
167                             }
168                         }
169                         //TODO handle deleted l2gw connections while the device is offline
170                     }
171                 }
172             }
173
174             if (LOG.isTraceEnabled()) {
175                 LOG.trace("L2Gateway cache updated with below details: {}", l2GwDevice);
176             }
177         } else {
178             LOG.trace("Received Node Add Event for {} is not related to Physical switch; it's not processed", nodeId);
179         }
180     }
181
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);
191                     }
192                 }
193             }
194         }
195         return l2GwConnections;
196     }
197
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();
204         }
205         return null;
206     }
207
208     private String getManagedByNodeId(HwvtepGlobalRef globalRef) {
209         InstanceIdentifier<?> instId = globalRef.getValue();
210         return instId.firstKeyOf(Node.class, NodeKey.class).getNodeId().getValue();
211     }
212 }