Migrate implementation/neutron/southbound to IETF YANG model
[lispflowmapping.git] / mappingservice / neutron / src / main / java / org / opendaylight / lispflowmapping / neutron / LispNeutronPortHandler.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 import java.util.List;
13 import java.util.concurrent.Future;
14
15 import org.apache.commons.lang3.exception.ExceptionUtils;
16 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
17 import org.opendaylight.neutron.spi.INeutronPortAware;
18 import org.opendaylight.neutron.spi.NeutronPort;
19 import org.opendaylight.neutron.spi.Neutron_IPs;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.OdlMappingserviceService;
26 import org.opendaylight.yangtools.yang.common.RpcResult;
27
28 /**
29  * Lisp Service implementation of NeutronPortAware API Creation of a new port
30  * results adding the mapping for the port's IP addresses to the port's host_ip
31  * in the mapping service. Currently the NetronPort object does not carry the
32  * required information to achieve the port's host_ip. Once such extension is
33  * available this class shall be updated.
34  *
35  * @author Vina Ermagan
36  *
37  */
38
39 public class LispNeutronPortHandler extends LispNeutronService implements
40         INeutronPortAware {
41
42     // The implementation for each of these services is resolved by the OSGi
43     // Service Manager
44     private volatile ILispNeutronService lispNeutronService;
45
46     @Override
47     public int canCreatePort(NeutronPort port) {
48         LOG.info("Neutron canCreatePort : Port name: " + port.getName());
49
50         return HttpURLConnection.HTTP_OK;
51     }
52
53     @Override
54     public void neutronPortCreated(NeutronPort port) {
55
56         // TODO Consider adding Port MAC -> Port fixed IP in MS
57         // TODO Add Port fixed ip -> host ip , if Port.host_id mapping to
58         // host_ip exists in MS
59
60         LOG.debug("Neutron Port Created : " + port.toString());
61
62         // Check if port.hostID is in map-server, if it is, get host eidtoloc
63         // record?
64         if (port.getBindinghostID() == null) {
65             LOG.error("Adding new Neutron port to lisp service mapping service failed. Port does not have Host_ID. Port : "
66                     + port.toString());
67             return;
68         }
69         Eid hostAddress = LispAddressUtil.asDistinguishedNameEid(port.getBindinghostID());
70
71         MappingRecord eidRecord;
72         List<LocatorRecord> hostLocRecords;
73         GetMappingInput input = LispUtil.buildGetMappingInput(hostAddress);
74         try {
75             OdlMappingserviceService lfmdb = lispNeutronService.getMappingDbService();
76             if (lfmdb == null) {
77                 LOG.debug("lfmdb is null!!!");
78                 return;
79             }
80             Future<RpcResult<GetMappingOutput>> result = lfmdb.getMapping(input);
81             GetMappingOutput output = result.get().getResult();
82
83             // TODO for now only selecting the first EidToLocatorRecord from the
84             // Host_ID mapping
85
86             eidRecord = output.getMappingRecord();
87             hostLocRecords = eidRecord.getLocatorRecord();
88             LOG.debug("hostLocRecords is : {}",hostLocRecords);
89
90
91         } catch (Exception e) {
92             LOG.warn("Failed to GET mapping for EID {}: , mappingInput: {} , Exception: {}", hostAddress, input,
93                     ExceptionUtils.getStackTrace(e));
94             return;
95         }
96
97         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
98         if (fixedIPs != null && fixedIPs.size() > 0) {
99           Eid eidAddress;
100             for (Neutron_IPs ip : fixedIPs) {
101
102                 // TODO Add check/support for IPv6.
103                 // Get subnet for this port, based on v4 or v6 decide address
104                 // iana code.
105
106                 eidAddress = LispAddressUtil.asIpv4PrefixEid(ip.getIpAddress() + "/32");
107                 lispNeutronService.getMappingDbService().addMapping(LispUtil.buildAddMappingInput(eidAddress, hostLocRecords));
108             }
109         }
110
111         LOG.info("Neutron Port Created: Port name: "
112                     + port.getName()
113                     + " Port Fixed IP: "
114                     + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
115                             : "No Fixed IP assigned"));
116
117     }
118
119     @Override
120     public int canUpdatePort(NeutronPort delta, NeutronPort original) {
121         // TODO Change of Fixed IPs are not allowed as we are storing ports by
122         // fixed IPs for now
123
124         if (original.getFixedIPs().equals(original.getFixedIPs())) {
125             LOG.info("Neutron canUpdatePort : Port name: "
126                     + original.getName()
127                     + " Port Fixed IP: "
128                     + (original.getFixedIPs() != null ? original.getFixedIPs()
129                             .get(0) : "No Fixed IP assigned")
130                     + "New Port Fixed IP: "
131                     + (delta.getFixedIPs() != null ? delta.getFixedIPs().get(0)
132                             : "No Fixed IP assigned"));
133             LOG.debug("Neutron canUpdatePort : original" + original.toString()
134                     + " delta : " + delta.toString());
135
136             return HttpURLConnection.HTTP_OK;
137         }
138         return HttpURLConnection.HTTP_NOT_IMPLEMENTED;
139     }
140
141     @Override
142     public void neutronPortUpdated(NeutronPort port) {
143         // TODO Port IP and port's host ip is stored by Lisp Neutron Service. If
144         // there is change to these fields, the update needs to be processed.
145
146         LOG.info("Neutron Port updated: Port name: "
147                 + port.getName()
148                 + " Port Fixed IP: "
149                 + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
150                         : "No Fixed IP assigned"));
151         LOG.debug("Neutron Port Updated : " + port.toString());
152
153     }
154
155     @Override
156     public int canDeletePort(NeutronPort port) {
157         // TODO Check if Port IPs are stored by Lisp Neutron Service. if not
158         // return error code.
159
160         LOG.info("Neutron canDeletePort : Port name: "
161                 + port.getName()
162                 + " Port Fixed IP: "
163                 + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
164                         : "No Fixed IP assigned"));
165         LOG.debug("Neutron canDeltePort: " + port.toString());
166
167         return HttpURLConnection.HTTP_OK;
168     }
169
170     @Override
171     public void neutronPortDeleted(NeutronPort port) {
172         // TODO if port ips existed in MapServer, delete them. Else, log error.
173
174         LOG.info("Neutron Port Deleted: Port name: "
175                 + port.getName()
176                 + " Port Fixed IP: "
177                 + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
178                         : "No Fixed IP assigned"));
179         LOG.debug("Neutron Port Deleted : " + port.toString());
180
181         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
182         if (fixedIPs != null && fixedIPs.size() > 0) {
183             Eid eidAddress;
184
185             for (Neutron_IPs ip : fixedIPs) {
186
187                 // TODO Add check/support for IPv6.
188                 // Get subnet for this port, based on v4 or v6 decide address
189                 // iana code.
190
191                 eidAddress = LispAddressUtil.asIpv4PrefixEid(ip.getIpAddress() + "/32");
192                 lispNeutronService.getMappingDbService().removeMapping(LispUtil.buildRemoveMappingInput(eidAddress));
193
194                 LOG.info("Neutron Port mapping deleted from lisp: "
195                         + " Port Fixed IP: " + ip + "Port host IP: ");
196
197             }
198         }
199
200     }
201
202 }