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
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
\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
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
}\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
}\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
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
\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
}\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
}\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
\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
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
}\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
*/\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
// 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
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