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