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