Merge "BUG #4026 neutron spi: make NeutronObject implements INeutronObject"
[neutron.git] / transcriber / src / main / java / org / opendaylight / neutron / transcriber / NeutronSubnetInterface.java
1 /*
2  * Copyright (c) 2013, 2015 IBM Corporation 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.neutron.transcriber;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map.Entry;
15 import java.util.Set;
16
17 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
18 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
19 import org.opendaylight.neutron.spi.INeutronPortCRUD;
20 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
21 import org.opendaylight.neutron.spi.Neutron_IPs;
22 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
23 import org.opendaylight.neutron.spi.NeutronNetwork;
24 import org.opendaylight.neutron.spi.NeutronPort;
25 import org.opendaylight.neutron.spi.NeutronSubnet;
26 import org.opendaylight.neutron.spi.NeutronSubnetIPAllocationPool;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Base;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Off;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Slaac;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Stateful;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Stateless;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.IpVersionBase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.IpVersionV4;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.IpVersionV6;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150325.Neutron;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnet.attributes.AllocationPools;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnet.attributes.AllocationPoolsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnets.attributes.Subnets;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnets.attributes.subnets.Subnet;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnets.attributes.subnets.SubnetBuilder;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.osgi.framework.BundleContext;
44 import org.osgi.framework.ServiceRegistration;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import com.google.common.collect.ImmutableBiMap;
49
50 public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, NeutronSubnet> implements INeutronSubnetCRUD {
51     private static final Logger LOGGER = LoggerFactory.getLogger(NeutronSubnetInterface.class);
52
53     private static final ImmutableBiMap<Class<? extends IpVersionBase>,Integer> IPV_MAP
54             = new ImmutableBiMap.Builder<Class<? extends IpVersionBase>,Integer>()
55             .put(IpVersionV4.class,Integer.valueOf(4))
56             .put(IpVersionV6.class,Integer.valueOf(6))
57             .build();
58
59     private static final ImmutableBiMap<Class<? extends Dhcpv6Base>,String> DHCPV6_MAP
60             = new ImmutableBiMap.Builder<Class<? extends Dhcpv6Base>,String>()
61             .put(Dhcpv6Off.class,"off")
62             .put(Dhcpv6Stateful.class,"dhcpv6-stateful")
63             .put(Dhcpv6Slaac.class,"slaac")
64             .put(Dhcpv6Stateless.class,"dhcpv6-stateless")
65             .build();
66
67     NeutronSubnetInterface(ProviderContext providerContext) {
68         super(providerContext);
69     }
70
71     // IfNBSubnetCRUD methods
72
73     @Override
74     public boolean subnetExists(String uuid) {
75         Subnet subnet = readMd(createInstanceIdentifier(toMd(uuid)));
76         if (subnet == null) {
77             return false;
78         }
79         return true;
80     }
81
82     @Override
83     public NeutronSubnet getSubnet(String uuid) {
84         Subnet subnet = readMd(createInstanceIdentifier(toMd(uuid)));
85         if (subnet == null) {
86             return null;
87         }
88         return fromMd(subnet);
89     }
90
91     @Override
92     public List<NeutronSubnet> getAllSubnets() {
93         Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
94         Subnets subnets = readMd(createInstanceIdentifier());
95         if (subnets != null) {
96             for (Subnet subnet: subnets.getSubnet()) {
97                 allSubnets.add(fromMd(subnet));
98             }
99         }
100         LOGGER.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());
101         List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
102         ans.addAll(allSubnets);
103         return ans;
104     }
105
106     @Override
107     public boolean addSubnet(NeutronSubnet input) {
108         String id = input.getID();
109         if (subnetExists(id)) {
110             return false;
111         }
112         addMd(input);
113         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
114             .fetchINeutronNetworkCRUD(this);
115         INeutronNetworkCRUD networkIf = interfaces.getNetworkInterface();
116
117         NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());
118         targetNet.addSubnet(id);
119         return true;
120     }
121
122     @Override
123     public boolean removeSubnet(String uuid) {
124         NeutronSubnet target = getSubnet(uuid);
125         if (target == null) {
126             return false;
127         }
128         removeMd(toMd(uuid));
129         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
130             .fetchINeutronNetworkCRUD(this);
131         INeutronNetworkCRUD networkIf = interfaces.getNetworkInterface();
132
133         NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());
134         targetNet.removeSubnet(uuid);
135         return true;
136     }
137
138     @Override
139     public boolean updateSubnet(String uuid, NeutronSubnet delta) {
140         if (!subnetExists(uuid)) {
141             return false;
142         }
143 /* note: because what we get is *not* a delta but (at this point) the updated
144  * object, this is much simpler - just replace the value and update the mdsal
145  * with it */
146         updateMd(delta);
147         return true;
148     }
149
150 // note: this is being set to false in preparation for deprecation and removal
151     @Override
152     public boolean subnetInUse(String subnetUUID) {
153         return false;
154     }
155
156     protected NeutronSubnet fromMd(Subnet subnet) {
157         NeutronSubnet result = new NeutronSubnet();
158         result.setName(subnet.getName());
159         result.setTenantID(String.valueOf(subnet.getTenantId().getValue()).replace("-",""));
160         result.setNetworkUUID(subnet.getNetworkId().getValue());
161         result.setIpVersion(IPV_MAP.get(subnet.getIpVersion()));
162         result.setCidr(subnet.getCidr());
163         result.setGatewayIP(String.valueOf(subnet.getGatewayIp().getValue()));
164         result.setIpV6RaMode(DHCPV6_MAP.get(subnet.getIpv6RaMode()));
165         result.setIpV6AddressMode(DHCPV6_MAP.get(subnet.getIpv6AddressMode()));
166         result.setEnableDHCP(subnet.isEnableDhcp());
167         if (subnet.getAllocationPools() != null) {
168             List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<NeutronSubnetIPAllocationPool>();
169             for (AllocationPools allocationPool : subnet.getAllocationPools()) {
170                 NeutronSubnetIPAllocationPool pool = new NeutronSubnetIPAllocationPool();
171                 pool.setPoolStart(allocationPool.getStart());
172                 pool.setPoolEnd(allocationPool.getEnd());
173                 allocationPools.add(pool);
174             }
175             result.setAllocationPools(allocationPools);
176         }
177         if (subnet.getDnsNameservers() != null) {
178             List<String> dnsNameServers = new ArrayList<String>();
179             for (IpAddress dnsNameServer : subnet.getDnsNameservers()) {
180                 dnsNameServers.add(String.valueOf(dnsNameServer.getValue()));
181             }
182             result.setDnsNameservers(dnsNameServers);
183         }
184         result.setID(subnet.getUuid().getValue());
185 // read through the ports and put the ones in this subnet into the internal
186 // myPorts object.
187 // @deprecated and will be removed in Boron
188         Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
189         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
190             .fetchINeutronPortCRUD(this);
191         INeutronPortCRUD portIf = interfaces.getPortInterface();
192         for (NeutronPort port : portIf.getAllPorts()) {
193             if (port.getFixedIPs() != null) {
194                 for (Neutron_IPs ip : port.getFixedIPs()) {
195                     if (ip.getSubnetUUID().equals(result.getID())) {
196                         allPorts.add(port);
197                     }
198                 }
199             }
200         }
201         List<NeutronPort> ports = new ArrayList<NeutronPort>();
202         ports.addAll(allPorts);
203         result.setPorts(ports);
204         return result;
205     }
206
207     protected Subnet toMd(NeutronSubnet subnet) {
208         SubnetBuilder subnetBuilder = new SubnetBuilder();
209         if (subnet.getName() != null) {
210             subnetBuilder.setName(subnet.getName());
211         }
212         if (subnet.getTenantID() != null) {
213             subnetBuilder.setTenantId(toUuid(subnet.getTenantID()));
214         }
215         if (subnet.getNetworkUUID() != null) {
216             subnetBuilder.setNetworkId(toUuid(subnet.getNetworkUUID()));
217         }
218         if (subnet.getIpVersion() != null) {
219             ImmutableBiMap<Integer, Class<? extends IpVersionBase>> mapper =
220                     IPV_MAP.inverse();
221             subnetBuilder.setIpVersion((Class<? extends IpVersionBase>) mapper.get(subnet
222                     .getIpVersion()));
223         }
224         if (subnet.getCidr() != null) {
225             subnetBuilder.setCidr(subnet.getCidr());
226         }
227         if (subnet.getGatewayIP() != null) {
228             IpAddress ipAddress = new IpAddress(subnet.getGatewayIP()
229                     .toCharArray());
230             subnetBuilder.setGatewayIp(ipAddress);
231         }
232         if (subnet.getIpV6RaMode() != null) {
233             ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
234                     DHCPV6_MAP.inverse();
235             subnetBuilder.setIpv6RaMode((Class<? extends Dhcpv6Base>) mapper.get(subnet.getIpV6RaMode()));
236         }
237         if (subnet.getIpV6AddressMode() != null) {
238             ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
239                     DHCPV6_MAP.inverse();
240             subnetBuilder.setIpv6AddressMode((Class<? extends Dhcpv6Base>) mapper.get(subnet.getIpV6AddressMode()));
241         }
242         subnetBuilder.setEnableDhcp(subnet.getEnableDHCP());
243         if (subnet.getAllocationPools() != null) {
244             List<AllocationPools> allocationPools = new ArrayList<AllocationPools>();
245             for (NeutronSubnetIPAllocationPool allocationPool : subnet
246                     .getAllocationPools()) {
247                 AllocationPoolsBuilder builder = new AllocationPoolsBuilder();
248                 builder.setStart(allocationPool.getPoolStart());
249                 builder.setEnd(allocationPool.getPoolEnd());
250                 AllocationPools temp = builder.build();
251                 allocationPools.add(temp);
252             }
253             subnetBuilder.setAllocationPools(allocationPools);
254         }
255         if (subnet.getDnsNameservers() != null) {
256             List<IpAddress> dnsNameServers = new ArrayList<IpAddress>();
257             for (String dnsNameServer : subnet.getDnsNameservers()) {
258                 IpAddress ipAddress = new IpAddress(dnsNameServer.toCharArray());
259                 dnsNameServers.add(ipAddress);
260             }
261             subnetBuilder.setDnsNameservers(dnsNameServers);
262         }
263         if (subnet.getID() != null) {
264             subnetBuilder.setUuid(toUuid(subnet.getID()));
265         } else {
266             LOGGER.warn("Attempting to write neutron subnet without UUID");
267         }
268         return subnetBuilder.build();
269     }
270
271     @Override
272     protected InstanceIdentifier<Subnet> createInstanceIdentifier(Subnet subnet) {
273         return InstanceIdentifier.create(Neutron.class).child(Subnets.class)
274                 .child(Subnet.class, subnet.getKey());
275     }
276
277     protected InstanceIdentifier<Subnets> createInstanceIdentifier() {
278         return InstanceIdentifier.create(Neutron.class)
279                 .child(Subnets.class);
280     }
281
282     @Override
283     protected Subnet toMd(String uuid) {
284         SubnetBuilder subnetBuilder = new SubnetBuilder();
285         subnetBuilder.setUuid(toUuid(uuid));
286         return subnetBuilder.build();
287     }
288
289     public static void registerNewInterface(BundleContext context,
290                                             ProviderContext providerContext,
291                                             List<ServiceRegistration<?>> registrations) {
292         NeutronSubnetInterface neutronSubnetInterface = new NeutronSubnetInterface(providerContext);
293         ServiceRegistration<INeutronSubnetCRUD> neutronSubnetInterfaceRegistration = context.registerService(INeutronSubnetCRUD.class, neutronSubnetInterface, null);
294         if(neutronSubnetInterfaceRegistration != null) {
295             registrations.add(neutronSubnetInterfaceRegistration);
296         }
297     }
298 }