Drop unused exceptions in elanmanager
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / ha / handlers / NodeConnectedHandler.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.ha.handlers;
9
10 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
11 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
12
13 import com.google.common.base.Optional;
14 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.genius.utils.hwvtep.HwvtepHACache;
21 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
22 import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAJobScheduler;
23 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
24 import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalNodeMerger;
25 import org.opendaylight.netvirt.elan.l2gw.ha.merge.PSAugmentationMerger;
26 import org.opendaylight.netvirt.elan.l2gw.ha.merge.PSNodeMerger;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 public class NodeConnectedHandler {
40
41     static Logger LOG = LoggerFactory.getLogger(NodeConnectedHandler.class);
42
43     GlobalAugmentationMerger globalAugmentationMerger = GlobalAugmentationMerger.getInstance();
44     PSAugmentationMerger psAugmentationMerger = PSAugmentationMerger.getInstance();
45     GlobalNodeMerger globalNodeMerger = GlobalNodeMerger.getInstance();
46     PSNodeMerger psNodeMerger = PSNodeMerger.getInstance();
47     DataBroker db;
48     HwvtepHACache hwvtepHACache = HwvtepHACache.getInstance();
49
50     public NodeConnectedHandler(DataBroker db) {
51         this.db = db;
52     }
53
54     /**
55      * Takes care of merging the data when a node gets connected.
56      * When a ha child node gets connected , we perform the following.
57      * Merge the ha parent config data to child node.
58      * Merge the ha parent physical node config data to child physical node.
59      * Merge the child operational data to parent operational data.
60      * Merge the child physical switch node operational data to parent physical switch operational node .
61      *
62      * @param childNode   Ha child node
63      * @param childNodePath Ha child Iid
64      * @param haNodePath  Ha Iid
65      * @param haGlobalCfg Ha Global Config Node
66      * @param haPSCfg Ha Physical Config Node
67      * @param tx Transaction
68      * @throws ReadFailedException  Exception thrown if read fails
69      */
70     public void handleNodeConnected(Node childNode,
71                                     InstanceIdentifier<Node> childNodePath,
72                                     InstanceIdentifier<Node> haNodePath,
73                                     Optional<Node> haGlobalCfg,
74                                     Optional<Node> haPSCfg,
75                                     ReadWriteTransaction tx)
76             throws ReadFailedException {
77         HwvtepHAUtil.buildGlobalConfigForHANode(tx, childNode, haNodePath, haGlobalCfg);
78         copyChildOpToHA(childNode, haNodePath, tx);
79         readAndCopyChildPSOpToHAPS(childNode, haNodePath, tx);
80         if (haGlobalCfg.isPresent()) {
81             //copy ha config to newly connected child case of reconnected child
82             if (haPSCfg.isPresent()) {
83                 /*
84                  copy task of physical switch node is done in the next transaction
85                  The reason being if it is done in the same transaction,
86                  hwvtep plugin is not able to proess this update and send vlanbindings to device
87                  as it is expecting the logical switch to be already present in operational ds
88                  (created in the device)
89                  */
90                 HAJobScheduler.getInstance().submitJob(() -> {
91                     try {
92                         hwvtepHACache.updateConnectedNodeStatus(childNodePath);
93                         LOG.info("HA child reconnected handleNodeReConnected {}",
94                                 childNode.getNodeId().getValue());
95                         ReadWriteTransaction tx1 = db.newReadWriteTransaction();
96                         copyHAPSConfigToChildPS(haPSCfg.get(), childNodePath, tx1);
97                         tx1.submit().checkedGet();
98                     } catch (TransactionCommitFailedException e) {
99                         LOG.error("Failed to process ", e);
100                     }
101                 });
102
103             }
104             copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, tx);
105         }
106         deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, tx);
107     }
108
109     private void deleteChildPSConfigIfHAPSConfigIsMissing(Optional<Node> haPSCfg,
110                                                           Node childNode,
111                                                           ReadWriteTransaction tx) throws ReadFailedException {
112         if (haPSCfg.isPresent()) {
113             return;
114         }
115         LOG.info("HA ps node not present cleanup child {}" , childNode);
116         HwvtepGlobalAugmentation augmentation = childNode.getAugmentation(HwvtepGlobalAugmentation.class);
117         if (augmentation != null) {
118             List<Switches> switches = augmentation.getSwitches();
119             if (switches != null) {
120                 for (Switches ps : switches) {
121                     HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, ps.getSwitchRef().getValue());
122                 }
123             }
124         } else {
125             LOG.info("Global augumentation not present for connected ha child node {}" , childNode);
126         }
127     }
128
129     /**
130      * Merge data of child PS node to HA ps node .
131      *
132      * @param childGlobalNode Ha Global Child node
133      * @param haNodePath Ha node path
134      * @param tx  Transaction
135      * @throws ReadFailedException  Exception thrown if read fails
136      */
137     void readAndCopyChildPSOpToHAPS(Node childGlobalNode,
138                                     InstanceIdentifier<Node> haNodePath,
139                                     ReadWriteTransaction tx)
140             throws ReadFailedException {
141
142         if (childGlobalNode == null || childGlobalNode.getAugmentation(HwvtepGlobalAugmentation.class) == null) {
143             return;
144         }
145         List<Switches> switches = childGlobalNode.getAugmentation(HwvtepGlobalAugmentation.class).getSwitches();
146         if (switches == null) {
147             return;
148         }
149         for (Switches ps : switches) {
150             Node childPsNode = HwvtepHAUtil.readNode(tx, OPERATIONAL,
151                     (InstanceIdentifier<Node>) ps.getSwitchRef().getValue());
152             if (childPsNode != null) {
153                 InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haNodePath);
154                 copyChildPSOpToHAPS(childPsNode, haNodePath, haPsPath, tx);
155             }
156         }
157     }
158
159     /**
160      * Copy HA global node data to Child HA node of config data tree .
161      *
162      * @param srcNode Node which to be transformed
163      * @param childPath Path to which source node will be transformed
164      * @param tx Transaction
165      */
166     private void copyHANodeConfigToChild(Node srcNode,
167                                          InstanceIdentifier<Node> childPath,
168                                          ReadWriteTransaction tx) {
169         if (srcNode == null) {
170             return;
171         }
172         HwvtepGlobalAugmentation src = srcNode.getAugmentation(HwvtepGlobalAugmentation.class);
173         if (src == null) {
174             return;
175         }
176         NodeBuilder nodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(childPath);
177         HwvtepGlobalAugmentationBuilder dstBuilder = new HwvtepGlobalAugmentationBuilder();
178
179         globalAugmentationMerger.mergeConfigData(dstBuilder, src, childPath);
180         globalNodeMerger.mergeConfigData(nodeBuilder, srcNode, childPath);
181         nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, dstBuilder.build());
182         Node dstNode = nodeBuilder.build();
183         tx.put(CONFIGURATION, childPath, dstNode, WriteTransaction.CREATE_MISSING_PARENTS);
184     }
185
186     /**
187      * Copy HA child node to HA node of Operational data tree.
188      *
189      * @param childNode HA Child Node
190      * @param haNodePath HA node path
191      * @param tx Transaction
192      * @throws ReadFailedException  Exception thrown if read fails
193      */
194     private void copyChildOpToHA(Node childNode,
195                                  InstanceIdentifier<Node> haNodePath,
196                                  ReadWriteTransaction tx)
197             throws ReadFailedException {
198         if (childNode == null) {
199             return;
200         }
201         HwvtepGlobalAugmentation childData = childNode.getAugmentation(HwvtepGlobalAugmentation.class);
202         if (childData == null) {
203             return;
204         }
205         NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haNodePath);
206         HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
207
208         Optional<Node> existingHANodeOptional = tx.read(OPERATIONAL, haNodePath).checkedGet();
209         Node existingHANode = existingHANodeOptional.isPresent() ? existingHANodeOptional.get() : null;
210         HwvtepGlobalAugmentation existingHAData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingHANode);
211
212         globalAugmentationMerger.mergeOperationalData(haBuilder, existingHAData, childData, haNodePath);
213         globalNodeMerger.mergeOperationalData(haNodeBuilder, existingHANode, childNode, haNodePath);
214
215         haBuilder.setManagers(HwvtepHAUtil.buildManagersForHANode(childNode, existingHANodeOptional));
216         haBuilder.setSwitches(HwvtepHAUtil.buildSwitchesForHANode(childNode, haNodePath, existingHANodeOptional));
217         haBuilder.setDbVersion(childData.getDbVersion());
218         haNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, haBuilder.build());
219         Node haNode = haNodeBuilder.build();
220         tx.merge(OPERATIONAL, haNodePath, haNode, true);
221     }
222
223     /**
224      * Merge data to Physical switch from HA node path .
225      *
226      * @param psAugmentation  Physical Switch Augmation of Node
227      * @param builder Physical Switch Augmentation Builder
228      * @param haNodePath HA node Path
229      */
230     public void mergeOpManagedByAttributes(PhysicalSwitchAugmentation psAugmentation,
231                                            PhysicalSwitchAugmentationBuilder builder,
232                                            InstanceIdentifier<Node> haNodePath) {
233         builder.setManagedBy(new HwvtepGlobalRef(haNodePath));
234         builder.setHwvtepNodeName(psAugmentation.getHwvtepNodeName());
235         builder.setHwvtepNodeDescription(psAugmentation.getHwvtepNodeDescription());
236         builder.setTunnelIps(psAugmentation.getTunnelIps());
237         builder.setPhysicalSwitchUuid(HwvtepHAUtil.getUUid(psAugmentation.getHwvtepNodeName().getValue()));
238     }
239
240     /**
241      * Copy HA physical switch data to Child Physical switch node of config data tree.
242      *
243      * @param haPsNode HA physical Switch Node
244      * @param childPath HA Child Node path
245      * @param tx Transaction
246      */
247     public void copyHAPSConfigToChildPS(Node haPsNode,
248                                         InstanceIdentifier<Node> childPath,
249                                         ReadWriteTransaction tx) {
250         InstanceIdentifier<Node> childPsPath = HwvtepHAUtil.convertPsPath(haPsNode, childPath);
251
252         NodeBuilder childPsBuilder = HwvtepHAUtil.getNodeBuilderForPath(childPsPath);
253         PhysicalSwitchAugmentationBuilder dstBuilder = new PhysicalSwitchAugmentationBuilder();
254         PhysicalSwitchAugmentation src = haPsNode.getAugmentation(PhysicalSwitchAugmentation.class);
255
256         psAugmentationMerger.mergeConfigData(dstBuilder, src, childPath);
257         psNodeMerger.mergeConfigData(childPsBuilder, haPsNode, childPath);
258
259         childPsBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
260         Node childPSNode = childPsBuilder.build();
261         tx.put(CONFIGURATION, childPsPath, childPSNode, WriteTransaction.CREATE_MISSING_PARENTS);
262     }
263
264     /**
265      * Copy child physical switch node data to HA physical switch data of Operational data tree.
266      *
267      * @param childPsNode HA child PS node
268      * @param haPath  HA node path
269      * @param haPspath Ha Physical Switch Node path
270      * @param tx Transaction
271      * @throws ReadFailedException  Exception thrown if read fails
272      */
273     public void copyChildPSOpToHAPS(Node childPsNode,
274                                     InstanceIdentifier<Node> haPath,
275                                     InstanceIdentifier<Node> haPspath,
276                                     ReadWriteTransaction tx)
277             throws ReadFailedException {
278
279         NodeBuilder haPSNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haPspath);
280         PhysicalSwitchAugmentationBuilder dstBuilder = new PhysicalSwitchAugmentationBuilder();
281
282         PhysicalSwitchAugmentation src = childPsNode.getAugmentation(PhysicalSwitchAugmentation.class);
283
284         Node existingHAPSNode = HwvtepHAUtil.readNode(tx, OPERATIONAL, haPspath);
285         PhysicalSwitchAugmentation existingHAPSAugumentation =
286                 HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingHAPSNode);
287
288         psAugmentationMerger.mergeOperationalData(dstBuilder, existingHAPSAugumentation, src, haPath);
289         psNodeMerger.mergeOperationalData(haPSNodeBuilder, existingHAPSNode, childPsNode, haPath);
290         mergeOpManagedByAttributes(src, dstBuilder, haPath);
291
292         haPSNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
293         Node haPsNode = haPSNodeBuilder.build();
294         tx.merge(OPERATIONAL, haPspath, haPsNode, true);
295     }
296
297 }