00c9598aa2305eb01586af5da6306fe2e7aa730d
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / cli / l2gw / L2GwValidateCli.java
1 /*
2  * Copyright (c) 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
9 package org.opendaylight.netvirt.elan.cli.l2gw;
10
11 import static java.util.Collections.emptyList;
12 import static org.opendaylight.netvirt.elan.utils.ElanUtils.requireNonNullElse;
13
14 import com.google.common.base.Function;
15 import com.google.common.base.Optional;
16 import com.google.common.collect.Sets;
17 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
18 import java.io.File;
19 import java.io.FileOutputStream;
20 import java.io.PrintWriter;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.Set;
28 import java.util.stream.Collectors;
29 import javax.annotation.Nullable;
30 import org.apache.karaf.shell.commands.Command;
31 import org.apache.karaf.shell.console.OsgiCommandSupport;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
34 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
35 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
36 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
37 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
38 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
39 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LogicalSwitchesCmd;
40 import org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand;
41 import org.opendaylight.netvirt.elan.l2gw.ha.commands.RemoteMcastCmd;
42 import org.opendaylight.netvirt.elan.l2gw.ha.commands.RemoteUcastCmd;
43 import org.opendaylight.netvirt.elan.l2gw.ha.commands.TerminationPointCmd;
44 import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
45 import org.opendaylight.netvirt.elan.utils.ElanConstants;
46 import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
47 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
48 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
70 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
71 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
72 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
73 import org.opendaylight.yangtools.yang.binding.DataObject;
74 import org.opendaylight.yangtools.yang.binding.Identifier;
75 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78
79 @Command(scope = "l2gw", name = "validate", description = "Validates the hwvtep nodes data")
80 public class L2GwValidateCli extends OsgiCommandSupport {
81
82     private static final Logger LOG = LoggerFactory.getLogger(L2GwValidateCli.class);
83
84     private final MergeCommand[] globalCommands = new MergeCommand[]{new LogicalSwitchesCmd(), new RemoteUcastCmd(),
85         new RemoteMcastCmd()};
86     private final MergeCommand[] physicalSwitchCommands = new MergeCommand[]{new TerminationPointCmd()};
87
88     private final Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
89     private final Map<InstanceIdentifier<Node>, Node> configNodes = new HashMap<>();
90     private final Map<String, ElanInstance> elanInstanceMap = new HashMap<>();
91     private final Map<Uuid, L2gateway> uuidToL2Gateway = new HashMap<>();
92     private final InstanceIdentifier<Topology> topoIid = HwvtepSouthboundUtils.createHwvtepTopologyInstanceIdentifier();
93     private final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier, DataObject>> operationalNodesData =
94             new HashMap<>();
95     private final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier, DataObject>> configNodesData =
96             new HashMap<>();
97
98     private final DataBroker dataBroker;
99     private final L2GatewayCache l2GatewayCache;
100     private final HwvtepNodeHACache hwvtepNodeHACache;
101
102     private List<L2gateway> l2gateways;
103     private List<L2gatewayConnection> l2gatewayConnections;
104
105     private PrintWriter pw;
106
107     public L2GwValidateCli(DataBroker dataBroker, L2GatewayCache l2GatewayCache,
108             HwvtepNodeHACache hwvtepNodeHACache) {
109         this.dataBroker = dataBroker;
110         this.l2GatewayCache = l2GatewayCache;
111         this.hwvtepNodeHACache = hwvtepNodeHACache;
112     }
113
114     @Override
115     @SuppressFBWarnings("DM_DEFAULT_ENCODING")
116     @Nullable
117     public Object doExecute() throws Exception {
118         try {
119             pw = new PrintWriter(new FileOutputStream(new File("l2gw.validation.txt")));
120             readNodes();
121             verifyHANodes();
122             verifyConfigVsOperationalDiff();
123             verifyL2GatewayConnections();
124             pw.close();
125         } catch (ReadFailedException e) {
126             session.getConsole().println("Failed with error " + e.getMessage());
127             LOG.error("Failed with error ", e);
128         }
129         return null;
130     }
131
132     private void readNodes() throws ReadFailedException {
133         try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) {
134             InstanceIdentifier<Topology> topoId = HwvtepSouthboundUtils.createHwvtepTopologyInstanceIdentifier();
135
136             Optional<Topology> operationalTopoOptional = tx.read(LogicalDatastoreType.OPERATIONAL, topoId).checkedGet();
137             Optional<Topology> configTopoOptional = tx.read(LogicalDatastoreType.CONFIGURATION, topoId).checkedGet();
138
139             if (operationalTopoOptional.isPresent()) {
140                 for (Node node : requireNonNullElse(operationalTopoOptional.get().getNode(),
141                         Collections.<Node>emptyList())) {
142                     InstanceIdentifier<Node> nodeIid = topoId.child(Node.class, node.key());
143                     operationalNodes.put(nodeIid, node);
144                 }
145             }
146             if (configTopoOptional.isPresent()) {
147                 for (Node node : requireNonNullElse(configTopoOptional.get().getNode(),
148                         Collections.<Node>emptyList())) {
149                     InstanceIdentifier<Node> nodeIid = topoId.child(Node.class, node.key());
150                     configNodes.put(nodeIid, node);
151                 }
152             }
153
154             fillNodesData(operationalNodes, operationalNodesData);
155             fillNodesData(configNodes, configNodesData);
156
157             Optional<ElanInstances> elanInstancesOptional = tx.read(LogicalDatastoreType.CONFIGURATION,
158                     InstanceIdentifier.builder(ElanInstances.class).build()).checkedGet();
159
160             if (elanInstancesOptional.isPresent() && elanInstancesOptional.get().getElanInstance() != null) {
161                 for (ElanInstance elanInstance : elanInstancesOptional.get().getElanInstance()) {
162                     elanInstanceMap.put(elanInstance.getElanInstanceName(), elanInstance);
163                 }
164             }
165             l2gatewayConnections = L2GatewayConnectionUtils.getAllL2gatewayConnections(dataBroker);
166             l2gateways = L2GatewayConnectionUtils.getL2gatewayList(dataBroker);
167             for (L2gateway l2gateway : l2gateways) {
168                 uuidToL2Gateway.put(l2gateway.getUuid(), l2gateway);
169             }
170         }
171     }
172
173     private boolean isPresent(Map<InstanceIdentifier<Node>, Map<InstanceIdentifier, DataObject>> dataMap,
174                               InstanceIdentifier<Node> nodeIid, InstanceIdentifier dataIid) {
175         if (dataMap.containsKey(nodeIid)) {
176             return dataMap.get(nodeIid).containsKey(dataIid);
177         }
178         return false;
179     }
180
181     @Nullable
182     private DataObject getData(Map<InstanceIdentifier<Node>, Map<InstanceIdentifier, DataObject>> dataMap,
183                                InstanceIdentifier<Node> nodeIid, InstanceIdentifier dataIid) {
184         if (dataMap.containsKey(nodeIid)) {
185             return dataMap.get(nodeIid).get(dataIid);
186         }
187         return null;
188     }
189
190     private void fillNodesData(Map<InstanceIdentifier<Node>, Node> nodes,
191                                Map<InstanceIdentifier<Node>, Map<InstanceIdentifier, DataObject>> dataMap) {
192
193         for (Map.Entry<InstanceIdentifier<Node>, Node> entry : nodes.entrySet()) {
194             InstanceIdentifier<Node> nodeId = entry.getKey();
195             Node node = entry.getValue();
196             Map<InstanceIdentifier, DataObject> map = new HashMap<>();
197             dataMap.put(nodeId, map);
198             if (node.augmentation(HwvtepGlobalAugmentation.class) != null) {
199                 for (MergeCommand command : globalCommands) {
200                     List<DataObject> data = command.getData(node.augmentation(HwvtepGlobalAugmentation.class));
201                     if (data != null) {
202                         for (DataObject dataObject : data) {
203                             map.put(command.generateId(nodeId, dataObject), dataObject);
204                         }
205                     }
206                 }
207             } else {
208                 for (MergeCommand command : physicalSwitchCommands) {
209                     List<DataObject> data = command.getData(node);
210                     if (data != null) {
211                         for (DataObject dataObject : data) {
212                             map.put(command.generateId(nodeId, dataObject), dataObject);
213                         }
214                     }
215                 }
216             }
217         }
218     }
219
220     /**
221      * Checks the diff between config and operational topology nodes and prints it to the file if any.
222      * This will tell what is present in the controller config and not in the device
223      */
224     private void verifyConfigVsOperationalDiff() {
225         for (Node cfgNode : configNodes.values()) {
226             InstanceIdentifier<Node> nodeId = topoIid.child(Node.class, cfgNode.key());
227             compareNodes(cfgNode, operationalNodes.get(nodeId), false, LogicalDatastoreType.CONFIGURATION);
228         }
229     }
230
231     /**
232      * Checks the diff between HA parent and child nodes.
233      * Whatever config data in parent should be present in child nodes
234      * Whatever operational data in child should be present in parent node
235      */
236     private void verifyHANodes() {
237         pw.println("Verifying HA nodes");
238         boolean parentChildComparison = true;
239         Set<InstanceIdentifier<Node>> parentNodes = hwvtepNodeHACache.getHAParentNodes();
240         if (HwvtepHAUtil.isEmpty(parentNodes)) {
241             return;
242         }
243         for (InstanceIdentifier<Node> parentNodeIid : parentNodes) {
244             String parentNodeId = parentNodeIid.firstKeyOf(Node.class).getNodeId().getValue();
245             Node parentOpNode = operationalNodes.get(parentNodeIid);
246             Node parentCfgNode = configNodes.get(parentNodeIid);
247             Set<InstanceIdentifier<Node>> childNodeIids = hwvtepNodeHACache.getChildrenForHANode(parentNodeIid);
248             if (HwvtepHAUtil.isEmpty(childNodeIids)) {
249                 pw.println("No child nodes could be found for parent node " + parentNodeId);
250                 continue;
251             }
252             for (InstanceIdentifier<Node> childNodeIid : childNodeIids) {
253                 String childNodeId = childNodeIid.firstKeyOf(Node.class).getNodeId().getValue();
254                 if (parentOpNode != null) {
255                     compareNodes(parentOpNode, operationalNodes.get(childNodeIid), parentChildComparison,
256                             LogicalDatastoreType.OPERATIONAL);
257                 } else {
258                     pw.println("Missing parent operational node for id " + parentNodeId);
259                 }
260                 if (parentCfgNode != null) {
261                     if (configNodes.get(childNodeIid) == null) {
262                         if (containsLogicalSwitch(parentCfgNode)) {
263                             pw.println("Missing child config data " + childNodeId);
264                         }
265                     } else {
266                         compareNodes(parentCfgNode, configNodes.get(childNodeIid), parentChildComparison,
267                                 LogicalDatastoreType.CONFIGURATION);
268                     }
269                 } else {
270                     pw.println("Missing parent config node for id " + parentNodeId);
271                 }
272             }
273         }
274     }
275
276     private boolean containsLogicalSwitch(Node node) {
277         if (node == null || node.augmentation(HwvtepGlobalAugmentation.class) == null
278                 || HwvtepHAUtil.isEmptyList(
279                 node.augmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches())) {
280             return false;
281         }
282         return true;
283     }
284
285     private boolean compareNodes(Node node1, Node node2, boolean parentChildComparison,
286                                  LogicalDatastoreType datastoreType) {
287
288         if (node1 == null || node2 == null) {
289             return false;
290         }
291         InstanceIdentifier<Node> nodeIid1 = HwvtepSouthboundUtils.createInstanceIdentifier(node1.getNodeId());
292         InstanceIdentifier<Node> nodeIid2 = HwvtepSouthboundUtils.createInstanceIdentifier(node2.getNodeId());
293
294         NodeId nodeId1 = nodeIid1.firstKeyOf(Node.class).getNodeId();
295         NodeId nodeId2 = nodeIid2.firstKeyOf(Node.class).getNodeId();
296
297         PhysicalSwitchAugmentation psAug1 = node1.augmentation(PhysicalSwitchAugmentation.class);
298         PhysicalSwitchAugmentation psAug2 = node2.augmentation(PhysicalSwitchAugmentation.class);
299
300         HwvtepGlobalAugmentation aug1 = node1.augmentation(HwvtepGlobalAugmentation.class);
301         HwvtepGlobalAugmentation aug2 = node2.augmentation(HwvtepGlobalAugmentation.class);
302
303         boolean globalNodes = psAug1 == null && psAug2 == null ? true : false;
304         MergeCommand[] commands = globalNodes ? globalCommands : physicalSwitchCommands;
305
306         for (MergeCommand cmd : commands) {
307
308             List<DataObject> data1 = null;
309             List<DataObject> data2 = null;
310
311             if (globalNodes) {
312                 data1 = cmd.getData(aug1);
313                 data2 = cmd.getData(aug2);
314             } else {
315                 data1 = cmd.getData(node1);
316                 data2 = cmd.getData(node2);
317             }
318             data1 = data1 == null ? Collections.EMPTY_LIST : data1;
319             data2 = data2 == null ? Collections.EMPTY_LIST : data2;
320
321             if (parentChildComparison) {
322                 data2 = cmd.transform(nodeIid1, data2);
323             }
324             Function<DataObject, DataObject> withoutUuidTransformer = cmd::withoutUuid;
325             data1 = data1.stream().map(withoutUuidTransformer).collect(Collectors.toList());
326             data2 = data2.stream().map(withoutUuidTransformer).collect(Collectors.toList());
327
328             Map<Identifier<?>, DataObject> map1 = new HashMap<>();
329             Map<Identifier<?>, DataObject> map2 = new HashMap<>();
330             for (DataObject dataObject : data1) {
331                 map1.put(cmd.getKey(dataObject), dataObject);
332             }
333             for (DataObject dataObject : data2) {
334                 map2.put(cmd.getKey(dataObject), dataObject);
335             }
336             Set<DataObject> diff = Sets.newHashSet();
337
338             for (Entry<Identifier<?>, DataObject> entry : map1.entrySet()) {
339                 DataObject obj1 = entry.getValue();
340                 DataObject obj2 = map2.get(entry.getKey());
341                 if (obj2 == null || !cmd.areEqual(obj1, obj2)) {
342                     diff.add(obj1);
343                 }
344             }
345
346             if (!diff.isEmpty()) {
347                 if (parentChildComparison) {
348                     pw.println("Missing " + cmd.getDescription() + " child entries in " + datastoreType
349                             + " parent node " + nodeId1 + " contain " + " more entries than child "
350                             + nodeId2 + " " + diff.size());
351                 } else {
352                     pw.println("Missing " + cmd.getDescription() + " op entries config "
353                             + nodeId1 + " contain " + " more entries than operational node " + diff.size());
354                 }
355                 if (diff.size() < 10) {
356                     for (Object obj : diff) {
357                         pw.println(cmd.getKey((DataObject) obj));
358                     }
359                 }
360             }
361
362             diff = Sets.newHashSet();
363             for (Entry<Identifier<?>, DataObject> entry : map2.entrySet()) {
364                 DataObject obj1 = entry.getValue();
365                 DataObject obj2 = map1.get(entry.getKey());
366                 if (globalNodes || parentChildComparison) {
367                     if (obj2 == null || !cmd.areEqual(obj1, obj2)) {
368                         diff.add(obj1);
369                     }
370                 }
371             }
372             if (!diff.isEmpty()) {
373                 if (parentChildComparison) {
374                     pw.println("Extra " + cmd.getDescription() + " child entries in " + datastoreType + " node "
375                             + nodeId2 + " contain " + " more entries than parent node " + nodeId1 + " " + diff.size());
376                 } else {
377                     pw.println("Extra " + cmd.getDescription() + " operational node "
378                             + nodeId2 + " contain " + " more entries than config node " + diff.size());
379                 }
380                 if (diff.size() < 10) {
381                     for (Object obj : diff) {
382                         pw.println(cmd.getKey((DataObject) obj));
383                     }
384                 }
385             }
386         }
387         return true;
388     }
389
390     private void verifyL2GatewayConnections() {
391         boolean isValid = true;
392         for (L2gatewayConnection l2gatewayConnection : l2gatewayConnections) {
393
394             L2gateway l2gateway = uuidToL2Gateway.get(l2gatewayConnection.getL2gatewayId());
395             String logicalSwitchName = l2gatewayConnection.getNetworkId().getValue();
396             List<Devices> devices = requireNonNullElse(l2gateway.getDevices(), emptyList());
397
398             for (Devices device : devices) {
399
400                 L2GatewayDevice l2GatewayDevice = l2GatewayCache.get(device.getDeviceName());
401                 isValid = verifyL2GatewayDevice(l2gateway, device, l2GatewayDevice);
402                 if (!isValid) {
403                     continue;
404                 }
405                 NodeId nodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
406                 InstanceIdentifier<Node> nodeIid = topoIid.child(Node.class, new NodeKey(nodeId));
407
408                 isValid = verfiyLogicalSwitch(logicalSwitchName, nodeIid);
409                 if (isValid) {
410                     isValid = verifyMcastMac(logicalSwitchName, nodeIid);
411                     verifyVlanBindings(nodeIid, logicalSwitchName, device, l2gatewayConnection.getSegmentId());
412                     L2GatewayDevice elanL2gatewayDevice = ElanL2GwCacheUtils
413                             .getL2GatewayDeviceFromCache(logicalSwitchName, nodeId.getValue());
414                     if (elanL2gatewayDevice == null) {
415                         pw.println("Failed elan l2gateway device not found for network " + logicalSwitchName
416                                 + " and device " + device.getDeviceName() + " " + l2GatewayDevice.getHwvtepNodeId()
417                                 + " l2gw connection id " + l2gatewayConnection.getUuid());
418                     }
419                 }
420             }
421         }
422     }
423
424     private boolean verifyL2GatewayDevice(L2gateway l2gateway, Devices device, L2GatewayDevice l2GatewayDevice) {
425         if (l2GatewayDevice == null) {
426             pw.println("Failed l2gateway not found in cache for device " + device.getDeviceName());
427             return false;
428         }
429         if (l2GatewayDevice.getHwvtepNodeId() == null) {
430             pw.println("L2gateway cache is not updated with node id for device " + device.getDeviceName());
431             return false;
432         }
433         if (l2GatewayDevice.getTunnelIp() == null) {
434             pw.println("L2gateway cache is not updated with tunnel ip for device " + device.getDeviceName());
435             return false;
436         }
437         if (!l2GatewayDevice.getL2GatewayIds().contains(l2gateway.getUuid())) {
438             pw.println("L2gateway cache is not updated with l2gw id for device " + device.getDeviceName());
439             return false;
440         }
441         return true;
442     }
443
444     private  InstanceIdentifier<TerminationPoint> getPhysicalPortTerminationPointIid(NodeId nodeId, String portName) {
445         TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName));
446         InstanceIdentifier<TerminationPoint> iid = HwvtepSouthboundUtils.createTerminationPointId(nodeId, tpKey);
447         return iid;
448     }
449
450     private boolean verfiyLogicalSwitch(String logicalSwitchName, InstanceIdentifier<Node> nodeIid) {
451         NodeId nodeId = nodeIid.firstKeyOf(Node.class).getNodeId();
452         InstanceIdentifier<LogicalSwitches> logicalSwitchPath = HwvtepSouthboundUtils
453                 .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName));
454
455         if (!isPresent(configNodesData, nodeIid, logicalSwitchPath)) {
456             pw.println("Failed to find config logical switch " + logicalSwitchName + " for node "
457                     + nodeId.getValue());
458             return false;
459         }
460
461         if (!isPresent(operationalNodesData, nodeIid, logicalSwitchPath)) {
462             pw.println("Failed to find operational logical switch " + logicalSwitchName + " for node "
463                     + nodeId.getValue());
464             return false;
465         }
466         return true;
467     }
468
469     private boolean verifyMcastMac(String logicalSwitchName,
470                                    InstanceIdentifier<Node> nodeIid) {
471         NodeId nodeId = nodeIid.firstKeyOf(Node.class).getNodeId();
472
473         HwvtepLogicalSwitchRef lsRef = new HwvtepLogicalSwitchRef(HwvtepSouthboundUtils
474                 .createLogicalSwitchesInstanceIdentifier(
475                         new NodeId(new Uri(nodeId)), new HwvtepNodeName(logicalSwitchName)));
476
477         RemoteMcastMacs remoteMcastMac = new RemoteMcastMacsBuilder()
478                 .setMacEntryKey(new MacAddress(ElanConstants.UNKNOWN_DMAC)).setLogicalSwitchRef(lsRef).build();
479         InstanceIdentifier<RemoteMcastMacs> mcastMacIid = HwvtepSouthboundUtils
480                 .createRemoteMcastMacsInstanceIdentifier(new NodeId(new Uri(nodeId)), remoteMcastMac.key());
481
482
483         if (!isPresent(configNodesData, nodeIid, mcastMacIid)) {
484             pw.println("Failed to find config mcast mac for logical switch " + logicalSwitchName
485                     + " node id " + nodeId.getValue());
486             return false;
487         }
488
489         if (!isPresent(operationalNodesData, nodeIid, mcastMacIid)) {
490             pw.println("Failed to find operational mcast mac for logical switch " + logicalSwitchName
491                     + " node id " + nodeId.getValue());
492             return false;
493         }
494         return true;
495     }
496
497     private boolean verifyVlanBindings(InstanceIdentifier<Node> nodeIid,
498                                        String logicalSwitchName,
499                                        Devices hwVtepDevice,
500                                        Integer defaultVlanId) {
501         boolean valid = true;
502         NodeId nodeId = nodeIid.firstKeyOf(Node.class).getNodeId();
503         if (hwVtepDevice.getInterfaces() == null) {
504             return false;
505         }
506         for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
507                  .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.getInterfaces()) {
508
509             NodeId switchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, hwVtepDevice.getDeviceName());
510             InstanceIdentifier<Node> physicalSwitchNodeIid = topoIid.child(Node.class, new NodeKey(switchNodeId));
511             InstanceIdentifier<TerminationPoint> terminationPointIid =
512                     getPhysicalPortTerminationPointIid(switchNodeId, deviceInterface.getInterfaceName());
513
514             TerminationPoint operationalTerminationPoint = (TerminationPoint) getData(operationalNodesData,
515                     physicalSwitchNodeIid, terminationPointIid);
516             if (operationalTerminationPoint == null) {
517                 valid = false;
518                 pw.println("Failed to find the operational port " + deviceInterface.getInterfaceName()
519                         + " for node " + hwVtepDevice.getDeviceName() + " nodeid " + nodeId.getValue());
520                 continue;
521             }
522             TerminationPoint configTerminationPoint = (TerminationPoint) getData(configNodesData,
523                     physicalSwitchNodeIid, terminationPointIid);
524             if (configTerminationPoint == null) {
525                 valid = false;
526                 pw.println("Failed to find the configurational port " + deviceInterface.getInterfaceName()
527                         + " for node " + hwVtepDevice.getDeviceName() +  " for logical switch " + logicalSwitchName
528                         + " nodeid " + nodeId.getValue());
529                 continue;
530             }
531
532             List<VlanBindings> expectedVlans = new ArrayList<>();
533             if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
534                 for (Integer vlanId : deviceInterface.getSegmentationIds()) {
535                     expectedVlans.add(HwvtepSouthboundUtils.createVlanBinding(nodeId, vlanId, logicalSwitchName));
536                 }
537             } else {
538                 expectedVlans.add(HwvtepSouthboundUtils.createVlanBinding(nodeId, defaultVlanId, logicalSwitchName));
539             }
540
541             HwvtepPhysicalPortAugmentation portAugmentation = configTerminationPoint.augmentation(
542                     HwvtepPhysicalPortAugmentation.class);
543             if (portAugmentation == null || HwvtepHAUtil.isEmptyList(portAugmentation.getVlanBindings())) {
544                 pw.println("Failed to find the config vlan bindings for port " + deviceInterface.getInterfaceName()
545                         + " for node " + hwVtepDevice.getDeviceName() +  " for logical switch " + logicalSwitchName
546                         + " nodeid " + nodeId.getValue());
547                 valid = false;
548                 continue;
549             }
550             portAugmentation = operationalTerminationPoint.augmentation(HwvtepPhysicalPortAugmentation.class);
551             if (portAugmentation == null || HwvtepHAUtil.isEmptyList(portAugmentation.getVlanBindings())) {
552                 pw.println("Failed to find the operational vlan bindings for port " + deviceInterface.getInterfaceName()
553                         + " for node " + hwVtepDevice.getDeviceName() +  " for logical switch " + logicalSwitchName
554                         + " nodeid " + nodeId.getValue());
555                 valid = false;
556                 continue;
557             }
558             VlanBindings expectedBindings = !expectedVlans.isEmpty() ? expectedVlans.get(0) : null;
559             boolean foundBindings = false;
560             List<VlanBindings> vlanBindingses = requireNonNullElse(configTerminationPoint.augmentation(
561                     HwvtepPhysicalPortAugmentation.class).getVlanBindings(), emptyList());
562             for (VlanBindings actual : vlanBindingses) {
563                 if (actual.equals(expectedBindings)) {
564                     foundBindings = true;
565                     break;
566                 }
567             }
568             if (!foundBindings) {
569                 pw.println("Mismatch in vlan bindings for port " + deviceInterface.getInterfaceName()
570                         + " for node " + hwVtepDevice.getDeviceName() +  " for logical switch " + logicalSwitchName
571                         + " nodeid " + nodeId.getValue());
572                 pw.println("Failed to find the vlan bindings " + expectedBindings);
573                 pw.println("Actual bindings present in config are ");
574                 for (VlanBindings actual : vlanBindingses) {
575                     pw.println(actual.toString());
576                 }
577                 valid = false;
578             }
579         }
580         return true;
581     }
582 }