Neutron port removal fixed
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronPortAware.java
index a22a655ce60fd7162a5f6f8df17dda0c815b7d58..07a0129a81c9dcd1d3042f2fa58794e87cd08972 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
+import com.sun.jndi.cosnaming.IiopUrl;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -100,8 +101,11 @@ public class NeutronPortAware implements NeutronAware<Port> {
         this.epRegistrator = checkNotNull(epRegistrator);
     }
 
-    @Override
-    public void onCreated(Port port, Neutron neutron) {
+    @Override public void onCreated(Port createdItem, Neutron neutron) {
+        onCreated(createdItem, neutron, true);
+    }
+
+    public void onCreated(Port port, Neutron neutron, boolean addBaseEpMapping) {
         LOG.trace("created port - {}", port);
         if (PortUtils.isRouterInterfacePort(port)) {
             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
@@ -114,38 +118,14 @@ public class NeutronPortAware implements NeutronAware<Port> {
             }
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             ContextId routerL3Context = new ContextId(port.getDeviceId());
-            // change L3Context for all EPs with same subnet as router port
-            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron);
-            // set L3Context as parent for bridge domain which is parent of subnet
-            TenantId tenantId = new TenantId(port.getTenantId().getValue());
-            Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), neutron.getSubnets());
-            if (!potentialRouterPortSubnet.isPresent()) {
-                LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}",
-                        port);
-                return;
-            }
-            Subnet routerPortSubnet = potentialRouterPortSubnet.get();
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-            ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
-            ForwardingContext l2Bd = new ForwardingContextBuilder().setContextId(l2BdId)
-                .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
-                .setParent(MappingUtils.createParent(routerL3Context, MappingUtils.L3_CONTEXT))
-                .build();
-            rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
-            // set virtual router IP for subnet
-            NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(
-                    routerPortSubnet, portIpWithSubnet.getIpAddress());
-            rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
 
             AddressEndpointKey addrEpKey = new AddressEndpointKey(port.getMacAddress().getValue(),
-                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
+                MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
             UniqueId portId = new UniqueId(port.getUuid().getValue());
             addBaseEndpointMappings(addrEpKey, portId, rwTx);
 
-            // does the same for tenant forwarding domains
-            processTenantForwarding(routerPortSubnet, routerL3Context, portIpWithSubnet, tenantId, rwTx);
-
-            // Add Qrouter port as Endpoint
+            // Add Qrouter and VPProuter port as Endpoint
             if (port.getAugmentation(PortBindingExtension.class) != null &&
                 PortUtils.DEVICE_VIF_TYPE.equals(port.getAugmentation(PortBindingExtension.class).getVifType())) {
                 LOG.trace("Port is QRouter port: {}", port.getUuid().getValue());
@@ -172,12 +152,36 @@ public class NeutronPortAware implements NeutronAware<Port> {
                     epInBuilder =
                     createEndpointRegFromPort(
                         port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron);
-
                 registerBaseEndpointAndStoreMapping(
-                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
+                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx, addBaseEpMapping);
                 registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
             }
 
+            // change L3Context for all EPs with same subnet as router port
+            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron);
+            // set L3Context as parent for bridge domain which is parent of subnet
+            TenantId tenantId = new TenantId(port.getTenantId().getValue());
+            Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), neutron.getSubnets());
+            if (!potentialRouterPortSubnet.isPresent()) {
+                LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}",
+                        port);
+                return;
+            }
+            Subnet routerPortSubnet = potentialRouterPortSubnet.get();
+            ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
+            ForwardingContext l2Bd = new ForwardingContextBuilder().setContextId(l2BdId)
+                .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
+                .setParent(MappingUtils.createParent(routerL3Context, MappingUtils.L3_CONTEXT))
+                .build();
+            rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
+            // set virtual router IP for subnet
+            NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(
+                    routerPortSubnet, portIpWithSubnet.getIpAddress());
+            rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
+
+            // does the same for tenant forwarding domains
+            processTenantForwarding(routerPortSubnet, routerL3Context, portIpWithSubnet, tenantId, rwTx);
+
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isDhcpPort(port)) {
             // process as normal port but put it to DHCP group
@@ -205,7 +209,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
 
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             registerBaseEndpointAndStoreMapping(
-                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
+                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx, addBaseEpMapping);
             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
@@ -236,7 +240,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 baseEpRegs.add(l3BaseEp.build());
             }
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-            registerBaseEndpointAndStoreMapping(baseEpRegs, port, rwTx);
+            registerBaseEndpointAndStoreMapping(baseEpRegs, port, rwTx, addBaseEpMapping);
             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isRouterGatewayPort(port)) {
@@ -291,14 +295,14 @@ public class NeutronPortAware implements NeutronAware<Port> {
         Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
         for (Port portInSameSubnet : portsInSameSubnet) {
             if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)
-                || PortUtils.isQrouterPort(portInSameSubnet)) {
+                || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
                 // endpoints are created only from neutron normal port or DHCP port
                 Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(portInSameSubnet);
                 if (firstFixedIps.isPresent()) {
                     // endpoint has only one network containment therefore only first IP is used
                     FixedIps ipWithSubnet = firstFixedIps.get();
                     List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
-                    if (PortUtils.isDhcpPort(portInSameSubnet)) {
+                    if (PortUtils.isDhcpPort(portInSameSubnet) || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
                         endpointGroupIds.add(NetworkService.EPG_ID);
                     } else if (PortUtils.isNormalPort(portInSameSubnet)) {
                         endpointGroupIds.add(NetworkClient.EPG_ID);
@@ -315,7 +319,9 @@ public class NeutronPortAware implements NeutronAware<Port> {
                         .setContextType(l3BaseEp.getContextType())
                         .build();
                     epRegistrator.unregisterEndpoint(addrEpUnreg);
-                    epRegistrator.registerEndpoint(l3BaseEp.build());
+                    RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder()
+                        .setAddressEndpointReg(ImmutableList.of(l2BaseEp.build(), l3BaseEp.build())).build();
+                    epRegistrator.registerEndpoint(regBaseEpInput);
 
                     modifyL3ContextForEndpoints(portInSameSubnet, ipWithSubnet, l3BaseEp.getContextId());
                 }
@@ -483,7 +489,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
     }
 
     private void registerBaseEndpointAndStoreMapping(List<AddressEndpointReg> addrEpRegs, Port port,
-            WriteTransaction wTx) {
+            WriteTransaction wTx, boolean addBaseEpMappings) {
         RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(addrEpRegs)
             .build();
 
@@ -493,7 +499,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
             return;
         }
         for (AddressEndpointReg addrEpReg : addrEpRegs) {
-            if (MappingUtils.L2_BRDIGE_DOMAIN.equals(addrEpReg.getContextType())) {
+            if (MappingUtils.L2_BRDIGE_DOMAIN.equals(addrEpReg.getContextType()) && addBaseEpMappings) {
                 UniqueId portId = new UniqueId(port.getUuid().getValue());
                 LOG.trace("Adding Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
                         port.getUuid());
@@ -515,7 +521,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
     }
 
     private void unregisterEndpointAndRemoveMapping(UnregisterEndpointInput baseEpUnreg, Port port,
-            ReadWriteTransaction rwTx) {
+            ReadWriteTransaction rwTx, boolean removeBaseEpMappings) {
         boolean isUnregisteredBaseEndpoint = epRegistrator.unregisterEndpoint(baseEpUnreg);
         if (isUnregisteredBaseEndpoint) {
             UniqueId portId = new UniqueId(port.getUuid().getValue());
@@ -523,7 +529,9 @@ public class NeutronPortAware implements NeutronAware<Port> {
                     MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
             LOG.trace("Removing Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
                     port.getUuid().getValue(), port.getDeviceOwner(), portByBaseEndpointKey);
-            removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
+            if (removeBaseEpMappings) {
+                removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
+            }
         }
     }
 
@@ -537,12 +545,15 @@ public class NeutronPortAware implements NeutronAware<Port> {
     @Override
     public void onUpdated(Port oldPort, Port newPort, Neutron oldNeutron, Neutron newNeutron) {
         LOG.trace("updated port - OLD: {}\nNEW: {}", oldPort, newPort);
-        onDeleted(oldPort, oldNeutron, newNeutron);
-        onCreated(newPort, newNeutron);
+        onDeleted(oldPort, oldNeutron, newNeutron, false);
+        onCreated(newPort, newNeutron, false);
     }
 
-    @Override
-    public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron) {
+    @Override public void onDeleted(Port deletedItem, Neutron oldNeutron, Neutron newNeutron) {
+        onDeleted(deletedItem, oldNeutron, newNeutron, true);
+    }
+
+    public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron, boolean removeBaseEpMapping) {
         LOG.trace("deleted port - {}", port);
         if (PortUtils.isRouterInterfacePort(port)) {
             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
@@ -556,7 +567,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue());
             // change L3Context for all EPs with same subnet as router port
-            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron);
+            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), newNeutron);
             // set L3Context as parent for bridge domain which is parent of subnet
             TenantId tenantId = new TenantId(port.getTenantId().getValue());
             Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(),
@@ -578,22 +589,20 @@ public class NeutronPortAware implements NeutronAware<Port> {
             NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null);
             rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()),
                     subnet);
-            UniqueId portId = new UniqueId(port.getUuid().getValue());
-            PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(),
-                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
-            removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isDhcpPort(port)) {
             LOG.trace("Port is DHCP port: {}", port.getUuid().getValue());
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
-            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
             LOG.trace("Port is normal port: {}", port.getUuid().getValue());
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
-            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isRouterGatewayPort(port)) {
             // do nothing because actual trigger is detaching of port from router