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