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