Bug 8998 - L2GW:Vlan bindings missing on reboot
[netvirt.git] / vpnservice / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / listeners / HwvtepLogicalSwitchListener.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 package org.opendaylight.netvirt.elan.l2gw.listeners;
9
10 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
11 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
12 import org.opendaylight.genius.datastoreutils.hwvtep.HwvtepClusteredDataTreeChangeListener;
13 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
14 import org.opendaylight.netvirt.elan.l2gw.jobs.LogicalSwitchAddedJob;
15 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
16 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
17 import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
18 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
19 import org.opendaylight.netvirt.elan.utils.ElanUtils;
20 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * The listener class for listening to {@code LogicalSwitches}
32  * add/delete/update.
33  *
34  * @see LogicalSwitches
35  */
36 public class HwvtepLogicalSwitchListener extends
37         HwvtepClusteredDataTreeChangeListener<LogicalSwitches, HwvtepLogicalSwitchListener> {
38
39     /** The Constant LOG. */
40     private static final Logger LOG = LoggerFactory.getLogger(HwvtepLogicalSwitchListener.class);
41
42     /** The node id. */
43     private NodeId nodeId;
44
45     /** The logical switch name. */
46     private String logicalSwitchName;
47
48     /** The physical device. */
49     private Devices physicalDevice;
50
51     /** The l2 gateway device. */
52     private L2GatewayDevice l2GatewayDevice;
53
54     // The default vlan id
55     private Integer defaultVlanId;
56
57     // Id of L2 Gateway connection responsible for this logical switch creation
58     private Uuid l2GwConnId;
59
60     private final DataBroker broker;
61     private final ElanL2GatewayUtils elanL2GatewayUtils;
62     private final EntityOwnershipService entityOwnershipService;
63     private final ElanUtils elanUtils;
64     private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
65
66     /**
67      * Instantiates a new hardware vtep logical switch listener.
68      *
69      * @param dataBroker DataBroker
70      * @param elanL2GatewayUtils l2 gateway utils
71      * @param entityOwnershipService the entity ownership service
72      * @param elanUtils the ELAN utilities
73      * @param elanL2GatewayMulticastUtils l2 gateway multicast utils
74      * @param l2GatewayDevice the l2 gateway device
75      * @param logicalSwitchName the logical switch name
76      * @param physicalDevice the physical device
77      * @param defaultVlanId the default vlan id
78      * @param l2GwConnId l2 gateway connection id
79      */
80     public HwvtepLogicalSwitchListener(DataBroker dataBroker, ElanL2GatewayUtils elanL2GatewayUtils,
81                                        EntityOwnershipService entityOwnershipService, ElanUtils elanUtils,
82                                        ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
83                                        L2GatewayDevice l2GatewayDevice,
84                                        String logicalSwitchName,
85                                        Devices physicalDevice, Integer defaultVlanId, Uuid l2GwConnId) {
86         super(LogicalSwitches.class, HwvtepLogicalSwitchListener.class);
87         this.broker = dataBroker;
88         this.elanL2GatewayUtils = elanL2GatewayUtils;
89         this.entityOwnershipService = entityOwnershipService;
90         this.elanUtils = elanUtils;
91         this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
92         this.nodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
93         this.logicalSwitchName = logicalSwitchName;
94         this.physicalDevice = physicalDevice;
95         this.l2GatewayDevice = l2GatewayDevice;
96         this.defaultVlanId = defaultVlanId;
97         this.l2GwConnId = l2GwConnId;
98     }
99
100     /*
101      * (non-Javadoc)
102      *
103      * @see
104      * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
105      * getWildCardPath()
106      */
107     @Override
108     public InstanceIdentifier<LogicalSwitches> getWildCardPath() {
109         return HwvtepSouthboundUtils.createLogicalSwitchesInstanceIdentifier(nodeId,
110                 new HwvtepNodeName(logicalSwitchName));
111     }
112
113     @Override
114     protected HwvtepLogicalSwitchListener getDataTreeChangeListener() {
115         return this;
116     }
117
118     /*
119      * (non-Javadoc)
120      *
121      * @see
122      * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
123      * remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
124      * org.opendaylight.yangtools.yang.binding.DataObject)
125      */
126     @Override
127     protected void removed(InstanceIdentifier<LogicalSwitches> identifier, LogicalSwitches deletedLogicalSwitch) {
128         LOG.trace("Received Remove DataChange Notification for identifier: {}, LogicalSwitches: {}", identifier,
129                 deletedLogicalSwitch);
130     }
131
132     /*
133      * (non-Javadoc)
134      *
135      * @see
136      * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
137      * update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
138      * org.opendaylight.yangtools.yang.binding.DataObject,
139      * org.opendaylight.yangtools.yang.binding.DataObject)
140      */
141     @Override
142     protected void updated(InstanceIdentifier<LogicalSwitches> identifier, LogicalSwitches logicalSwitchOld,
143             LogicalSwitches logicalSwitchNew) {
144         LOG.trace("Received Update DataChange Notification for identifier: {}, LogicalSwitches old: {}, new: {}."
145                 + "No Action Performed.", identifier, logicalSwitchOld, logicalSwitchNew);
146     }
147
148     @Override
149     @SuppressWarnings("checkstyle:IllegalCatch")
150     protected void added(InstanceIdentifier<LogicalSwitches> identifier, LogicalSwitches logicalSwitchNew) {
151         LOG.debug("Received Add DataChange Notification for identifier: {}, LogicalSwitches: {}", identifier,
152                 logicalSwitchNew);
153         try {
154             L2GatewayDevice elanDevice = L2GatewayConnectionUtils.addL2DeviceToElanL2GwCache(broker,
155                     logicalSwitchNew.getHwvtepNodeName().getValue(), elanUtils,
156                     l2GatewayDevice, l2GwConnId,physicalDevice);
157
158             LogicalSwitchAddedJob logicalSwitchAddedWorker = new LogicalSwitchAddedJob(broker, elanL2GatewayUtils,
159                     elanUtils, elanL2GatewayMulticastUtils, logicalSwitchName, physicalDevice, elanDevice,
160                     defaultVlanId);
161             ElanClusterUtils.runOnlyInLeaderNode(entityOwnershipService, logicalSwitchAddedWorker.getJobKey() ,
162                     "create vlan mappings and mcast configurations",
163                     logicalSwitchAddedWorker);
164         } catch (RuntimeException e) {
165             LOG.error("Failed to handle HwVTEPLogicalSwitch - add for: {}", identifier, e);
166         } finally {
167             try {
168                 // This listener is specific to handle a specific logical
169                 // switch, hence closing it.
170                 LOG.trace("Closing LogicalSwitches listener for node: {}, logicalSwitch: {}", nodeId.getValue(),
171                         logicalSwitchName);
172                 // TODO use https://git.opendaylight.org/gerrit/#/c/44145/ when merged, and remove @SuppressWarnings
173                 close();
174             } catch (Exception e) {
175                 LOG.warn("Failed to close HwVTEPLogicalSwitchListener", e);
176             }
177         }
178     }
179 }