4653806a3d74398e3743114eb0f3272ce71c40b2
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / ha / HwvtepHAUtil.java
1 /*
2  * Copyright © 2016, 2017 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;
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 com.google.common.base.Strings;
15 import java.nio.charset.StandardCharsets;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.stream.Collectors;
23 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
24 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
28 import org.opendaylight.netvirt.elan.l2gw.ha.commands.SwitchesCmd;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Managers;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ManagersBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ManagersKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.managers.ManagerOtherConfigs;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.managers.ManagerOtherConfigsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.managers.ManagerOtherConfigsKey;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public final class HwvtepHAUtil {
63
64     private static final Logger LOG = LoggerFactory.getLogger(HwvtepHAUtil.class);
65
66     //TODO reuse HWvtepSouthboundConstants
67     public static final String HA_ENABLED = "ha_enabled";
68     public static final String HWVTEP_ENTITY_TYPE = "hwvtep";
69     public static final String TEP_PREFIX = "vxlan_over_ipv4:";
70     public static final String HA_ID = "ha_id";
71     public static final String HA_CHILDREN = "ha_children";
72     public static final String PHYSICALSWITCH = "/physicalswitch/";
73     public static final TopologyId HWVTEP_TOPOLOGY_ID = new TopologyId(new Uri("hwvtep:1"));
74     public static final String UUID = "uuid";
75     public static final String HWVTEP_URI_PREFIX = "hwvtep";
76     public static final String MANAGER_KEY = "managerKey";
77     public static final String L2GW_JOB_KEY = ":l2gw";
78
79     private HwvtepHAUtil() { }
80
81     public static HwvtepPhysicalLocatorRef buildLocatorRef(InstanceIdentifier<Node> nodeIid, String tepIp) {
82         InstanceIdentifier<TerminationPoint> tepId = buildTpId(nodeIid, tepIp);
83         return new HwvtepPhysicalLocatorRef(tepId);
84     }
85
86     public static String getNodeIdVal(InstanceIdentifier<?> iid) {
87         return iid.firstKeyOf(Node.class).getNodeId().getValue();
88     }
89
90     public static Uuid getUUid(String key) {
91         return new Uuid(java.util.UUID.nameUUIDFromBytes(key.getBytes(StandardCharsets.UTF_8)).toString());
92     }
93
94     public static InstanceIdentifier<TerminationPoint> buildTpId(InstanceIdentifier<Node> nodeIid,String tepIp) {
95         String tpKeyStr = TEP_PREFIX + tepIp;
96         TerminationPointKey tpKey = new TerminationPointKey(new TpId(tpKeyStr));
97         InstanceIdentifier<TerminationPoint> plIid = nodeIid.child(TerminationPoint.class, tpKey);
98         return plIid;
99     }
100
101     public static String getTepIpVal(HwvtepPhysicalLocatorRef locatorRef) {
102         InstanceIdentifier<TerminationPoint> tpId = (InstanceIdentifier<TerminationPoint>) locatorRef.getValue();
103         return tpId.firstKeyOf(TerminationPoint.class).getTpId().getValue().substring("vxlan_over_ipv4:".length());
104     }
105
106     public static String getLogicalSwitchSwitchName(HwvtepLogicalSwitchRef logicalSwitchRef) {
107         InstanceIdentifier<LogicalSwitches> id = (InstanceIdentifier<LogicalSwitches>) logicalSwitchRef.getValue();
108         return id.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue();
109     }
110
111     public static String getNodeIdFromLocatorRef(HwvtepPhysicalLocatorRef locatorRef) {
112         InstanceIdentifier<TerminationPoint> tpId = (InstanceIdentifier<TerminationPoint>) locatorRef.getValue();
113         return tpId.firstKeyOf(Node.class).getNodeId().getValue();
114     }
115
116     public static String getNodeIdFromLogicalSwitches(HwvtepLogicalSwitchRef logicalSwitchRef) {
117         InstanceIdentifier<LogicalSwitches> id = (InstanceIdentifier<LogicalSwitches>) logicalSwitchRef.getValue();
118         return id.firstKeyOf(Node.class).getNodeId().getValue();
119     }
120
121     public static InstanceIdentifier<Node> createInstanceIdentifierFromHAId(String haUUidVal) {
122         String nodeString = HWVTEP_URI_PREFIX + "://"
123             + UUID + "/" + java.util.UUID.nameUUIDFromBytes(haUUidVal.getBytes(StandardCharsets.UTF_8)).toString();
124         NodeId nodeId = new NodeId(new Uri(nodeString));
125         NodeKey nodeKey = new NodeKey(nodeId);
126         TopologyKey topoKey = new TopologyKey(HWVTEP_TOPOLOGY_ID);
127         return InstanceIdentifier.builder(NetworkTopology.class)
128                 .child(Topology.class, topoKey)
129                 .child(Node.class, nodeKey)
130                 .build();
131     }
132
133     public static InstanceIdentifier<Node> convertToInstanceIdentifier(String nodeIdString) {
134         NodeId nodeId = new NodeId(new Uri(nodeIdString));
135         NodeKey nodeKey = new NodeKey(nodeId);
136         TopologyKey topoKey = new TopologyKey(HWVTEP_TOPOLOGY_ID);
137         return InstanceIdentifier.builder(NetworkTopology.class)
138                 .child(Topology.class, topoKey)
139                 .child(Node.class, nodeKey)
140                 .build();
141     }
142
143     /**
144      * Build other config data for HA node .
145      *
146      * @param key The key as in HA child device other config
147      * @param val The value as in HA child device other config
148      * @return return other config object
149      */
150     public static ManagerOtherConfigsBuilder getOtherConfigBuilder(String key, String val) {
151         ManagerOtherConfigsBuilder otherConfigsBuilder = new ManagerOtherConfigsBuilder();
152         ManagerOtherConfigsKey otherConfigsKey = new ManagerOtherConfigsKey(key);
153         otherConfigsBuilder.setKey(otherConfigsKey);
154         otherConfigsBuilder.setOtherConfigKey(key);
155         otherConfigsBuilder.setOtherConfigValue(val);
156         return otherConfigsBuilder;
157     }
158
159     public static Node readNode(ReadWriteTransaction tx, LogicalDatastoreType storeType,
160                                 InstanceIdentifier<Node> nodeId)
161             throws ReadFailedException {
162         Optional<Node> optional = tx.read(storeType, nodeId).checkedGet();
163         if (optional.isPresent()) {
164             return optional.get();
165         }
166         return null;
167     }
168
169     public static String convertToGlobalNodeId(String psNodeId) {
170         int idx = psNodeId.indexOf(PHYSICALSWITCH);
171         if (idx > 0) {
172             return psNodeId.substring(0, idx);
173         }
174         return psNodeId;
175     }
176
177     /**
178      * Trnaform logical switch to nodepath passed .
179      *
180      * @param src {@link HwvtepLogicalSwitchRef} Logical Switch Ref which needs to be transformed
181      * @param nodePath {@link InstanceIdentifier} src needs to be transformed to this path
182      * @return ref {@link HwvtepLogicalSwitchRef} the transforrmed result
183      */
184     public static HwvtepLogicalSwitchRef convertLogicalSwitchRef(HwvtepLogicalSwitchRef src,
185                                                                  InstanceIdentifier<Node> nodePath) {
186         InstanceIdentifier<LogicalSwitches> srcId = (InstanceIdentifier<LogicalSwitches>)src.getValue();
187         HwvtepNodeName switchName = srcId.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName();
188         InstanceIdentifier<LogicalSwitches> iid = nodePath.augmentation(HwvtepGlobalAugmentation.class)
189                 .child(LogicalSwitches.class, new LogicalSwitchesKey(switchName));
190         HwvtepLogicalSwitchRef ref = new HwvtepLogicalSwitchRef(iid);
191         return ref;
192     }
193
194     /**
195      * Trnaform locator reference to nodepath passed .
196      *
197      * @param src {@link HwvtepPhysicalLocatorRef} Logical Switch Ref which needs to be transformed
198      * @param nodePath {@link InstanceIdentifier} src needs to be transformed to this path
199      * @return physicalLocatorRef {@link HwvtepPhysicalLocatorRef} the transforrmed result
200      */
201     public static HwvtepPhysicalLocatorRef convertLocatorRef(HwvtepPhysicalLocatorRef src,
202                                                              InstanceIdentifier<Node> nodePath) {
203         InstanceIdentifier<TerminationPoint> srcTepPath = (InstanceIdentifier<TerminationPoint>)src.getValue();
204         TpId tpId = srcTepPath.firstKeyOf(TerminationPoint.class).getTpId();
205         InstanceIdentifier<TerminationPoint> tpPath =
206                 nodePath.child(TerminationPoint.class, new TerminationPointKey(tpId));
207         HwvtepPhysicalLocatorRef physicalLocatorRef = new HwvtepPhysicalLocatorRef(tpPath);
208         return physicalLocatorRef;
209     }
210
211     public static boolean isEmptyList(List list) {
212         return list == null || list.isEmpty();
213     }
214
215     public static boolean isEmpty(Collection collection) {
216         if (collection == null || collection.isEmpty()) {
217             return true;
218         }
219         return false;
220     }
221
222     public static Node getOriginal(DataObjectModification<Node> mod) {
223         Node node = null;
224         switch (mod.getModificationType()) {
225             case SUBTREE_MODIFIED:
226             case DELETE:
227                 node = mod.getDataBefore();
228                 break;
229             case WRITE:
230                 if (mod.getDataBefore() !=  null) {
231                     node = mod.getDataBefore();
232                 }
233                 break;
234             default:
235                 break;
236         }
237         return node;
238     }
239
240     public static Node getUpdated(DataObjectModification<Node> mod) {
241         Node node = null;
242         switch (mod.getModificationType()) {
243             case SUBTREE_MODIFIED:
244                 node = mod.getDataAfter();
245                 break;
246             case WRITE:
247                 if (mod.getDataAfter() !=  null) {
248                     node = mod.getDataAfter();
249                 }
250                 break;
251             default:
252                 break;
253         }
254         return node;
255     }
256
257     public static Node getCreated(DataObjectModification<Node> mod) {
258         if (mod.getModificationType() == DataObjectModification.ModificationType.WRITE
259                 && mod.getDataBefore() == null) {
260             return mod.getDataAfter();
261         }
262         return null;
263     }
264
265     public static Node getRemoved(DataObjectModification<Node> mod) {
266         if (mod.getModificationType() == DataObjectModification.ModificationType.DELETE) {
267             return mod.getDataBefore();
268         }
269         return null;
270     }
271
272     public static String getPsName(Node psNode) {
273         String psNodeId = psNode.getNodeId().getValue();
274         if (psNodeId.contains(PHYSICALSWITCH)) {
275             return psNodeId.substring(psNodeId.indexOf(PHYSICALSWITCH) + PHYSICALSWITCH.length());
276         }
277         return null;
278     }
279
280     public static String getPsName(InstanceIdentifier<Node> psNodeIid) {
281         String psNodeId = psNodeIid.firstKeyOf(Node.class).getNodeId().getValue();
282         if (psNodeId.contains(PHYSICALSWITCH)) {
283             return psNodeId.substring(psNodeId.indexOf(PHYSICALSWITCH) +  PHYSICALSWITCH.length());
284         }
285         return null;
286     }
287
288     public static InstanceIdentifier<Node> getGlobalNodePathFromPSNode(Node psNode) {
289         String psNodeId = psNode.getNodeId().getValue();
290         if (psNodeId.contains(PHYSICALSWITCH)) {
291             return convertToInstanceIdentifier(psNodeId.substring(0, psNodeId.indexOf(PHYSICALSWITCH)));
292         }
293         return convertToInstanceIdentifier(psNodeId);
294     }
295
296     public static InstanceIdentifier<Node> convertPsPath(Node psNode, InstanceIdentifier<Node> nodePath) {
297         String psNodeId = psNode.getNodeId().getValue();
298         if (psNodeId.contains(PHYSICALSWITCH)) {
299             String psName = psNodeId.substring(psNodeId.indexOf(PHYSICALSWITCH) + PHYSICALSWITCH.length());
300             String haPsNodeIdVal = nodePath.firstKeyOf(Node.class).getNodeId().getValue() + PHYSICALSWITCH + psName;
301             InstanceIdentifier<Node> haPsPath = convertToInstanceIdentifier(haPsNodeIdVal);
302             return haPsPath;
303         } else {
304             LOG.error("Failed to find ps path from node {}", psNode);
305             return null;
306         }
307     }
308
309     public static NodeBuilder getNodeBuilderForPath(InstanceIdentifier<Node> haPath) {
310         NodeBuilder nodeBuilder = new NodeBuilder();
311         nodeBuilder.setNodeId(haPath.firstKeyOf(Node.class).getNodeId());
312         return nodeBuilder;
313     }
314
315     public static String getHAIdFromManagerOtherConfig(Node node) {
316         if (node.getAugmentation(HwvtepGlobalAugmentation.class) == null) {
317             return null;
318         }
319         HwvtepGlobalAugmentation globalAugmentation = node.getAugmentation(HwvtepGlobalAugmentation.class);
320         if (globalAugmentation != null) {
321             List<Managers> managers = globalAugmentation.getManagers();
322             if (managers != null && managers.size() > 0 && managers.get(0).getManagerOtherConfigs() != null) {
323                 for (ManagerOtherConfigs configs : managers.get(0).getManagerOtherConfigs()) {
324                     if (configs.getOtherConfigKey().equals(HA_ID)) {
325                         return configs.getOtherConfigValue();
326                     }
327                 }
328             }
329         }
330         return null;
331     }
332
333     /**
334      * Returns ha child node path from ha node of config data tree.
335      *
336      * @param haGlobalConfigNodeOptional HA global node
337      * @return ha Child ids
338      */
339     public static  List<NodeId> getChildNodeIdsFromManagerOtherConfig(Optional<Node> haGlobalConfigNodeOptional) {
340         List<NodeId> childNodeIds = new ArrayList<>();
341         if (!haGlobalConfigNodeOptional.isPresent()) {
342             return childNodeIds;
343         }
344         HwvtepGlobalAugmentation augmentation =
345                 haGlobalConfigNodeOptional.get().getAugmentation(HwvtepGlobalAugmentation.class);
346         if (augmentation != null && augmentation.getManagers() != null
347                 && augmentation.getManagers().size() > 0) {
348             Managers managers = augmentation.getManagers().get(0);
349             if (null == managers.getManagerOtherConfigs()) {
350                 return childNodeIds;
351             }
352             for (ManagerOtherConfigs otherConfigs : managers.getManagerOtherConfigs()) {
353                 if (otherConfigs.getOtherConfigKey().equals(HA_CHILDREN)) {
354                     String nodeIdsVal = otherConfigs.getOtherConfigValue();
355                     if (nodeIdsVal != null) {
356                         String[] parts = nodeIdsVal.split(",");
357                         for (String part : parts) {
358                             childNodeIds.add(new NodeId(part));
359                         }
360                     }
361
362                 }
363             }
364         }
365         return childNodeIds;
366     }
367
368     public static HwvtepGlobalAugmentation getGlobalAugmentationOfNode(Node node) {
369         HwvtepGlobalAugmentation result = null;
370         if (node != null) {
371             result = node.getAugmentation(HwvtepGlobalAugmentation.class);
372         }
373         if (result == null) {
374             result = new HwvtepGlobalAugmentationBuilder().build();
375         }
376         return result;
377     }
378
379     public static PhysicalSwitchAugmentation getPhysicalSwitchAugmentationOfNode(Node psNode) {
380         PhysicalSwitchAugmentation result = null;
381         if (psNode != null) {
382             result = psNode.getAugmentation(PhysicalSwitchAugmentation.class);
383         }
384         if (result == null) {
385             result = new PhysicalSwitchAugmentationBuilder().build();
386         }
387         return result;
388     }
389
390     /**
391      * Transform child managers (Source) to HA managers using HA node path.
392      *
393      * @param childNode Child Node
394      * @param haGlobalCfg HA global config node
395      * @return Transformed managers
396      */
397     public static List<Managers> buildManagersForHANode(Node childNode, Optional<Node> haGlobalCfg) {
398
399         Set<NodeId> nodeIds = new HashSet<>();
400         nodeIds.add(childNode.getNodeId());
401         List<NodeId> childNodeIds = getChildNodeIdsFromManagerOtherConfig(haGlobalCfg);
402         nodeIds.addAll(childNodeIds);
403
404         ManagersBuilder builder1 = new ManagersBuilder();
405
406         builder1.setKey(new ManagersKey(new Uri(MANAGER_KEY)));
407         List<ManagerOtherConfigs> otherConfigses = new ArrayList<>();
408         String children = nodeIds.stream().map(NodeId::getValue).collect(Collectors.joining(","));
409         otherConfigses.add(getOtherConfigBuilder(HA_CHILDREN, children).build());
410         builder1.setManagerOtherConfigs(otherConfigses);
411         List<Managers> managers = new ArrayList<>();
412         managers.add(builder1.build());
413         return managers;
414     }
415
416     /**
417      * Transform child switch (Source) to HA swicthes using HA node path.
418      *
419      * @param childNode  HA child node
420      * @param haNodePath  HA node path
421      * @param haNode Ha node object
422      * @return Transformed switches
423      */
424     public static List<Switches> buildSwitchesForHANode(Node childNode,
425                                                         InstanceIdentifier<Node> haNodePath,
426                                                         Optional<Node> haNode) {
427         List<Switches> psList = new ArrayList<>();
428         boolean switchesAlreadyPresent = false;
429         if (haNode.isPresent()) {
430             Node node = haNode.get();
431             HwvtepGlobalAugmentation augmentation = node.getAugmentation(HwvtepGlobalAugmentation.class);
432             if (augmentation != null) {
433                 if (augmentation.getSwitches() != null) {
434                     if (augmentation.getSwitches().size() > 0) {
435                         switchesAlreadyPresent = true;
436                     }
437                 }
438             }
439         }
440         if (!switchesAlreadyPresent) {
441             HwvtepGlobalAugmentation augmentation = childNode.getAugmentation(HwvtepGlobalAugmentation.class);
442             if (augmentation != null && augmentation.getSwitches() != null) {
443                 List<Switches> src = augmentation.getSwitches();
444                 if (src != null && src.size() > 0) {
445                     psList.add(new SwitchesCmd().transform(haNodePath, src.get(0)));
446                 }
447             }
448         }
449         return psList;
450     }
451
452     /**
453      * Build HA Global node from child nodes in config data tress.
454      *
455      * @param tx Transaction
456      * @param childNode Child Node object
457      * @param haNodePath Ha node path
458      * @param haGlobalCfg HA global node object
459      */
460     public static void buildGlobalConfigForHANode(ReadWriteTransaction tx,
461                                                   Node childNode,
462                                                   InstanceIdentifier<Node> haNodePath,
463                                                   Optional<Node> haGlobalCfg) {
464
465         NodeBuilder nodeBuilder = new NodeBuilder();
466         HwvtepGlobalAugmentationBuilder hwvtepGlobalBuilder = new HwvtepGlobalAugmentationBuilder();
467         hwvtepGlobalBuilder.setSwitches(buildSwitchesForHANode(childNode, haNodePath, haGlobalCfg));
468         hwvtepGlobalBuilder.setManagers(buildManagersForHANode(childNode, haGlobalCfg));
469
470         nodeBuilder.setNodeId(haNodePath.firstKeyOf(Node.class).getNodeId());
471         nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, hwvtepGlobalBuilder.build());
472         Node configHANode = nodeBuilder.build();
473         tx.merge(CONFIGURATION, haNodePath, configHANode,Boolean.TRUE);
474     }
475
476     public static void deleteNodeIfPresent(ReadWriteTransaction tx,
477                                            LogicalDatastoreType logicalDatastoreType,
478                                            InstanceIdentifier<?> iid) throws ReadFailedException {
479         if (tx.read(logicalDatastoreType, iid).checkedGet().isPresent()) {
480             LOG.info("Deleting child node {}", getNodeIdVal(iid));
481             tx.delete(logicalDatastoreType, iid);
482         }
483     }
484
485     /**
486      * Delete PS data of HA node of Config Data tree.
487      *
488      * @param key Node object
489      * @param haNode Ha Node from which to be deleted
490      * @param tx Transaction
491      * @throws ReadFailedException  Exception thrown if read fails
492      */
493     public static void deletePSNodesOfNode(InstanceIdentifier<Node> key,
494                                            Node haNode,
495                                            ReadWriteTransaction tx)
496             throws ReadFailedException {
497         //read from switches attribute and clean up them
498         HwvtepGlobalAugmentation globalAugmentation = haNode.getAugmentation(HwvtepGlobalAugmentation.class);
499         if (globalAugmentation == null) {
500             return;
501         }
502         HashMap<InstanceIdentifier<Node>,Boolean> deleted = new HashMap<>();
503         List<Switches> switches = globalAugmentation.getSwitches();
504         if (switches != null) {
505             for (Switches switche : switches) {
506                 InstanceIdentifier<Node> psId = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
507                 deleteNodeIfPresent(tx, CONFIGURATION, psId);
508                 deleted.put(psId, Boolean.TRUE);
509             }
510         }
511         //also read from managed by attribute of switches and cleanup them as a back up if the above cleanup fails
512         Optional<Topology> topologyOptional = tx
513                 .read(CONFIGURATION, key.firstIdentifierOf(Topology.class)).checkedGet();
514         String deletedNodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
515         if (topologyOptional.isPresent()) {
516             Topology topology = topologyOptional.get();
517             if (topology.getNode() != null) {
518                 for (Node psNode : topology.getNode()) {
519                     PhysicalSwitchAugmentation ps = psNode.getAugmentation(PhysicalSwitchAugmentation.class);
520                     if (ps != null) {
521                         InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>)ps.getManagedBy().getValue();
522                         String nodeIdVal = iid.firstKeyOf(Node.class).getNodeId().getValue();
523                         if (deletedNodeId.equals(nodeIdVal)) {
524                             InstanceIdentifier<Node> psNodeId =
525                                     convertToInstanceIdentifier(psNode.getNodeId().getValue());
526                             if (deleted.containsKey(psNodeId)) {
527                                 deleteNodeIfPresent(tx, CONFIGURATION, psNodeId);
528                             }
529                         }
530                     }
531                 }
532             }
533         }
534     }
535
536     /**
537      * Delete switches from Node in Operational Data Tree .
538      *
539      * @param haPath HA node path from whih switches will be deleted
540      * @param tx  Transaction object
541      * @throws ReadFailedException  Exception thrown if read fails
542      */
543     public static void deleteSwitchesManagedByNode(InstanceIdentifier<Node> haPath,
544                                                    ReadWriteTransaction tx)
545             throws ReadFailedException {
546
547         Optional<Node> nodeOptional = tx.read(OPERATIONAL, haPath).checkedGet();
548         if (!nodeOptional.isPresent()) {
549             return;
550         }
551         Node node = nodeOptional.get();
552         HwvtepGlobalAugmentation globalAugmentation = node.getAugmentation(HwvtepGlobalAugmentation.class);
553         if (globalAugmentation == null) {
554             return;
555         }
556         List<Switches> switches = globalAugmentation.getSwitches();
557         if (switches != null) {
558             for (Switches switche : switches) {
559                 InstanceIdentifier<Node> id = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
560                 deleteNodeIfPresent(tx, OPERATIONAL, id);
561             }
562         }
563     }
564
565     /**
566      * Returns true/false if all the childrens are deleted from Operational Data store.
567      *
568      * @param children IID for the child node to read from OP data tree
569      * @param tx Transaction
570      * @return true/false boolean
571      * @throws ReadFailedException Exception thrown if read fails
572      */
573     public static boolean areAllChildDeleted(Set<InstanceIdentifier<Node>> children,
574                                              ReadWriteTransaction tx) throws ReadFailedException {
575         for (InstanceIdentifier<Node> childId : children) {
576             if (tx.read(OPERATIONAL, childId).checkedGet().isPresent()) {
577                 return false;
578             }
579         }
580         return true;
581     }
582
583     public static void addToCacheIfHAChildNode(InstanceIdentifier<Node> childPath, Node childNode,
584             HwvtepNodeHACache hwvtepNodeHACache) {
585         String haId = HwvtepHAUtil.getHAIdFromManagerOtherConfig(childNode);
586         if (!Strings.isNullOrEmpty(haId)) {
587             InstanceIdentifier<Node> parentId = HwvtepHAUtil.createInstanceIdentifierFromHAId(haId);
588             hwvtepNodeHACache.addChild(parentId, childPath/*child*/);
589         }
590     }
591 }