Code improvements for FDS scenarios
[groupbasedpolicy.git] / neutron-vpp-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / vpp / mapper / processors / PortHandler.java
index b3f7ab56cb7c4655ccd05367f87370fa63eaef55..adf92cc3f43d5be3199eb7c202a29ef6e3fd2eaf 100644 (file)
@@ -14,9 +14,7 @@ import java.util.List;
 import javax.annotation.Nonnull;\r
 import javax.annotation.Nullable;\r
 \r
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;\r
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;\r
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
@@ -24,6 +22,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;\r
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;\r
+import org.opendaylight.groupbasedpolicy.util.SyncedChain;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;\r
@@ -67,7 +66,9 @@ import org.slf4j.LoggerFactory;
 \r
 import com.google.common.annotations.VisibleForTesting;\r
 import com.google.common.base.Optional;\r
+import com.google.common.base.Preconditions;\r
 import com.google.common.base.Strings;\r
+\r
 public class PortHandler implements TransactionChainListener {\r
 \r
     private static final Logger LOG = LoggerFactory.getLogger(PortHandler.class);\r
@@ -85,20 +86,18 @@ public class PortHandler implements TransactionChainListener {
     static final String DEFAULT_NODE = "default";\r
 \r
     private final NodeId routingNode;\r
-    private BindingTransactionChain transactionChain;\r
+    private SyncedChain syncedChain;\r
     private DataBroker dataBroker;\r
 \r
     PortHandler(DataBroker dataBroker, NodeId routingNodeId) {\r
         this.dataBroker = dataBroker;\r
         this.routingNode = routingNodeId;\r
-        transactionChain = this.dataBroker.createTransactionChain(this);\r
+        this.syncedChain = new SyncedChain(Preconditions.checkNotNull(dataBroker.createTransactionChain(this)));\r
     }\r
 \r
     void processCreated(Port port) {\r
-        ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
-        Optional<BaseEndpointByPort> optBaseEpByPort = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,\r
-                createBaseEpByPortIid(port.getUuid()), rTx);\r
-        rTx.close();\r
+        Optional<BaseEndpointByPort> optBaseEpByPort =\r
+                syncedChain.readFromDs(LogicalDatastoreType.OPERATIONAL, createBaseEpByPortIid(port.getUuid()));\r
         if (!optBaseEpByPort.isPresent()) {\r
             return;\r
         }\r
@@ -106,10 +105,8 @@ public class PortHandler implements TransactionChainListener {
     }\r
 \r
     void processCreated(BaseEndpointByPort bebp) {\r
-        ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
-        Optional<Port> optPort = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
-                createPortIid(bebp.getPortId()), rTx);\r
-        rTx.close();\r
+        Optional<Port> optPort =\r
+                syncedChain.readFromDs(LogicalDatastoreType.CONFIGURATION, createPortIid(bebp.getPortId()));\r
         if (!optPort.isPresent()) {\r
             return;\r
         }\r
@@ -151,29 +148,27 @@ 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
+        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
+        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
-                    createBaseEpByPortIid(original.getUuid()), rTx);\r
-            rTx.close();\r
+            Optional<BaseEndpointByPort> optBebp =\r
+                    syncedChain.readFromDs(LogicalDatastoreType.OPERATIONAL, createBaseEpByPortIid(original.getUuid()));\r
             if (!optBebp.isPresent()) {\r
                 return;\r
             }\r
-            LOG.trace("Updating port - deleting old port {}" , optBebp.get().getPortId());\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
+        LOG.trace("Updating port - creating new port {}", delta.getUuid());\r
         processCreated(delta);\r
     }\r
 \r
     private boolean isUpdateNeeded(final Port oldPort, final Port newPort) {\r
-        //TODO fix this to better support update of ports for VPP\r
+        // TODO fix this to better support update of ports for VPP\r
         final PortBindingExtension oldPortAugmentation = oldPort.getAugmentation(PortBindingExtension.class);\r
         final PortBindingExtension newPortAugmentation = newPort.getAugmentation(PortBindingExtension.class);\r
 \r
@@ -188,12 +183,15 @@ public class PortHandler implements TransactionChainListener {
         final String newVifType = newPortAugmentation.getVifType();\r
 \r
         // TODO potential bug here\r
-        // Temporary change for Openstack Mitaka: If old neutron-binding:vif-type is vhost, new one is unbound and\r
-        // device owner is ROUTER_OWNER, skip update. Openstack (or ml2) sometimes sends router update messages in\r
+        // Temporary change for Openstack Mitaka: If old neutron-binding:vif-type is vhost, new one\r
+        // is unbound and\r
+        // device owner is ROUTER_OWNER, skip update. Openstack (or ml2) sometimes sends router\r
+        // update messages in\r
         // incorrect order which causes unwanted port removal\r
-        if (oldVifType.equals(VHOST_USER) && newVifType.equals(UNBOUND) && oldDeviceOwner != null &&\r
-                ROUTER_OWNER.equals(oldDeviceOwner) && ROUTER_OWNER.equals(newDeviceOwner)) {\r
-            LOG.warn("Port vif-type was updated from vhost to unbound. This update is currently disabled and will be skipped");\r
+        if (oldVifType.equals(VHOST_USER) && newVifType.equals(UNBOUND) && oldDeviceOwner != null\r
+                && ROUTER_OWNER.equals(oldDeviceOwner) && ROUTER_OWNER.equals(newDeviceOwner)) {\r
+            LOG.warn(\r
+                    "Port vif-type was updated from vhost to unbound. This update is currently disabled and will be skipped");\r
             return false;\r
         }\r
 \r
@@ -204,13 +202,13 @@ public class PortHandler implements TransactionChainListener {
 \r
         final List<VifDetails> vifDetails = oldPortAugmentation.getVifDetails();\r
 \r
-        if (!oldPortAugmentation.getHostId().equals(newPortAugmentation.getHostId()) ||\r
-            nullToEmpty(vifDetails).size() != nullToEmpty(newPortAugmentation.getVifDetails()).size()) {\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
+            // check if vhostuser_socket, vhostuser_mode and port_filter are changed\r
             if (!newPortAugmentation.getVifDetails().contains(vifDetail))\r
                 return true;\r
         }\r
@@ -218,13 +216,11 @@ public class PortHandler implements TransactionChainListener {
     }\r
 \r
     void processDeleted(BaseEndpointByPort bebp) {\r
-        LOG.trace("Deleting vpp-endpoint by 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
-        ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
-        Optional<VppEndpoint> readVppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, vppEpIid, rTx);\r
-        rTx.close();\r
+        Optional<VppEndpoint> readVppEp = syncedChain.readFromDs(LogicalDatastoreType.CONFIGURATION, vppEpIid);\r
         if (readVppEp.isPresent()) {\r
             writeVppEndpoint(vppEpIid, null);\r
             LOG.debug("Deleted vpp-endpoint {}", vppEpKey);\r
@@ -232,13 +228,13 @@ public class PortHandler implements TransactionChainListener {
     }\r
 \r
     private synchronized void writeVppEndpoint(InstanceIdentifier<VppEndpoint> vppEpIid, VppEndpoint vppEp) {\r
-        WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();\r
+        WriteTransaction wTx = syncedChain.newWriteOnlyTransaction();\r
         if (vppEp != null) {\r
             wTx.put(LogicalDatastoreType.CONFIGURATION, vppEpIid, vppEp, true);\r
         } else {\r
             wTx.delete(LogicalDatastoreType.CONFIGURATION, vppEpIid);\r
         }\r
-        wTx.submit();\r
+        syncedChain.submitNow(wTx);\r
     }\r
 \r
     @VisibleForTesting\r
@@ -273,8 +269,8 @@ public class PortHandler implements TransactionChainListener {
 \r
         } else if (isValidQRouterPort(port)) {\r
             TapCase tapCase = new TapCaseBuilder().setPhysicalAddress(new PhysAddress(port.getMacAddress().getValue()))\r
-                    .setName(createQRouterPortName(port.getUuid()))\r
-                    .build();\r
+                .setName(createQRouterPortName(port.getUuid()))\r
+                .build();\r
             vppEpBuilder.setInterfaceTypeChoice(tapCase);\r
             vppEpBuilder.addAugmentation(ExcludeFromPolicy.class, excludeFromPolicy);\r
 \r
@@ -286,10 +282,8 @@ public class PortHandler implements TransactionChainListener {
                 vppEpBuilder.setVppNodeId(routingNode);\r
             } else if (port.getDeviceId() != null) {\r
                 LOG.debug("Resolving host-id for unbound router port {}", port.getUuid());\r
-                ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();\r
-                Optional<Ports> optPorts = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
-                        InstanceIdentifier.builder(Neutron.class).child(Ports.class).build(), readTx);\r
-                readTx.close();\r
+                Optional<Ports> optPorts = syncedChain.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+                        InstanceIdentifier.builder(Neutron.class).child(Ports.class).build());\r
                 if (optPorts.isPresent() && optPorts.get().getPort() != null) {\r
                     java.util.Optional<Port> optPortOnTheSameNode = optPorts.get()\r
                         .getPort()\r
@@ -328,18 +322,16 @@ public class PortHandler implements TransactionChainListener {
     }\r
 \r
     private LoopbackCase getLoopbackCase(Port port) {\r
-        LoopbackCaseBuilder loopbackCase = new LoopbackCaseBuilder()\r
-            .setPhysAddress(new PhysAddress(port.getMacAddress().getValue()));\r
+        LoopbackCaseBuilder loopbackCase =\r
+                new LoopbackCaseBuilder().setPhysAddress(new PhysAddress(port.getMacAddress().getValue()));\r
         Optional<FixedIps> fixedIpsOptional = resolveFirstFixedIps(port);\r
-        if(fixedIpsOptional.isPresent() && fixedIpsOptional.get().getIpAddress() != null){\r
+        if (fixedIpsOptional.isPresent() && fixedIpsOptional.get().getIpAddress() != null) {\r
             loopbackCase.setIpAddress(fixedIpsOptional.get().getIpAddress());\r
-            ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
-            Optional<Subnet> subnetOptional =\r
-                DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+            Optional<Subnet> subnetOptional = syncedChain.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
                     InstanceIdentifier.builder(Neutron.class)\r
                         .child(Subnets.class)\r
                         .child(Subnet.class, new SubnetKey(fixedIpsOptional.get().getSubnetId()))\r
-                        .build(), rTx);\r
+                        .build());\r
             if (subnetOptional.isPresent()) {\r
                 Ipv4Prefix ipv4Prefix = subnetOptional.get().getCidr().getIpv4Prefix();\r
                 loopbackCase.setIpPrefix(new IpPrefix(ipv4Prefix));\r
@@ -363,14 +355,12 @@ public class PortHandler implements TransactionChainListener {
      */\r
     private boolean isValidQRouterPort(Port port) {\r
         Optional<Router> optRouter = getRouterOptional(port);\r
-        return !optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
-                && port.getMacAddress() != null;\r
+        return !optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER) && port.getMacAddress() != null;\r
     }\r
 \r
     private boolean isValidVppRouterPort(Port port) {\r
         Optional<Router> optRouter = getRouterOptional(port);\r
-        return optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
-            && port.getMacAddress() != null;\r
+        return optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER) && port.getMacAddress() != null;\r
     }\r
 \r
     private Optional<Router> getRouterOptional(Port port) {\r
@@ -384,13 +374,9 @@ public class PortHandler implements TransactionChainListener {
             // port.getDeviceId() may not match Uuid.PATTERN_CONSTANTS\r
             return Optional.absent();\r
         }\r
-        ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
-        InstanceIdentifier<Router> routerIid = InstanceIdentifier.builder(Neutron.class)\r
-            .child(Routers.class)\r
-            .child(Router.class, routerKey)\r
-            .build();\r
-        Optional<Router> optRouter = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, routerIid, rTx);\r
-        rTx.close();\r
+        InstanceIdentifier<Router> routerIid =\r
+                InstanceIdentifier.builder(Neutron.class).child(Routers.class).child(Router.class, routerKey).build();\r
+        Optional<Router> optRouter = syncedChain.readFromDs(LogicalDatastoreType.CONFIGURATION, routerIid);\r
         return optRouter;\r
     }\r
 \r
@@ -457,8 +443,8 @@ public class PortHandler implements TransactionChainListener {
             Throwable cause) {\r
         LOG.error("Transaction chain failed. {} \nTransaction which caused the chain to fail {}", cause.getMessage(),\r
                 transaction, cause);\r
-        transactionChain.close();\r
-        transactionChain = dataBroker.createTransactionChain(this);\r
+        syncedChain.closeChain();\r
+        this.syncedChain = new SyncedChain(Preconditions.checkNotNull(dataBroker.createTransactionChain(this)));\r
     }\r
 \r
     @Override\r