2 * Copyright © 2016, 2017 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;
11 import com.google.common.base.Strings;
12 import java.nio.charset.StandardCharsets;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
19 import java.util.Optional;
21 import java.util.concurrent.ExecutionException;
22 import java.util.stream.Collectors;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
25 import org.opendaylight.mdsal.binding.api.DataObjectModification;
26 import org.opendaylight.mdsal.binding.util.Datastore;
27 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
28 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
29 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
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.SwitchesKey;
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;
65 public final class HwvtepHAUtil {
67 private static final Logger LOG = LoggerFactory.getLogger(HwvtepHAUtil.class);
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 public static final String L2GW_JOB_KEY = ":l2gw";
82 private HwvtepHAUtil() {
86 public static HwvtepPhysicalLocatorRef buildLocatorRef(InstanceIdentifier<Node> nodeIid, String tepIp) {
87 InstanceIdentifier<TerminationPoint> tepId = buildTpId(nodeIid, tepIp);
88 return new HwvtepPhysicalLocatorRef(tepId);
91 public static String getNodeIdVal(InstanceIdentifier<?> iid) {
92 return iid.firstKeyOf(Node.class).getNodeId().getValue();
95 public static Uuid getUUid(String key) {
96 return new Uuid(java.util.UUID.nameUUIDFromBytes(key.getBytes(StandardCharsets.UTF_8)).toString());
99 public static InstanceIdentifier<TerminationPoint> buildTpId(InstanceIdentifier<Node> nodeIid,String tepIp) {
100 String tpKeyStr = TEP_PREFIX + tepIp;
101 TerminationPointKey tpKey = new TerminationPointKey(new TpId(tpKeyStr));
102 InstanceIdentifier<TerminationPoint> plIid = nodeIid.child(TerminationPoint.class, tpKey);
106 public static String getTepIpVal(HwvtepPhysicalLocatorRef locatorRef) {
107 InstanceIdentifier<TerminationPoint> tpId = (InstanceIdentifier<TerminationPoint>) locatorRef.getValue();
108 return tpId.firstKeyOf(TerminationPoint.class).getTpId().getValue().substring("vxlan_over_ipv4:".length());
111 public static InstanceIdentifier<Node> createInstanceIdentifierFromHAId(String haUUidVal) {
112 String nodeString = HWVTEP_URI_PREFIX + "://"
113 + UUID + "/" + java.util.UUID.nameUUIDFromBytes(haUUidVal.getBytes(StandardCharsets.UTF_8)).toString();
114 NodeId nodeId = new NodeId(new Uri(nodeString));
115 NodeKey nodeKey = new NodeKey(nodeId);
116 TopologyKey topoKey = new TopologyKey(HWVTEP_TOPOLOGY_ID);
117 return InstanceIdentifier.builder(NetworkTopology.class)
118 .child(Topology.class, topoKey)
119 .child(Node.class, nodeKey)
123 public static InstanceIdentifier<Node> convertToInstanceIdentifier(String nodeIdString) {
124 NodeId nodeId = new NodeId(new Uri(nodeIdString));
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)
134 * Build other config data for HA node .
136 * @param key The key as in HA child device other config
137 * @param val The value as in HA child device other config
138 * @return return other config object
140 public static ManagerOtherConfigsBuilder getOtherConfigBuilder(String key, String val) {
141 ManagerOtherConfigsBuilder otherConfigsBuilder = new ManagerOtherConfigsBuilder();
142 ManagerOtherConfigsKey otherConfigsKey = new ManagerOtherConfigsKey(key);
143 otherConfigsBuilder.withKey(otherConfigsKey);
144 otherConfigsBuilder.setOtherConfigKey(key);
145 otherConfigsBuilder.setOtherConfigValue(val);
146 return otherConfigsBuilder;
149 public static String convertToGlobalNodeId(String psNodeId) {
150 int idx = psNodeId.indexOf(PHYSICALSWITCH);
152 return psNodeId.substring(0, idx);
158 * Trnaform logical switch to nodepath passed .
160 * @param src {@link HwvtepLogicalSwitchRef} Logical Switch Ref which needs to be transformed
161 * @param nodePath {@link InstanceIdentifier} src needs to be transformed to this path
162 * @return ref {@link HwvtepLogicalSwitchRef} the transforrmed result
164 public static HwvtepLogicalSwitchRef convertLogicalSwitchRef(HwvtepLogicalSwitchRef src,
165 InstanceIdentifier<Node> nodePath) {
166 InstanceIdentifier<LogicalSwitches> srcId = (InstanceIdentifier<LogicalSwitches>)src.getValue();
167 HwvtepNodeName switchName = srcId.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName();
168 InstanceIdentifier<LogicalSwitches> iid = nodePath.augmentation(HwvtepGlobalAugmentation.class)
169 .child(LogicalSwitches.class, new LogicalSwitchesKey(switchName));
170 HwvtepLogicalSwitchRef ref = new HwvtepLogicalSwitchRef(iid);
175 * Trnaform locator reference to nodepath passed .
177 * @param src {@link HwvtepPhysicalLocatorRef} Logical Switch Ref which needs to be transformed
178 * @param nodePath {@link InstanceIdentifier} src needs to be transformed to this path
179 * @return physicalLocatorRef {@link HwvtepPhysicalLocatorRef} the transforrmed result
181 public static HwvtepPhysicalLocatorRef convertLocatorRef(HwvtepPhysicalLocatorRef src,
182 InstanceIdentifier<Node> nodePath) {
183 InstanceIdentifier<TerminationPoint> srcTepPath = (InstanceIdentifier<TerminationPoint>)src.getValue();
184 TpId tpId = srcTepPath.firstKeyOf(TerminationPoint.class).getTpId();
185 InstanceIdentifier<TerminationPoint> tpPath =
186 nodePath.child(TerminationPoint.class, new TerminationPointKey(tpId));
187 HwvtepPhysicalLocatorRef physicalLocatorRef = new HwvtepPhysicalLocatorRef(tpPath);
188 return physicalLocatorRef;
191 public static boolean isEmptyList(@Nullable List list) {
192 return list == null || list.isEmpty();
195 public static boolean isEmpty(Collection collection) {
196 return collection == null || collection.isEmpty();
200 public static Node getOriginal(DataObjectModification<Node> mod) {
202 switch (mod.getModificationType()) {
203 case SUBTREE_MODIFIED:
205 node = mod.getDataBefore();
208 if (mod.getDataBefore() != null) {
209 node = mod.getDataBefore();
219 public static Node getUpdated(DataObjectModification<Node> mod) {
220 switch (mod.getModificationType()) {
221 case SUBTREE_MODIFIED:
223 return mod.getDataAfter();
230 public static Node getCreated(DataObjectModification<Node> mod) {
231 if (mod.getModificationType() == DataObjectModification.ModificationType.WRITE
232 && mod.getDataBefore() == null) {
233 return mod.getDataAfter();
239 public static Node getRemoved(DataObjectModification<Node> mod) {
240 if (mod.getModificationType() == DataObjectModification.ModificationType.DELETE) {
241 return mod.getDataBefore();
247 public static String getPsName(InstanceIdentifier<Node> psNodeIid) {
248 String psNodeId = psNodeIid.firstKeyOf(Node.class).getNodeId().getValue();
249 if (psNodeId.contains(PHYSICALSWITCH)) {
250 return psNodeId.substring(psNodeId.indexOf(PHYSICALSWITCH) + PHYSICALSWITCH.length());
256 public static String getPsName(String psNodeId) {
257 if (psNodeId.contains(PHYSICALSWITCH)) {
258 return psNodeId.substring(psNodeId.indexOf(PHYSICALSWITCH) + PHYSICALSWITCH.length());
263 public static InstanceIdentifier<Node> getGlobalNodePathFromPSNode(Node psNode) {
264 String psNodeId = psNode.getNodeId().getValue();
265 if (psNodeId.contains(PHYSICALSWITCH)) {
266 return convertToInstanceIdentifier(psNodeId.substring(0, psNodeId.indexOf(PHYSICALSWITCH)));
268 return convertToInstanceIdentifier(psNodeId);
272 public static InstanceIdentifier<Node> convertPsPath(Node psNode, InstanceIdentifier<Node> nodePath) {
273 String psNodeId = psNode.getNodeId().getValue();
274 if (psNodeId.contains(PHYSICALSWITCH)) {
275 String psName = psNodeId.substring(psNodeId.indexOf(PHYSICALSWITCH) + PHYSICALSWITCH.length());
276 String haPsNodeIdVal = nodePath.firstKeyOf(Node.class).getNodeId().getValue() + PHYSICALSWITCH + psName;
277 InstanceIdentifier<Node> haPsPath = convertToInstanceIdentifier(haPsNodeIdVal);
280 LOG.error("Failed to find ps path from node {}", psNode);
285 public static NodeBuilder getNodeBuilderForPath(InstanceIdentifier<Node> haPath) {
286 NodeBuilder nodeBuilder = new NodeBuilder();
287 nodeBuilder.setNodeId(haPath.firstKeyOf(Node.class).getNodeId());
292 public static String getHAIdFromManagerOtherConfig(Node node) {
293 if (node.augmentation(HwvtepGlobalAugmentation.class) == null) {
296 HwvtepGlobalAugmentation globalAugmentation = node.augmentation(HwvtepGlobalAugmentation.class);
297 if (globalAugmentation != null) {
298 List<Managers> managers = new ArrayList<Managers>(globalAugmentation.nonnullManagers().values());
299 if (managers != null && !managers.isEmpty() && managers.get(0).getManagerOtherConfigs() != null) {
300 for (ManagerOtherConfigs configs : managers.get(0).nonnullManagerOtherConfigs().values()) {
301 if (HA_ID.equals(configs.getOtherConfigKey())) {
302 return configs.getOtherConfigValue();
311 * Returns ha child node path from ha node of config data tree.
313 * @param haGlobalConfigNodeOptional HA global node
314 * @return ha Child ids
316 public static List<NodeId> getChildNodeIdsFromManagerOtherConfig(Optional<Node> haGlobalConfigNodeOptional) {
317 List<NodeId> childNodeIds = new ArrayList<>();
318 if (!haGlobalConfigNodeOptional.isPresent()) {
321 HwvtepGlobalAugmentation augmentation =
322 haGlobalConfigNodeOptional.get().augmentation(HwvtepGlobalAugmentation.class);
323 if (augmentation != null && augmentation.getManagers() != null
324 && augmentation.getManagers().size() > 0) {
325 Managers managers = new ArrayList<Managers>(augmentation.nonnullManagers().values()).get(0);
326 if (null == managers.getManagerOtherConfigs()) {
329 for (ManagerOtherConfigs otherConfigs : managers.nonnullManagerOtherConfigs().values()) {
330 if (HA_CHILDREN.equals(otherConfigs.getOtherConfigKey())) {
331 String nodeIdsVal = otherConfigs.getOtherConfigValue();
332 if (nodeIdsVal != null) {
333 String[] parts = nodeIdsVal.split(",");
334 for (String part : parts) {
335 childNodeIds.add(new NodeId(part));
345 public static HwvtepGlobalAugmentation getGlobalAugmentationOfNode(Node node) {
346 HwvtepGlobalAugmentation result = null;
348 result = node.augmentation(HwvtepGlobalAugmentation.class);
350 if (result == null) {
351 result = new HwvtepGlobalAugmentationBuilder().build();
356 public static PhysicalSwitchAugmentation getPhysicalSwitchAugmentationOfNode(Node psNode) {
357 PhysicalSwitchAugmentation result = null;
358 if (psNode != null) {
359 result = psNode.augmentation(PhysicalSwitchAugmentation.class);
361 if (result == null) {
362 result = new PhysicalSwitchAugmentationBuilder().build();
368 * Transform child managers (Source) to HA managers using HA node path.
370 * @param childNode Child Node
371 * @param haGlobalCfg HA global config node
372 * @return Transformed managers
374 public static List<Managers> buildManagersForHANode(Node childNode, Optional<Node> haGlobalCfg) {
376 Set<NodeId> nodeIds = new HashSet<>();
377 nodeIds.add(childNode.getNodeId());
378 List<NodeId> childNodeIds = getChildNodeIdsFromManagerOtherConfig(haGlobalCfg);
379 nodeIds.addAll(childNodeIds);
381 ManagersBuilder builder1 = new ManagersBuilder();
383 builder1.withKey(new ManagersKey(new Uri(MANAGER_KEY)));
384 List<ManagerOtherConfigs> otherConfigses = new ArrayList<>();
385 String children = nodeIds.stream().map(NodeId::getValue).collect(Collectors.joining(","));
386 otherConfigses.add(getOtherConfigBuilder(HA_CHILDREN, children).build());
387 builder1.setManagerOtherConfigs(otherConfigses);
388 List<Managers> managers = new ArrayList<>();
389 managers.add(builder1.build());
394 * Transform child switch (Source) to HA swicthes using HA node path.
396 * @param childNode HA child node
397 * @param haNodePath HA node path
398 * @param haNode Ha node object
399 * @return Transformed switches
401 public static List<Switches> buildSwitchesForHANode(Node childNode,
402 InstanceIdentifier<Node> haNodePath,
403 Optional<Node> haNode) {
404 List<Switches> psList = new ArrayList<>();
405 boolean switchesAlreadyPresent = false;
406 if (haNode.isPresent()) {
407 Node node = haNode.get();
408 HwvtepGlobalAugmentation augmentation = node.augmentation(HwvtepGlobalAugmentation.class);
409 if (augmentation != null) {
410 if (augmentation.getSwitches() != null) {
411 if (augmentation.getSwitches().size() > 0) {
412 switchesAlreadyPresent = true;
417 if (!switchesAlreadyPresent) {
418 HwvtepGlobalAugmentation augmentation = childNode.augmentation(HwvtepGlobalAugmentation.class);
419 if (augmentation != null && augmentation.getSwitches() != null) {
420 List<Switches> src = new ArrayList<Switches>(augmentation.nonnullSwitches().values());
421 if (src != null && src.size() > 0) {
422 psList.add(new SwitchesCmd().transform(haNodePath, src.get(0)));
430 * Build HA Global node from child nodes in config data tress.
432 * @param tx Transaction
433 * @param childNode Child Node object
434 * @param haNodePath Ha node path
435 * @param haGlobalCfg HA global node object
437 public static void buildGlobalConfigForHANode(TypedWriteTransaction<Configuration> tx,
439 InstanceIdentifier<Node> haNodePath,
440 Optional<Node> haGlobalCfg) {
442 NodeBuilder nodeBuilder = new NodeBuilder();
443 HwvtepGlobalAugmentationBuilder hwvtepGlobalBuilder = new HwvtepGlobalAugmentationBuilder();
444 hwvtepGlobalBuilder.setSwitches(buildSwitchesForHANode(childNode, haNodePath, haGlobalCfg));
445 hwvtepGlobalBuilder.setManagers(buildManagersForHANode(childNode, haGlobalCfg));
447 nodeBuilder.setNodeId(haNodePath.firstKeyOf(Node.class).getNodeId());
448 nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, hwvtepGlobalBuilder.build());
449 Node configHANode = nodeBuilder.build();
450 tx.mergeParentStructureMerge(haNodePath, configHANode);
453 public static <D extends Datastore> void deleteNodeIfPresent(TypedReadWriteTransaction<D> tx,
454 InstanceIdentifier<?> iid) throws ExecutionException, InterruptedException {
455 if (tx.read(iid).get().isPresent()) {
456 LOG.info("Deleting child node {}", getNodeIdVal(iid));
462 * Delete PS data of HA node of Config Data tree.
464 * @param key Node object
465 * @param haNode Ha Node from which to be deleted
466 * @param tx Transaction
468 public static void deletePSNodesOfNode(InstanceIdentifier<Node> key, Node haNode,
469 TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
470 //read from switches attribute and clean up them
471 HwvtepGlobalAugmentation globalAugmentation = haNode.augmentation(HwvtepGlobalAugmentation.class);
472 if (globalAugmentation == null) {
475 HashMap<InstanceIdentifier<Node>,Boolean> deleted = new HashMap<>();
476 Map<SwitchesKey, Switches> switches = globalAugmentation.nonnullSwitches();
477 if (switches != null) {
478 for (Switches switche : switches.values()) {
479 InstanceIdentifier<Node> psId = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
480 deleteNodeIfPresent(tx, psId);
481 deleted.put(psId, Boolean.TRUE);
484 //also read from managed by attribute of switches and cleanup them as a back up if the above cleanup fails
485 Optional<Topology> topologyOptional = tx .read(key.firstIdentifierOf(Topology.class)).get();
486 String deletedNodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
487 if (topologyOptional.isPresent()) {
488 Topology topology = topologyOptional.get();
489 if (topology.getNode() != null) {
490 for (Node psNode : topology.nonnullNode().values()) {
491 PhysicalSwitchAugmentation ps = psNode.augmentation(PhysicalSwitchAugmentation.class);
493 InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>)ps.getManagedBy().getValue();
494 String nodeIdVal = iid.firstKeyOf(Node.class).getNodeId().getValue();
495 if (deletedNodeId.equals(nodeIdVal)) {
496 InstanceIdentifier<Node> psNodeId =
497 convertToInstanceIdentifier(psNode.getNodeId().getValue());
498 if (deleted.containsKey(psNodeId)) {
499 deleteNodeIfPresent(tx, psNodeId);
508 public static void addToCacheIfHAChildNode(InstanceIdentifier<Node> childPath, Node childNode,
509 HwvtepNodeHACache hwvtepNodeHACache) {
510 String haId = HwvtepHAUtil.getHAIdFromManagerOtherConfig(childNode);
511 if (!Strings.isNullOrEmpty(haId)) {
512 InstanceIdentifier<Node> parentId = HwvtepHAUtil.createInstanceIdentifierFromHAId(haId);
513 hwvtepNodeHACache.addChild(parentId, childPath/*child*/);