Handle nullable lists in natservice
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / cli / DisplayNaptSwithcesCli.java
1 /*
2  * Copyright (c) 2017 Red Hat, Inc. 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.natservice.cli;
10
11 import com.google.common.base.Optional;
12 import java.io.PrintStream;
13 import java.math.BigInteger;
14 import java.util.Collections;
15 import javax.annotation.Nonnull;
16 import javax.annotation.Nullable;
17 import org.apache.karaf.shell.commands.Command;
18 import org.apache.karaf.shell.console.OsgiCommandSupport;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
22 import org.opendaylight.netvirt.natservice.internal.NatUtil;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33
34 @Command(scope = "odl", name = "display-napt-switches", description = "Display the napt switch for the routers.")
35 public class DisplayNaptSwithcesCli extends OsgiCommandSupport {
36
37     private DataBroker dataBroker;
38     private static final String LOCAL_IP = "local_ip";
39
40     public void setDataBroker(DataBroker dataBroker) {
41         this.dataBroker = dataBroker;
42     }
43
44     @Override
45     @Nullable
46     protected Object doExecute() {
47         PrintStream ps = session.getConsole();
48         Optional<NaptSwitches> npatSwitches = NatUtil.getAllPrimaryNaptSwitches(dataBroker);
49         ps.printf(String.format(" %-36s  %-20s  %-20s %n", "Router Id ", "Datapath Node Id", "Managment Ip Address"));
50         ps.printf("-------------------------------------------------------------------------------------------%n");
51         if (npatSwitches.isPresent()) {
52             for (RouterToNaptSwitch routerToNaptSwitch : NatUtil.requireNonNullElse(
53                     npatSwitches.get().getRouterToNaptSwitch(), Collections.<RouterToNaptSwitch>emptyList())) {
54                 ps.printf(String.format(" %-36s  %-20s  %-20s %n", routerToNaptSwitch.getRouterName(),
55                      routerToNaptSwitch.getPrimarySwitchId(), getDpnLocalIp(routerToNaptSwitch.getPrimarySwitchId())));
56             }
57         }
58         return null;
59     }
60
61     @SuppressWarnings("unchecked")
62     private Optional<Node> getPortsNode(BigInteger dpnId) {
63         InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
64                 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
65
66         Optional<BridgeRefEntry> bridgeRefEntry =
67                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
68                         LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
69         if (!bridgeRefEntry.isPresent()) {
70             return Optional.absent();
71         }
72
73         InstanceIdentifier<Node> nodeId =
74                 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
75
76         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
77                 LogicalDatastoreType.OPERATIONAL, nodeId);
78     }
79
80     @Nullable
81     private String getDpnLocalIp(BigInteger dpId) {
82         return getPortsNode(dpId).toJavaUtil().map(node -> getOpenvswitchOtherConfig(node, LOCAL_IP)).orElse(null);
83     }
84
85     @Nullable
86     private String getOpenvswitchOtherConfig(Node node, String key) {
87         OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
88         if (ovsdbNode == null) {
89             Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node);
90             if (nodeFromReadOvsdbNode.isPresent()) {
91                 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
92             }
93         }
94
95         if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
96             for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
97                 if (key.equals(openvswitchOtherConfigs.getOtherConfigKey())) {
98                     return openvswitchOtherConfigs.getOtherConfigValue();
99                 }
100             }
101         }
102
103         return null;
104     }
105
106     @Nonnull
107     private Optional<Node> readOvsdbNode(Node bridgeNode) {
108         OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
109         if (bridgeAugmentation != null) {
110             InstanceIdentifier<Node> ovsdbNodeIid =
111                     (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
112             return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
113                     LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
114         }
115         return Optional.absent();
116
117     }
118
119     @Nullable
120     private OvsdbBridgeAugmentation extractBridgeAugmentation(@Nullable Node node) {
121         if (node == null) {
122             return null;
123         }
124         return node.augmentation(OvsdbBridgeAugmentation.class);
125     }
126
127 }