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