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
8 package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
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;
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;
39 public class NodeConnectedHandler {
41 private static final Logger LOG = LoggerFactory.getLogger(NodeConnectedHandler.class);
43 GlobalAugmentationMerger globalAugmentationMerger = GlobalAugmentationMerger.getInstance();
44 PSAugmentationMerger psAugmentationMerger = PSAugmentationMerger.getInstance();
45 GlobalNodeMerger globalNodeMerger = GlobalNodeMerger.getInstance();
46 PSNodeMerger psNodeMerger = PSNodeMerger.getInstance();
48 HwvtepHACache hwvtepHACache = HwvtepHACache.getInstance();
50 public NodeConnectedHandler(DataBroker db) {
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 .
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
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()) {
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)
90 HAJobScheduler.getInstance().submitJob(() -> {
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);
104 copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, tx);
106 deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, tx);
109 private void deleteChildPSConfigIfHAPSConfigIsMissing(Optional<Node> haPSCfg,
111 ReadWriteTransaction tx) throws ReadFailedException {
112 if (haPSCfg.isPresent()) {
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());
125 LOG.info("Global augumentation not present for connected ha child node {}" , childNode);
130 * Merge data of child PS node to HA ps node .
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
137 void readAndCopyChildPSOpToHAPS(Node childGlobalNode,
138 InstanceIdentifier<Node> haNodePath,
139 ReadWriteTransaction tx)
140 throws ReadFailedException {
142 if (childGlobalNode == null || childGlobalNode.getAugmentation(HwvtepGlobalAugmentation.class) == null) {
145 List<Switches> switches = childGlobalNode.getAugmentation(HwvtepGlobalAugmentation.class).getSwitches();
146 if (switches == null) {
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);
160 * Copy HA global node data to Child HA node of config data tree .
162 * @param srcNode Node which to be transformed
163 * @param childPath Path to which source node will be transformed
164 * @param tx Transaction
166 private void copyHANodeConfigToChild(Node srcNode,
167 InstanceIdentifier<Node> childPath,
168 ReadWriteTransaction tx) {
169 if (srcNode == null) {
172 HwvtepGlobalAugmentation src = srcNode.getAugmentation(HwvtepGlobalAugmentation.class);
176 NodeBuilder nodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(childPath);
177 HwvtepGlobalAugmentationBuilder dstBuilder = new HwvtepGlobalAugmentationBuilder();
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);
187 * Copy HA child node to HA node of Operational data tree.
189 * @param childNode HA Child Node
190 * @param haNodePath HA node path
191 * @param tx Transaction
192 * @throws ReadFailedException Exception thrown if read fails
194 private void copyChildOpToHA(Node childNode,
195 InstanceIdentifier<Node> haNodePath,
196 ReadWriteTransaction tx)
197 throws ReadFailedException {
198 if (childNode == null) {
201 HwvtepGlobalAugmentation childData = childNode.getAugmentation(HwvtepGlobalAugmentation.class);
202 if (childData == null) {
205 NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haNodePath);
206 HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
208 Optional<Node> existingHANodeOptional = tx.read(OPERATIONAL, haNodePath).checkedGet();
209 Node existingHANode = existingHANodeOptional.isPresent() ? existingHANodeOptional.get() : null;
210 HwvtepGlobalAugmentation existingHAData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingHANode);
212 globalAugmentationMerger.mergeOperationalData(haBuilder, existingHAData, childData, haNodePath);
213 globalNodeMerger.mergeOperationalData(haNodeBuilder, existingHANode, childNode, haNodePath);
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);
224 * Merge data to Physical switch from HA node path .
226 * @param psAugmentation Physical Switch Augmation of Node
227 * @param builder Physical Switch Augmentation Builder
228 * @param haNodePath HA node Path
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()));
241 * Copy HA physical switch data to Child Physical switch node of config data tree.
243 * @param haPsNode HA physical Switch Node
244 * @param childPath HA Child Node path
245 * @param tx Transaction
247 public void copyHAPSConfigToChildPS(Node haPsNode,
248 InstanceIdentifier<Node> childPath,
249 ReadWriteTransaction tx) {
250 InstanceIdentifier<Node> childPsPath = HwvtepHAUtil.convertPsPath(haPsNode, childPath);
252 NodeBuilder childPsBuilder = HwvtepHAUtil.getNodeBuilderForPath(childPsPath);
253 PhysicalSwitchAugmentationBuilder dstBuilder = new PhysicalSwitchAugmentationBuilder();
254 PhysicalSwitchAugmentation src = haPsNode.getAugmentation(PhysicalSwitchAugmentation.class);
256 psAugmentationMerger.mergeConfigData(dstBuilder, src, childPath);
257 psNodeMerger.mergeConfigData(childPsBuilder, haPsNode, childPath);
259 childPsBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
260 Node childPSNode = childPsBuilder.build();
261 tx.put(CONFIGURATION, childPsPath, childPSNode, WriteTransaction.CREATE_MISSING_PARENTS);
265 * Copy child physical switch node data to HA physical switch data of Operational data tree.
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
273 public void copyChildPSOpToHAPS(Node childPsNode,
274 InstanceIdentifier<Node> haPath,
275 InstanceIdentifier<Node> haPspath,
276 ReadWriteTransaction tx)
277 throws ReadFailedException {
279 NodeBuilder haPSNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haPspath);
280 PhysicalSwitchAugmentationBuilder dstBuilder = new PhysicalSwitchAugmentationBuilder();
282 PhysicalSwitchAugmentation src = childPsNode.getAugmentation(PhysicalSwitchAugmentation.class);
284 Node existingHAPSNode = HwvtepHAUtil.readNode(tx, OPERATIONAL, haPspath);
285 PhysicalSwitchAugmentation existingHAPSAugumentation =
286 HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingHAPSNode);
288 psAugmentationMerger.mergeOperationalData(dstBuilder, existingHAPSAugumentation, src, haPath);
289 psNodeMerger.mergeOperationalData(haPSNodeBuilder, existingHAPSNode, childPsNode, haPath);
290 mergeOpManagedByAttributes(src, dstBuilder, haPath);
292 haPSNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
293 Node haPsNode = haPSNodeBuilder.build();
294 tx.merge(OPERATIONAL, haPspath, haPsNode, true);