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