Reorganize mappingservice.implementation
[lispflowmapping.git] / mappingservice / neutron / src / main / java / org / opendaylight / lispflowmapping / neutron / LispNeutronSubnetHandler.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc.  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.lispflowmapping.neutron;
10
11 import java.net.HttpURLConnection;
12
13 import org.apache.commons.lang3.exception.ExceptionUtils;
14 import org.apache.commons.net.util.SubnetUtils;
15 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
16 import org.opendaylight.lispflowmapping.lisp.util.LispAFIConvertor;
17 import org.opendaylight.neutron.spi.INeutronSubnetAware;
18 import org.opendaylight.neutron.spi.NeutronSubnet;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LispAFIAddress;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer;
21
22 /**
23  * Lisp Service implementation of NeutronSubnetAware API Creation of a new
24  * Subnet results in defining the subnet as an EID prefix in the LISP Mapping
25  * System with subnet's network UUID as the key to use for registering mappings
26  * for the subnet.
27  *
28  * @author Vina Ermagan
29  *
30  */
31 public class LispNeutronSubnetHandler extends LispNeutronService implements
32                 INeutronSubnetAware {
33         private static final Integer SIX = Integer.valueOf(6);
34
35         // The implementation for each of these services is resolved by the OSGi
36         // Service Manager
37         private volatile ILispNeutronService lispNeutronService;
38
39         @Override
40         public int canCreateSubnet(NeutronSubnet subnet) {
41                 LOG.info("Neutron canCreateSubnet : Subnet name: " + subnet.getName()
42                                 + " Subnet Cidr: " + subnet.getCidr());
43                 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
44                 if (SIX.equals(subnet.getIpVersion())) {
45                         return HttpURLConnection.HTTP_PARTIAL;
46                 }
47                 return HttpURLConnection.HTTP_OK;
48         }
49
50         /**
51          * Method adds the newly created subnet as an EID prefix to the
52          * MappingService. The subnet's network UUID is used as the key for this EID
53          * prefix.
54          *
55          */
56         @Override
57         public void neutronSubnetCreated(NeutronSubnet subnet) {
58                 // TODO update for multi-tenancy
59
60                 LOG.info("Neutron Subnet Created request : Subnet name: "
61                                 + subnet.getName() + " Subnet Cidr: " + subnet.getCidr());
62                 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
63
64                 int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
65                 SubnetUtils util = new SubnetUtils(subnet.getCidr());
66                 SubnetInfo info = util.getInfo();
67
68                 // Determine the IANA code for the subnet IP version
69                 // Default is set to IPv4 for neutron subnets
70
71                 LispAFIAddress lispAddress = LispAFIConvertor.asIPAfiAddress(info.getNetworkAddress());
72                 LispAddressContainer addressContainer = LispAFIConvertor.toContainer(lispAddress);
73
74                 try {
75
76             lispNeutronService.getMappingDbService().addKey((LispUtil.buildAddKeyInput(addressContainer,subnet.getNetworkUUID(), masklen)));
77
78                         LOG.debug("Neutron Subnet Added to MapServer : Subnet name: "
79                                         + subnet.getName() + " EID Prefix: "
80                                         + addressContainer.toString() + " Key: "
81                                         + subnet.getNetworkUUID());
82                 } catch (Exception e) {
83                         LOG.error("Adding new subnet to lisp service mapping service failed. Subnet : "
84                                         + subnet.toString() + "Error: " + ExceptionUtils.getStackTrace(e));
85                 }
86         LOG.info("Neutron Subnet Created request : Subnet name: "
87                 + subnet.getName() + " Subnet Cidr: " + subnet.getCidr());
88
89         }
90
91         /**
92          * Method to check whether new Subnet can be created by LISP implementation
93          * of Neutron service API. Since we store the Cidr part of the subnet as the
94          * main key to the Lisp mapping service, we do not support updates to
95          * subnets that change it's cidr.
96          */
97         @Override
98         public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original) {
99                 if (delta == null || original == null) {
100                         LOG.error("Neutron canUpdateSubnet rejected: subnet objects were null");
101                         return HttpURLConnection.HTTP_BAD_REQUEST;
102                 }
103                 LOG.info("Neutron canUpdateSubnet : Subnet name: " + original.getName()
104                                 + " Subnet Cidr: " + original.getCidr());
105                 LOG.debug("Lisp Neutron Subnet update: original : "
106                                 + original.toString() + " delta : " + delta.toString());
107
108                 // We do not accept a Subnet update that changes the cidr. If cider or
109                 // network UUID is changed, return error.
110                 if (!(original.getCidr().equals(delta.getCidr()))) {
111                         LOG.error("Neutron canUpdateSubnet rejected: Subnet name: "
112                                         + original.getName() + " Subnet Cidr: "
113                                         + original.getCidr());
114                         return HttpURLConnection.HTTP_CONFLICT;
115                 }
116                 return HttpURLConnection.HTTP_OK;
117         }
118
119         @Override
120         public void neutronSubnetUpdated(NeutronSubnet subnet) {
121                 // Nothing to do here.
122         }
123
124         /**
125          * Method to check if subnet can be deleted. Returns error only if subnet
126          * does not exist in the lisp mapping service.
127          */
128         @Override
129         public int canDeleteSubnet(NeutronSubnet subnet) {
130                 LOG.info("Neutron canDeleteSubnet : Subnet name: " + subnet.getName()
131                                 + " Subnet Cidr: " + subnet.getCidr() + "Key: "
132                                 + subnet.getNetworkUUID());
133                 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
134
135
136                         return HttpURLConnection.HTTP_OK;
137         }
138
139         /**
140          * Method removes the EID prefix and key associated with the deleted subnet
141          * from Lisp mapping service.
142          */
143         @Override
144         public void neutronSubnetDeleted(NeutronSubnet subnet) {
145                 LOG.info("Neutron Subnet Deleted Request : Subnet name: "
146                                 + subnet.getName() + " Subnet Cidr: " + subnet.getCidr()
147                                 + "Key: " + subnet.getNetworkUUID());
148                 LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
149
150                 int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
151                 SubnetUtils util = new SubnetUtils(subnet.getCidr());
152                 SubnetInfo info = util.getInfo();
153
154                 // Determine the IANA code for the subnet IP version
155                 // Default is set to IPv4 for neutron subnets
156
157         LispAFIAddress lispAddress = LispAFIConvertor.asIPAfiAddress(info.getNetworkAddress());
158         LispAddressContainer addressContainer = LispAFIConvertor.toContainer(lispAddress);
159
160         try {
161
162             lispNeutronService.getMappingDbService().removeKey(LispUtil.buildRemoveKeyInput(addressContainer, masklen));
163
164                         LOG.debug("Neutron Subnet Deleted from MapServer : Subnet name: "
165                                         + subnet.getName() + " Eid Prefix: "
166                                         + addressContainer.toString() + " Key: "
167                                         + subnet.getNetworkUUID());
168                 } catch (Exception e) {
169                         LOG.error("Deleting subnet's EID prefix from mapping service failed + Subnet: "
170                                         + subnet.toString() + "Error: " + ExceptionUtils.getStackTrace(e));
171                 }
172         }
173
174 }