Bug 5315 - NPE while creating Neutron Router w/o interface attached to it
[vpnservice.git] / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / vpnservice / neutronvpn / NeutronvpnUtils.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.vpnservice.neutronvpn;
10
11 import com.google.common.base.Optional;
12
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
17 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
18 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TimeUnits;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NetworkMaps;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronPortData;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.Subnetmaps;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMaps;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMap;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMapKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
47         .PortFixedipToPortName;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
49         .PortFixedipToPortNameKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
51         .PortNameToPortUuid;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
53         .PortNameToPortUuidKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.Subnetmap;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapKey;
58 import org.opendaylight.yangtools.yang.binding.DataObject;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.common.RpcResult;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 import java.util.ArrayList;
65 import java.util.List;
66 import java.util.concurrent.ExecutionException;
67 import java.util.concurrent.Future;
68
69 //import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.port.ext.rev151125.TrunkportExt;
70 //import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.port.ext.rev151125.TrunkportTypeBase;
71 //import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.port.ext.rev151125.TrunkportTypeSubport;
72
73 public class NeutronvpnUtils {
74
75     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnUtils.class);
76
77     protected static Subnetmap getSubnetmap(DataBroker broker, Uuid subnetId) {
78         InstanceIdentifier id = buildSubnetMapIdentifier(subnetId);
79         Optional<Subnetmap> sn = read(broker, LogicalDatastoreType.CONFIGURATION, id);
80
81         if (sn.isPresent()) {
82             return sn.get();
83         }
84         return null;
85     }
86
87     protected static VpnMap getVpnMap(DataBroker broker, Uuid id) {
88         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
89                 new VpnMapKey(id)).build();
90         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
91         if (optionalVpnMap.isPresent()) {
92             return optionalVpnMap.get();
93         }
94         logger.error("getVpnMap failed, VPN {} not present", id.getValue());
95         return null;
96     }
97
98     protected static Uuid getVpnForNetwork(DataBroker broker, Uuid network) {
99         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
100         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
101         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
102             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
103             for (VpnMap vpnMap : allMaps) {
104                 if (vpnMap.getNetworkIds().contains(network)) {
105                     return vpnMap.getVpnId();
106                 }
107             }
108         }
109         return null;
110     }
111
112     // true for external vpn, false for internal vpn
113     protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
114         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
115         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
116                 vpnMapsIdentifier);
117         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
118             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
119             if (routerId != null) {
120                 for (VpnMap vpnMap : allMaps) {
121                     if (routerId.equals(vpnMap.getRouterId())) {
122                         if (externalVpn == true) {
123                             if (!routerId.equals(vpnMap.getVpnId())) {
124                                 return vpnMap.getVpnId();
125                             }
126                         } else {
127                             if (routerId.equals(vpnMap.getVpnId())) {
128                                 return vpnMap.getVpnId();
129                             }
130                         }
131                     }
132                 }
133             }
134         }
135         return null;
136     }
137
138     protected static Uuid getRouterforVpn(DataBroker broker, Uuid vpnId) {
139         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
140                 .child(VpnMap.class, new VpnMapKey(vpnId)).build();
141         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
142         if (optionalVpnMap.isPresent()) {
143             VpnMap vpnMap = optionalVpnMap.get();
144             return vpnMap.getRouterId();
145         }
146         return null;
147     }
148
149     protected static Uuid getNeutronPortIdfromPortName(DataBroker broker, String portname) {
150         InstanceIdentifier id = buildPortNameToPortUuidIdentifier(portname);
151         Optional<PortNameToPortUuid> portNameToPortUuidData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
152         if (portNameToPortUuidData.isPresent()) {
153             return portNameToPortUuidData.get().getPortId();
154         }
155         return null;
156     }
157
158     protected static String getNeutronPortNamefromPortFixedIp(DataBroker broker, String fixedIp) {
159         InstanceIdentifier id = buildFixedIpToPortNameIdentifier(fixedIp);
160         Optional<PortFixedipToPortName> portFixedipToPortNameData = read(broker, LogicalDatastoreType.CONFIGURATION,
161                 id);
162         if (portFixedipToPortNameData.isPresent()) {
163             return portFixedipToPortNameData.get().getPortName();
164         }
165         return null;
166     }
167
168     protected static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
169         InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
170         Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
171         if (optionalNetworkMap.isPresent()) {
172             return optionalNetworkMap.get().getSubnetIdList();
173         }
174         return null;
175     }
176
177     //TODO
178     //Will be done once integrated with TrunkPort Extensions
179     protected static int getVlanFromNeutronPort(Port port) {
180         int vlanId = 0;
181         /*
182         TrunkportExt trunkportExt = port.getAugmentation(TrunkportExt.class);
183         if (trunkportExt != null) {
184             Class<? extends TrunkportTypeBase> trunkportType = trunkportExt.getType();
185             if (trunkportType != null && trunkportType.isAssignableFrom(TrunkportTypeSubport.class)) {
186                 vlanId = trunkportExt.getVid();
187             }
188         }
189         */
190         return vlanId;
191     }
192
193     protected static Router getNeutronRouter(DataBroker broker, Uuid routerId) {
194
195         InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
196                 .class, new RouterKey(routerId));
197         Optional<Router> rtr = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
198         if (rtr.isPresent()) {
199             return rtr.get();
200         }
201         return null;
202     }
203
204     protected static Network getNeutronNetwork(DataBroker broker, Uuid networkId) {
205         logger.debug("getNeutronNetwork for {}", networkId.getValue());
206         InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class).child
207                 (Network.class, new NetworkKey(networkId));
208         Optional<Network> net = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
209         if (net.isPresent()) {
210             return net.get();
211         }
212         return null;
213     }
214
215     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
216         logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
217
218         List<Uuid> subnetIdList = new ArrayList<Uuid>();
219         Router router = getNeutronRouter(broker, routerId);
220         if (router != null) {
221             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
222                     .Interfaces> interfacesList = router.getInterfaces();
223             if (interfacesList != null) {
224                 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
225                         .router.Interfaces interfaces : interfacesList) {
226                     subnetIdList.add(interfaces.getSubnetId());
227                 }
228             }
229         }
230         logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
231         return subnetIdList;
232     }
233
234     protected static String uuidToTapPortName(Uuid id) {
235         String tapId = id.getValue().substring(0, 11);
236         return new StringBuilder().append("tap").append(tapId).toString();
237     }
238
239     protected static boolean lock(LockManagerService lockManager, String lockName) {
240         TryLockInput input = new TryLockInputBuilder().setLockName(lockName).setTime(5L).setTimeUnit
241                 (TimeUnits.Milliseconds).build();
242         boolean islockAcquired = false;
243         try {
244             Future<RpcResult<Void>> result = lockManager.tryLock(input);
245             if ((result != null) && (result.get().isSuccessful())) {
246                 logger.debug("Acquired lock for {}", lockName);
247                 islockAcquired = true;
248             } else {
249                 logger.error("Unable to acquire lock for  {}", lockName);
250             }
251         } catch (InterruptedException | ExecutionException e) {
252             logger.error("Unable to acquire lock for  {}", lockName);
253             throw new RuntimeException(String.format("Unable to acquire lock for %s", lockName), e.getCause());
254         }
255         return islockAcquired;
256     }
257
258     protected static boolean unlock(LockManagerService lockManager, String lockName) {
259         UnlockInput input = new UnlockInputBuilder().setLockName(lockName).build();
260         boolean islockAcquired = false;
261         try {
262             Future<RpcResult<Void>> result = lockManager.unlock(input);
263             if ((result != null) && (result.get().isSuccessful())) {
264                 logger.debug("Unlocked {}", lockName);
265                 islockAcquired = true;
266             } else {
267                 logger.error("Unable to unlock {}", lockName);
268             }
269         } catch (InterruptedException | ExecutionException e) {
270             logger.error("Unable to unlock {}", lockName);
271             throw new RuntimeException(String.format("Unable to unlock %s", lockName), e.getCause());
272         }
273         return islockAcquired;
274     }
275
276     protected static Short getIPPrefixFromPort(DataBroker broker, Port port) {
277         Short prefix = new Short((short) 0);
278         String cidr = "";
279         try {
280             Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
281
282             SubnetKey subnetkey = new SubnetKey(subnetUUID);
283             InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
284                     .class).child(Subnet.class, subnetkey);
285             Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier);
286             if (subnet.isPresent()) {
287                 cidr = subnet.get().getCidr();
288                 // Extract the prefix length from cidr
289                 String[] parts = cidr.split("/");
290                 if ((parts.length == 2)) {
291                     prefix = Short.valueOf(parts[1]);
292                     return prefix;
293                 } else {
294                     logger.trace("Could not retrieve prefix from subnet CIDR");
295                     System.out.println("Could not retrieve prefix from subnet CIDR");
296                 }
297             } else {
298                 logger.trace("Unable to read on subnet datastore");
299             }
300         } catch (Exception e) {
301             logger.error("Failed to retrieve IP prefix from port : ", e);
302             System.out.println("Failed to retrieve IP prefix from port : " + e.getMessage());
303         }
304         return null;
305     }
306
307     static InstanceIdentifier<PortNameToPortUuid> buildPortNameToPortUuidIdentifier(String portname) {
308         InstanceIdentifier<PortNameToPortUuid> id = InstanceIdentifier.builder(NeutronPortData.class).child
309                 (PortNameToPortUuid.class, new PortNameToPortUuidKey(portname)).build();
310         return id;
311     }
312
313     static InstanceIdentifier<PortFixedipToPortName> buildFixedIpToPortNameIdentifier(String fixedIp) {
314         InstanceIdentifier<PortFixedipToPortName> id = InstanceIdentifier.builder(NeutronPortData.class).child
315                 (PortFixedipToPortName.class, new PortFixedipToPortNameKey(fixedIp)).build();
316         return id;
317     }
318
319     static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
320         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
321                 NetworkMapKey(networkId)).build();
322         return id;
323     }
324
325     static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
326         InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).
327                 child(VpnInterface.class, new VpnInterfaceKey(ifName)).build();
328         return id;
329     }
330
331     static InstanceIdentifier<Subnetmap> buildSubnetMapIdentifier(Uuid subnetId) {
332         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
333                 SubnetmapKey(subnetId)).build();
334         return id;
335     }
336
337     static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
338         InstanceIdentifier<Interface> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new
339                 InterfaceKey(interfaceName)).build();
340         return id;
341     }
342
343     static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
344                                                    InstanceIdentifier<T> path) {
345
346         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
347
348         Optional<T> result = Optional.absent();
349         try {
350             result = tx.read(datastoreType, path).get();
351         } catch (Exception e) {
352             throw new RuntimeException(e);
353         }
354
355         return result;
356     }
357
358 }