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