package org.opendaylight.lispflowmapping.neutron;
import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.concurrent.Future;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.opendaylight.lispflowmapping.lisp.util.LispAFIConvertor;
import org.opendaylight.neutron.spi.INeutronPortAware;
import org.opendaylight.neutron.spi.NeutronPort;
+import org.opendaylight.neutron.spi.Neutron_IPs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.LispAFIAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidtolocatorrecords.EidToLocatorRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.LispAddressContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingserviceService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
/**
- * Lisp Service implementation of NeutronPortAware API
- * Creation of a new port results adding the mapping for
- * the port's IP addresses to the port's host_ip in the mapping service.
- * Currently the NetronPort object does not carry the required information
- * to achieve the port's host_ip. Once such extension is available
- * this class shall be updated.
+ * Lisp Service implementation of NeutronPortAware API Creation of a new port
+ * results adding the mapping for the port's IP addresses to the port's host_ip
+ * in the mapping service. Currently the NetronPort object does not carry the
+ * required information to achieve the port's host_ip. Once such extension is
+ * available this class shall be updated.
+ *
+ * @author Vina Ermagan
*
*/
-public class LispNeutronPortHandler extends LispNeutronService implements INeutronPortAware {
+public class LispNeutronPortHandler extends LispNeutronService implements
+ INeutronPortAware {
+
+ // The implementation for each of these services is resolved by the OSGi
+ // Service Manager
+ private volatile ILispNeutronService lispNeutronService;
- @Override
- public int canCreatePort(NeutronPort port) {
+ @Override
+ public int canCreatePort(NeutronPort port) {
LOG.info("Neutron canCreatePort : Port name: " + port.getName());
return HttpURLConnection.HTTP_OK;
- }
-
- @Override
- public void neutronPortCreated(NeutronPort port) {
- // TODO Consider adding Port MAC -> Port fixed IP in MS
- // TODO Add Port fixed ip -> host ip mapping in MS - Requires extension of Port object
+ }
- LOG.info("Neutron Port Created: Port name: " + port.getName() + " Port Fixed IP: " +
- ( port.getFixedIPs() != null ? port.getFixedIPs().get(0) : "No Fixed IP assigned" ));
- LOG.debug("Neutron Port Created : " + port.toString());
+ @Override
+ public void neutronPortCreated(NeutronPort port) {
- }
+ // TODO Consider adding Port MAC -> Port fixed IP in MS
+ // TODO Add Port fixed ip -> host ip , if Port.host_id mapping to
+ // host_ip exists in MS
- @Override
- public int canUpdatePort(NeutronPort delta, NeutronPort original) {
- // TODO Port IP and port's host ip is stored by Lisp Neutron Service. If there is change to these fields, the update needs to be processed.
+ LOG.debug("Neutron Port Created : " + port.toString());
- LOG.info("Neutron canUpdatePort : Port name: " + original.getName() + " Port Fixed IP: " +
- ( original.getFixedIPs() != null ? original.getFixedIPs().get(0) : "No Fixed IP assigned" ));
- LOG.debug("Neutron canUpdatePort : original" + original.toString() + " delta : " + delta.toString());
+ // Check if port.hostID is in map-server, if it is, get host eidtoloc
+ // record?
+ if (port.getBindinghostID() == null) {
+ LOG.error("Adding new Neutron port to lisp service mapping service failed. Port does not have Host_ID. Port : "
+ + port.toString());
+ return;
+ }
+ LispAFIAddress hostAddress = LispAFIConvertor.asDistinguishedNameAddress(port.getBindinghostID());
+
+ EidToLocatorRecord eidRecord;
+ List<LocatorRecord> hostLocRecords;
+ GetMappingInput input = LispUtil.buildGetMappingInput(LispAFIConvertor.toContainer(hostAddress), (short) 0);
+ try {
+ MappingserviceService lfmdb = lispNeutronService.getMappingDbService();
+ if (lfmdb == null) {
+ LOG.debug("lfmdb is null!!!");
+ return;
+ }
+ Future<RpcResult<GetMappingOutput>> result = lfmdb.getMapping(input);
+ GetMappingOutput output = result.get().getResult();
+
+ // TODO for now only selecting the first EidToLocatorRecord from the
+ // Host_ID mapping
+
+ eidRecord = output.getEidToLocatorRecord().get(0);
+ hostLocRecords = eidRecord.getLocatorRecord();
+ LOG.debug("hostLocRecords is : {}",hostLocRecords);
+
+
+ } catch (Exception e) {
+ LOG.warn("Failed to GET mapping for EID {}: , mappingInput: {} , Exception: {}", hostAddress, input,
+ ExceptionUtils.getStackTrace(e));
+ return;
+ }
+
+ List<Neutron_IPs> fixedIPs = port.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ LispAddressContainer eidAddress;
+ for (Neutron_IPs ip : fixedIPs) {
+
+ // TODO Add check/support for IPv6.
+ // Get subnet for this port, based on v4 or v6 decide address
+ // iana code.
+
+ eidAddress = LispAFIConvertor.toContainer(LispAFIConvertor.asIPAfiAddress(ip.getIpAddress()));
+ lispNeutronService.getMappingDbService().addMapping(LispUtil.buildAddMappingInput(eidAddress, hostLocRecords, 32));
+ }
+ }
+
+ LOG.info("Neutron Port Created: Port name: "
+ + port.getName()
+ + " Port Fixed IP: "
+ + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
+ : "No Fixed IP assigned"));
+
+ }
+
+ @Override
+ public int canUpdatePort(NeutronPort delta, NeutronPort original) {
+ // TODO Change of Fixed IPs are not allowed as we are storing ports by
+ // fixed IPs for now
+
+ if (original.getFixedIPs().equals(original.getFixedIPs())) {
+ LOG.info("Neutron canUpdatePort : Port name: "
+ + original.getName()
+ + " Port Fixed IP: "
+ + (original.getFixedIPs() != null ? original.getFixedIPs()
+ .get(0) : "No Fixed IP assigned")
+ + "New Port Fixed IP: "
+ + (delta.getFixedIPs() != null ? delta.getFixedIPs().get(0)
+ : "No Fixed IP assigned"));
+ LOG.debug("Neutron canUpdatePort : original" + original.toString()
+ + " delta : " + delta.toString());
+
+ return HttpURLConnection.HTTP_OK;
+ }
+ return HttpURLConnection.HTTP_NOT_IMPLEMENTED;
+ }
+
+ @Override
+ public void neutronPortUpdated(NeutronPort port) {
+ // TODO Port IP and port's host ip is stored by Lisp Neutron Service. If
+ // there is change to these fields, the update needs to be processed.
+
+ LOG.info("Neutron Port updated: Port name: "
+ + port.getName()
+ + " Port Fixed IP: "
+ + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
+ : "No Fixed IP assigned"));
+ LOG.debug("Neutron Port Updated : " + port.toString());
+
+ }
+
+ @Override
+ public int canDeletePort(NeutronPort port) {
+ // TODO Check if Port IPs are stored by Lisp Neutron Service. if not
+ // return error code.
+
+ LOG.info("Neutron canDeletePort : Port name: "
+ + port.getName()
+ + " Port Fixed IP: "
+ + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
+ : "No Fixed IP assigned"));
+ LOG.debug("Neutron canDeltePort: " + port.toString());
return HttpURLConnection.HTTP_OK;
- }
+ }
+
+ @Override
+ public void neutronPortDeleted(NeutronPort port) {
+ // TODO if port ips existed in MapServer, delete them. Else, log error.
- @Override
- public void neutronPortUpdated(NeutronPort port) {
- // TODO Port IP and port's host ip is stored by Lisp Neutron Service. If there is change to these fields, the update needs to be processed.
+ LOG.info("Neutron Port Deleted: Port name: "
+ + port.getName()
+ + " Port Fixed IP: "
+ + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
+ : "No Fixed IP assigned"));
+ LOG.debug("Neutron Port Deleted : " + port.toString());
- LOG.info("Neutron Port updated: Port name: " + port.getName() + " Port Fixed IP: " +
- ( port.getFixedIPs() != null ? port.getFixedIPs().get(0) : "No Fixed IP assigned" ));
- LOG.debug("Neutron Port Updated : " + port.toString());
+ List<Neutron_IPs> fixedIPs = port.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ LispAddressContainer eidAddress;
- }
+ for (Neutron_IPs ip : fixedIPs) {
- @Override
- public int canDeletePort(NeutronPort port) {
- // TODO Check if Port IPs are stored by Lisp Neutron Service. if not return error code.
+ // TODO Add check/support for IPv6.
+ // Get subnet for this port, based on v4 or v6 decide address
+ // iana code.
- LOG.info("Neutron canDeletePort : Port name: " + port.getName() + " Port Fixed IP: " +
- ( port.getFixedIPs() != null ? port.getFixedIPs().get(0) : "No Fixed IP assigned" ));
- LOG.debug("Neutron canDeltePort: " + port.toString());
+ eidAddress = LispAFIConvertor.toContainer(LispAFIConvertor.asIPAfiAddress(ip.getIpAddress()));
+ lispNeutronService.getMappingDbService().removeMapping(LispUtil.buildRemoveMappingInput(eidAddress,32));
- return HttpURLConnection.HTTP_OK;
- }
+ LOG.info("Neutron Port mapping deleted from lisp: "
+ + " Port Fixed IP: " + ip + "Port host IP: ");
- @Override
- public void neutronPortDeleted(NeutronPort port) {
- // TODO if port ips existed in MapServer, delete them. Else, log error.
+ }
+ }
- LOG.info("Neutron Port Deleted: Port name: " + port.getName() + " Port Fixed IP: " +
- ( port.getFixedIPs() != null ? port.getFixedIPs().get(0) : "No Fixed IP assigned" ));
- LOG.debug("Neutron Port Deleted : " + port.toString());
+ }
- }
}