Merge "GBP UI fixes"
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronFloatingIpAware.java
1 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
2
3 import static com.google.common.base.Preconditions.checkNotNull;
4
5 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
6 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
7 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
8 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
9 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
10 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
11 import org.opendaylight.neutron.spi.INeutronFloatingIPAware;
12 import org.opendaylight.neutron.spi.INeutronPortCRUD;
13 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
14 import org.opendaylight.neutron.spi.NeutronFloatingIP;
15 import org.opendaylight.neutron.spi.NeutronPort;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.floating.ip.association.mappings.floating.ip.ports.by.internal.ports.FloatingIpPortByInternalPortBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.floating.ip.association.mappings.internal.ports.by.floating.ip.ports.InternalPortByFloatingIpPort;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.floating.ip.association.mappings.internal.ports.by.floating.ip.ports.InternalPortByFloatingIpPortBuilder;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import com.google.common.base.Strings;
25
26 public class NeutronFloatingIpAware implements INeutronFloatingIPAware {
27
28     public static final Logger LOG = LoggerFactory.getLogger(NeutronFloatingIpAware.class);
29     private final DataBroker dataProvider;
30     private final EndpointService epService;
31
32     public NeutronFloatingIpAware(DataBroker dataProvider, EndpointService epService) {
33         this.dataProvider = checkNotNull(dataProvider);
34         this.epService = checkNotNull(epService);
35     }
36
37     @Override
38     public int canCreateFloatingIP(NeutronFloatingIP floatingIP) {
39         LOG.trace("canCreateFloatingIP - {}", floatingIP);
40         return StatusCode.OK;
41     }
42
43     @Override
44     public void neutronFloatingIPCreated(NeutronFloatingIP floatingIP) {
45         LOG.trace("neutronFloatingIPCreated - {}", floatingIP);
46     }
47
48     @Override
49     public int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original) {
50         LOG.trace("canUpdateFloatingIP - delta: {} original: {}", delta, original);
51         // floating IP UUID is same as device ID of a port representing floating IP
52         UniqueId floatingIpPortId = NeutronPortAware.getFloatingIpPortIdByDeviceId(original.getFloatingIPUUID());
53         if (floatingIpPortId == null) {
54             LOG.warn("Illegal state - Port representing floating ip where floating IP uuid is {} does not exist.",
55                     original.getFloatingIPUUID());
56             return StatusCode.INTERNAL_SERVER_ERROR;
57         }
58
59         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
60         String oldFixedIPAddress = Strings.nullToEmpty(original.getFixedIPAddress());
61         String oldPortUUID = Strings.nullToEmpty(original.getPortUUID());
62         String newFixedIPAddress = Strings.nullToEmpty(delta.getFixedIPAddress());
63         String newPortUUID = Strings.nullToEmpty(delta.getPortUUID());
64         if (oldFixedIPAddress.equals(newFixedIPAddress) && oldPortUUID.equals(newPortUUID)) {
65             // interesting fields were not changed
66             return StatusCode.OK;
67         }
68
69         if ((!oldFixedIPAddress.isEmpty() && newFixedIPAddress.isEmpty())
70                 || (!oldPortUUID.isEmpty() && newPortUUID.isEmpty())) {
71             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
72                     NeutronGbpIidFactory.internalPortByFloatingIpPortIid(floatingIpPortId), rwTx);
73             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
74                     NeutronGbpIidFactory.floatingIpPortByInternalPortIid(new UniqueId(oldPortUUID)), rwTx);
75             // TODO unregister EP representing floating ip port
76         } else if (!newFixedIPAddress.isEmpty() && !newPortUUID.isEmpty()) {
77             // workaround for https://bugs.opendaylight.org/show_bug.cgi?id=3368
78             // otherwise we will create port representing floating IP in NeutronPortAware
79             Integer errorCode = registerFloatingIpPort(original.getTenantUUID(), floatingIpPortId.getValue(), rwTx);
80             if (errorCode != null) {
81                 rwTx.cancel();
82                 return errorCode;
83             }
84
85             UniqueId internalPortId = new UniqueId(newPortUUID);
86             InternalPortByFloatingIpPort internalPortByFloatingIpPort = new InternalPortByFloatingIpPortBuilder().setFloatingIpPortId(
87                     floatingIpPortId)
88                 .setFloatingIpPortIpAddress(Utils.createIpAddress(original.getFloatingIPAddress()))
89                 .setInternalPortId(internalPortId)
90                 .setInternalPortIpAddress(Utils.createIpAddress(newFixedIPAddress))
91                 .build();
92             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.internalPortByFloatingIpPortIid(floatingIpPortId),
93                     internalPortByFloatingIpPort, true);
94             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.floatingIpPortByInternalPortIid(internalPortId),
95                     new FloatingIpPortByInternalPortBuilder(internalPortByFloatingIpPort).build(), true);
96         }
97         boolean isSubmitToDsSuccessful = DataStoreHelper.submitToDs(rwTx);
98         if (!isSubmitToDsSuccessful) {
99             return StatusCode.INTERNAL_SERVER_ERROR;
100         }
101
102         return StatusCode.OK;
103     }
104
105     private Integer registerFloatingIpPort(String tenantUUID, String floatingIpPortUUID, ReadWriteTransaction rwTx) {
106         INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
107         if (portInterface == null) {
108             LOG.warn("Illegal state - No provider for {}", INeutronPortCRUD.class.getName());
109             return StatusCode.INTERNAL_SERVER_ERROR;
110         }
111         NeutronPort floatingIpPort = portInterface.getPort(floatingIpPortUUID);
112         // TenantId tenantId = new TenantId(Utils.normalizeUuid());
113         floatingIpPort.setTenantID(tenantUUID);
114         boolean isNeutronPortCreated = NeutronPortAware.addNeutronPort(floatingIpPort, rwTx, epService);
115         if (!isNeutronPortCreated) {
116             rwTx.cancel();
117             return StatusCode.INTERNAL_SERVER_ERROR;
118         }
119         return null;
120     }
121
122     @Override
123     public void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP) {
124         LOG.trace("neutronFloatingIPUpdated - {}", floatingIP);
125     }
126
127     @Override
128     public int canDeleteFloatingIP(NeutronFloatingIP floatingIP) {
129         LOG.trace("canDeleteFloatingIP - {}", floatingIP);
130         return StatusCode.OK;
131     }
132
133     @Override
134     public void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP) {
135         LOG.trace("neutronFloatingIPDeleted - {}", floatingIP);
136     }
137
138 }