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