Handle nullable lists in elanmanager
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / cli / l2gw / NetworkL2gwDeviceInfoCli.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.elan.cli.l2gw;
10
11 import static java.util.Collections.emptyList;
12 import static org.opendaylight.netvirt.elan.utils.ElanUtils.requireNonNullElse;
13
14 import com.google.common.base.Optional;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22 import javax.annotation.Nullable;
23 import org.apache.karaf.shell.commands.Command;
24 import org.apache.karaf.shell.commands.Option;
25 import org.apache.karaf.shell.console.OsgiCommandSupport;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.genius.mdsalutil.MDSALUtil;
29 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
30 import org.opendaylight.genius.utils.hwvtep.HwvtepUtils;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54
55 /**
56  * Prints L2Gw devices and Elan details .
57  * Print result as per each elan instance , printing all Mcast , UCast macs and vlan binding
58  * for each l2Gw device .
59  */
60 @Command(scope = "l2gw", name = "dump", description = "Provide l2gw info per network")
61 public class NetworkL2gwDeviceInfoCli extends OsgiCommandSupport {
62
63     private static final String GAP = "                              ";
64     private static final String HEADINGUCAST = "    Mac " + GAP + "          Locator";
65     private static final String HEADINGMCAST = "    Mac " + GAP + "          Locator Set";
66     private static final String HEADINGVLAN = "    TepId " + GAP + "          Vlan ID";
67
68     @Option(name = "-elan", aliases = {"--elan"}, description = "elan name",
69             required = false, multiValued = false)
70     String elanName;
71
72     @Option(name = "-nodeId", aliases = {"--nodeId"}, description = "hwvtep node id",
73             required = false, multiValued = false)
74     String nodeId;
75
76     private static InstanceIdentifier<Topology> createHwvtepTopologyInstanceIdentifier() {
77         return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
78                 new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID));
79     }
80
81     private static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
82         return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
83                 new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class, new NodeKey(nodeId));
84     }
85
86     Map<NodeId, Node> opNodes = new HashMap<>();
87     Map<NodeId, Node> configNodes = new HashMap<>();
88     Map<NodeId, Node> opPSNodes = new HashMap<>();
89     Map<NodeId, Node> configPSNodes = new HashMap<>();
90
91     private DataBroker dataBroker;
92
93     public void setDataBroker(DataBroker dataBroker) {
94         this.dataBroker = dataBroker;
95     }
96
97     @Override
98     @Nullable
99     protected Object doExecute() {
100         List<Node> nodes = new ArrayList<>();
101         Set<String> networks = new HashSet<>();
102         if (nodeId == null) {
103             Optional<Topology> topologyOptional = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
104                     createHwvtepTopologyInstanceIdentifier());
105             if (topologyOptional.isPresent()) {
106                 nodes = requireNonNullElse(topologyOptional.get().getNode(), emptyList());
107             }
108         } else {
109             Optional<Node> nodeOptional = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
110                     createInstanceIdentifier(new NodeId(new Uri(nodeId))));
111             if (nodeOptional.isPresent()) {
112                 nodes.add(nodeOptional.get());
113             }
114         }
115         if (elanName == null) {
116             //get all elan instance
117             //get all device node id
118             //print result
119             Optional<ElanInstances> elanInstancesOptional = MDSALUtil.read(dataBroker,
120                     LogicalDatastoreType.CONFIGURATION,
121                     InstanceIdentifier.builder(ElanInstances.class).build());
122             if (elanInstancesOptional.isPresent()) {
123                 List<ElanInstance> elans = elanInstancesOptional.get().getElanInstance();
124                 if (elans != null) {
125                     for (ElanInstance elan : elans) {
126                         networks.add(elan.getElanInstanceName());
127                     }
128                 }
129             }
130         } else {
131             networks.add(elanName);
132         }
133
134         for (Node node : nodes) {
135             if (node.getNodeId().getValue().contains("physicalswitch")) {
136                 continue;
137             }
138             Node hwvtepConfigNode =
139                     HwvtepUtils.getHwVtepNode(dataBroker, LogicalDatastoreType.CONFIGURATION, node.getNodeId());
140             Node hwvtepOpPsNode = getPSnode(node, LogicalDatastoreType.OPERATIONAL);
141             Node hwvtepConfigPsNode = null;
142             if (hwvtepOpPsNode != null) {
143                 hwvtepConfigPsNode = HwvtepUtils.getHwVtepNode(dataBroker, LogicalDatastoreType.CONFIGURATION,
144                         hwvtepOpPsNode.getNodeId());
145                 opPSNodes.put(node.getNodeId(), hwvtepOpPsNode);
146             }
147             opNodes.put(node.getNodeId(), node);
148             configNodes.put(node.getNodeId(), hwvtepConfigNode);
149
150             if (hwvtepConfigPsNode != null) {
151                 configPSNodes.put(node.getNodeId(), hwvtepConfigPsNode);
152             }
153         }
154         for (String network : networks) {
155             session.getConsole().println("Network info for " + network);
156             for (Node node : nodes) {
157                 if (node.getNodeId().getValue().contains("physicalswitch")) {
158                     continue;
159                 }
160                 session.getConsole().println("Printing for node " + node.getNodeId().getValue());
161                 process(node.getNodeId(), network);
162             }
163         }
164         return null;
165     }
166
167     @SuppressWarnings("checkstyle:HiddenField")
168     void process(NodeId hwvtepNodeId, String elanName) {
169         Node hwvtepConfigNode = configNodes.get(hwvtepNodeId);
170         session.getConsole().println("Config Data >>");
171         printLocalUcastMacs(hwvtepConfigNode, elanName);
172         session.getConsole().println("Operational Data >>");
173         Node hwvtepOpNode = opNodes.get(hwvtepNodeId);
174         printLocalUcastMacs(hwvtepOpNode, elanName);
175         session.getConsole().println("Config Data >>");
176         printLocalMcastMacs(hwvtepConfigNode, elanName);
177         session.getConsole().println("Operational Data >>");
178         printLocalMcastMacs(hwvtepOpNode, elanName);
179         session.getConsole().println("Config Data >>");
180         printRemoteUcastMacs(hwvtepConfigNode, elanName);
181         session.getConsole().println("Operational Data >>");
182         printRemoteUcastMacs(hwvtepOpNode, elanName);
183         session.getConsole().println("Config Data >>");
184         printRemoteMcastMacs(hwvtepConfigNode, elanName);
185         session.getConsole().println("Operational Data >>");
186         printRemoteMcastMacs(hwvtepOpNode, elanName);
187         Node hwvtepConfigPsNode = configPSNodes.get(hwvtepNodeId);
188         session.getConsole().println("Config Data >>");
189         printVlanBindings(hwvtepConfigPsNode, elanName);
190         session.getConsole().println("Operational Data >>");
191         Node hwvtepOpPsNode = opPSNodes.get(hwvtepNodeId);
192         printVlanBindings(hwvtepOpPsNode, elanName);
193     }
194
195     @SuppressWarnings("checkstyle:HiddenField")
196     void printRemoteUcastMacs(Node hwvtepNode, String elanName) {
197         session.getConsole().println("RemoteUCast macs :");
198         session.getConsole().println(HEADINGUCAST);
199         if (hwvtepNode == null || hwvtepNode.augmentation(HwvtepGlobalAugmentation.class) == null) {
200             return;
201         }
202         List<RemoteUcastMacs> remoteUcastMacs =
203                 hwvtepNode.augmentation(HwvtepGlobalAugmentation.class).getRemoteUcastMacs();
204         if (remoteUcastMacs == null || remoteUcastMacs.isEmpty()) {
205             return;
206         }
207         for (RemoteUcastMacs remoteMac : remoteUcastMacs) {
208             String lsFromRemoteMac = getLogicalSwitchValue(remoteMac.getLogicalSwitchRef());
209             if (elanName.equals(lsFromRemoteMac)) {
210                 String mac = remoteMac.getMacEntryKey().getValue();
211                 String locator = getLocatorValue(remoteMac.getLocatorRef());
212                 session.getConsole().println(mac + GAP + locator);
213             }
214         }
215
216
217     }
218
219     @SuppressWarnings("checkstyle:HiddenField")
220     void printLocalUcastMacs(Node hwvtepNode, String elanName) {
221         session.getConsole().println("LocalUCast macs :");
222         session.getConsole().println(HEADINGUCAST);
223         if (hwvtepNode == null || hwvtepNode.augmentation(HwvtepGlobalAugmentation.class) == null) {
224             return;
225         }
226         List<LocalUcastMacs> localUcastMacs =
227                 hwvtepNode.augmentation(HwvtepGlobalAugmentation.class).getLocalUcastMacs();
228         if (localUcastMacs == null || localUcastMacs.isEmpty()) {
229             return;
230         }
231         for (LocalUcastMacs localMac : localUcastMacs) {
232             String lsFromLocalMac = getLogicalSwitchValue(localMac.getLogicalSwitchRef());
233             if (elanName.equals(lsFromLocalMac)) {
234                 String mac = localMac.getMacEntryKey().getValue();
235                 String locator = getLocatorValue(localMac.getLocatorRef());
236                 session.getConsole().println(mac + GAP + locator);
237             }
238         }
239
240
241     }
242
243     @SuppressWarnings("checkstyle:HiddenField")
244     void printLocalMcastMacs(Node hwvtepNode, String elanName) {
245         session.getConsole().println("LocalMcast macs :");
246         session.getConsole().println(HEADINGMCAST);
247         if (hwvtepNode == null || hwvtepNode.augmentation(HwvtepGlobalAugmentation.class) == null) {
248             return;
249         }
250         List<LocalMcastMacs> localMcastMacs =
251                 hwvtepNode.augmentation(HwvtepGlobalAugmentation.class).getLocalMcastMacs();
252         if (localMcastMacs == null || localMcastMacs.isEmpty()) {
253             return;
254         }
255         for (LocalMcastMacs localMac : localMcastMacs) {
256             String lsFromLocalMac = getLogicalSwitchValue(localMac.getLogicalSwitchRef());
257             if (elanName.equals(lsFromLocalMac)) {
258                 String mac = localMac.getMacEntryKey().getValue();
259                 List<String> locatorsets = new ArrayList<>();
260                 for (LocatorSet locatorSet : requireNonNullElse(localMac.getLocatorSet(),
261                         Collections.<LocatorSet>emptyList())) {
262                     locatorsets.add(getLocatorValue(locatorSet.getLocatorRef()));
263                 }
264                 session.getConsole().println(mac + GAP + locatorsets.toString());
265             }
266         }
267
268
269     }
270
271     @SuppressWarnings("checkstyle:HiddenField")
272     void printRemoteMcastMacs(Node hwvtepNode, String elanName) {
273         session.getConsole().println("RemoteMCast macs :");
274         session.getConsole().println(HEADINGMCAST);
275         if (hwvtepNode == null || hwvtepNode.augmentation(HwvtepGlobalAugmentation.class) == null) {
276             return;
277         }
278         List<RemoteMcastMacs> remoteMcastMacs =
279                 hwvtepNode.augmentation(HwvtepGlobalAugmentation.class).getRemoteMcastMacs();
280         if (remoteMcastMacs == null || remoteMcastMacs.isEmpty()) {
281             return;
282         }
283         for (RemoteMcastMacs remoteMac : remoteMcastMacs) {
284             String lsFromremoteMac = getLogicalSwitchValue(remoteMac.getLogicalSwitchRef());
285             if (elanName.equals(lsFromremoteMac)) {
286                 String mac = remoteMac.getMacEntryKey().getValue();
287                 List<String> locatorsets = new ArrayList<>();
288                 for (LocatorSet locatorSet : requireNonNullElse(remoteMac.getLocatorSet(),
289                         Collections.<LocatorSet>emptyList())) {
290                     locatorsets.add(getLocatorValue(locatorSet.getLocatorRef()));
291                 }
292                 session.getConsole().println(mac + GAP + locatorsets.toString());
293             }
294         }
295
296
297     }
298
299     @SuppressWarnings("checkstyle:HiddenField")
300     void printVlanBindings(Node psNode, String elanName) {
301         session.getConsole().println("Vlan Bindings :");
302         session.getConsole().println(HEADINGVLAN);
303         if (psNode == null) {
304             return;
305         }
306         List<TerminationPoint> terminationPoints = psNode.getTerminationPoint();
307         if (terminationPoints == null || terminationPoints.isEmpty()) {
308             return;
309         }
310         for (TerminationPoint terminationPoint : terminationPoints) {
311             HwvtepPhysicalPortAugmentation aug =
312                     terminationPoint.augmentation(HwvtepPhysicalPortAugmentation.class);
313             if (aug == null || aug.getVlanBindings() == null) {
314                 continue;
315             }
316             for (VlanBindings vlanBindings : aug.getVlanBindings()) {
317                 String lsFromremoteMac = getLogicalSwitchValue(vlanBindings.getLogicalSwitchRef());
318                 if (elanName.equals(lsFromremoteMac)) {
319                     session.getConsole().println(terminationPoint.getTpId().getValue()
320                             + GAP + vlanBindings.getVlanIdKey().toString());
321                 }
322             }
323         }
324
325
326     }
327
328     @Nullable
329     String getLocatorValue(HwvtepPhysicalLocatorRef locatorRef) {
330         if (locatorRef == null) {
331             return null;
332         }
333         return locatorRef.getValue()
334                 .firstKeyOf(TerminationPoint.class).getTpId().getValue();
335     }
336
337     @Nullable
338     String getLogicalSwitchValue(HwvtepLogicalSwitchRef logicalSwitchRef) {
339         if (logicalSwitchRef == null) {
340             return null;
341         }
342         return logicalSwitchRef.getValue()
343                 .firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue();
344     }
345
346     @Nullable
347     Node getPSnode(Node hwvtepNode, LogicalDatastoreType datastoreType) {
348         if (hwvtepNode.augmentation(HwvtepGlobalAugmentation.class) != null) {
349             List<Switches> switches = hwvtepNode.augmentation(HwvtepGlobalAugmentation.class).getSwitches();
350             if (switches != null) {
351                 return HwvtepUtils.getHwVtepNode(dataBroker, datastoreType,
352                     switches.iterator().next().getSwitchRef().getValue().firstKeyOf(Node.class).getNodeId());
353             }
354         }
355         return null;
356     }
357 }