Fix for Neutron Port update for VPP 65/48665/6
authorMichal Cmarada <mcmarada@cisco.com>
Tue, 29 Nov 2016 12:59:24 +0000 (13:59 +0100)
committerMichal Cmarada <mcmarada@cisco.com>
Tue, 29 Nov 2016 12:59:24 +0000 (13:59 +0100)
Change-Id: I1baf4e77b797d5f9d3e79dd619b6ee6e0ff4a1ed
Signed-off-by: Michal Cmarada <mcmarada@cisco.com>
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortAware.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java

index 454b4dea38eda59bd72c631c911b884c769b5325..01b92e1e3889c1de3601ec5140b346800a893aab 100644 (file)
@@ -100,8 +100,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());
@@ -149,7 +152,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
                     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);
             }
 
@@ -205,7 +208,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 +239,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)) {
@@ -485,7 +488,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();
 
@@ -495,7 +498,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());
@@ -517,7 +520,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());
@@ -525,7 +528,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);
+            }
         }
     }
 
@@ -539,12 +544,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());
@@ -589,13 +597,13 @@ public class NeutronPortAware implements NeutronAware<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
index 8746b33bc85a61a43d6c4bd8c233f5cc4298a887..df44f2cfa0c2af43b9a9e4a1266d29f8e803a54b 100644 (file)
@@ -19,10 +19,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gb
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 \r
 public class PortAware extends DataTreeChangeHandler<BaseEndpointByPort> implements\r
         MappingProvider<Port> {\r
 \r
+    private static final Logger LOG = LoggerFactory.getLogger(PortAware.class);\r
     private final PortHandler portHandler;\r
 \r
     protected PortAware(PortHandler portHandler, DataBroker dataProvider) {\r
@@ -43,16 +46,19 @@ public class PortAware extends DataTreeChangeHandler<BaseEndpointByPort> impleme
 \r
     @Override\r
     public void processCreatedNeutronDto(Port port) {\r
+        LOG.trace("Neutron port created: {}", port);\r
         portHandler.processCreated(port);\r
     }\r
 \r
     @Override\r
     public void processUpdatedNeutronDto(Port original, Port delta) {\r
+        LOG.trace("Neutron port updated: {}, delta {}", original, delta);\r
         portHandler.processUpdated(original, delta);\r
     }\r
 \r
     @Override\r
     public void processDeletedNeutronDto(Port port) {\r
+        LOG.trace("Neutron port deleted: {}", port);\r
         // handled by BaseEndpointByPort removal\r
     }\r
 \r
index 560d1556613de73e8ac23eb4ea396c5cea410e57..434da171c2dc0900e5027ff7125c2f4a917800b1 100644 (file)
@@ -38,6 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_render
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCaseBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.binding.attributes.VifDetails;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;\r
@@ -64,6 +65,8 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;\r
 import com.google.common.base.Optional;\r
 \r
+import javax.annotation.Nullable;\r
+import java.util.Collections;\r
 import java.util.List;\r
 \r
 public class PortHandler implements TransactionChainListener {\r
@@ -140,6 +143,12 @@ public class PortHandler implements TransactionChainListener {
     }\r
 \r
     void processUpdated(Port original, Port delta) {\r
+        if (!isUpdateNeeded(original, delta)){\r
+            LOG.trace("Port update skipped, port didn`t change. before {}, after: {}" , original, delta);\r
+            return;\r
+        }\r
+\r
+        LOG.trace("Updating port before: {}, after: {}" , original, delta);\r
         if (isValidVhostUser(original)) {\r
             ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
             Optional<BaseEndpointByPort> optBebp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,\r
@@ -148,12 +157,40 @@ public class PortHandler implements TransactionChainListener {
             if (!optBebp.isPresent()) {\r
                 return;\r
             }\r
+            LOG.trace("Updating port - deleting old port {}" , optBebp.get().getPortId());\r
             processDeleted(optBebp.get());\r
         }\r
+        LOG.trace("Updating port - creating new port {}" , delta.getUuid());\r
         processCreated(delta);\r
     }\r
 \r
+    private boolean isUpdateNeeded(Port oldPort, Port newPort) {\r
+        //TODO fix this to better support update of ports for VPP\r
+        PortBindingExtension oldPortAugmentation = oldPort.getAugmentation(PortBindingExtension.class);\r
+        PortBindingExtension newPortAugmentation = newPort.getAugmentation(PortBindingExtension.class);\r
+\r
+        List<VifDetails> vifDetails = oldPortAugmentation.getVifDetails();\r
+\r
+        if (newPortAugmentation == null) {\r
+            LOG.trace("Port {} is no longer a vhost type port, updating port...");\r
+            return true;\r
+        }\r
+\r
+        if (!oldPortAugmentation.getHostId().equals(newPortAugmentation.getHostId()) ||\r
+            nullToEmpty(vifDetails).size() != nullToEmpty(newPortAugmentation.getVifDetails()).size()) {\r
+            return true;\r
+        }\r
+\r
+        for (VifDetails vifDetail : nullToEmpty(vifDetails)) {\r
+            //check if vhostuser_socket, vhostuser_mode and port_filter are changed\r
+            if (!newPortAugmentation.getVifDetails().contains(vifDetail))\r
+                return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
     void processDeleted(BaseEndpointByPort bebp) {\r
+        LOG.trace("Deleting vpp-endpoint by BaseEndpointByPort {}" , bebp);\r
         VppEndpointKey vppEpKey = new VppEndpointKey(bebp.getAddress(), bebp.getAddressType(), bebp.getContextId(),\r
                 bebp.getContextType());\r
         InstanceIdentifier<VppEndpoint> vppEpIid = createVppEndpointIid(vppEpKey);\r
@@ -340,4 +377,8 @@ public class PortHandler implements TransactionChainListener {
     public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {\r
         LOG.trace("Transaction chain was successful. {}", chain);\r
     }\r
+\r
+    private <T> List<T> nullToEmpty(@Nullable List<T> list) {\r
+        return list == null ? Collections.emptyList() : list;\r
+    }\r
 }\r