*/
package org.opendaylight.genius.itm.rpc;
-import static org.opendaylight.serviceutils.tools.mdsal.rpc.FutureRpcResults.LogLevel.ERROR;
-import static org.opendaylight.serviceutils.tools.mdsal.rpc.FutureRpcResults.fromListenableFuture;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.serviceutils.tools.rpc.FutureRpcResults.LogLevel.ERROR;
+import static org.opendaylight.serviceutils.tools.rpc.FutureRpcResults.fromListenableFuture;
import static org.opendaylight.yangtools.yang.common.RpcResultBuilder.failed;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfo;
+import org.opendaylight.genius.mdsalutil.MetaDataUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
-import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
+import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
-import org.opendaylight.serviceutils.tools.mdsal.rpc.FutureRpcResults;
+import org.opendaylight.serviceutils.tools.rpc.FutureRpcResults;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.get.dpn.info.output.ComputesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
private final DirectTunnelUtils directTunnelUtils;
private final ManagedNewTransactionRunner txRunner;
+ private final RetryingManagedNewTransactionRunner retryingTxRunner;
+ private final ItmConfig itmConfig;
@Inject
public ItmManagerRpcService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
this.dataBroker = dataBroker;
this.mdsalManager = mdsalManager;
this.dpnTEPsInfoCache = dpnTEPsInfoCache;
- this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(dataBroker, itmConfig, dpnTEPsInfoCache);
+ this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig, dpnTEPsInfoCache);
this.singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
this.interfaceManager = interfaceManager;
this.interfaceManagerService = interfaceManagerService;
this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
this.directTunnelUtils = directTunnelUtils;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ this.retryingTxRunner = new RetryingManagedNewTransactionRunner(dataBroker);
+ this.itmConfig = itmConfig;
}
@PostConstruct
new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput>() {
@Override
- public void onSuccess(@Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.genius
- .interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput result) {
+ public void onSuccess(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs
+ .rev160406.@NonNull GetEgressActionsForInterfaceOutput result) {
GetEgressActionsForTunnelOutputBuilder output =
new GetEgressActionsForTunnelOutputBuilder().setAction(result.getAction());
settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>success()
settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
.withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
}
- });
+ } ,MoreExecutors.directExecutor());
return settableFuture;
} else {
- return fromListenableFuture(LOG, input, () -> getEgressActionsForInterface(input.getIntfName(),
+ return fromListenableFuture(LOG, input, () -> getEgressActionsForInternalTunnels(input.getIntfName(),
input.getTunnelKey(), input.getActionKey())).onFailureLogLevel(ERROR).build();
}
}
Futures.addCallback(interfaceManagerService.getTunnelType(inputBuilder.build()),
new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
.interfacemanager.rpcs.rev160406.GetTunnelTypeOutput>() {
- public void onSuccess(@Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.genius
- .interfacemanager.rpcs.rev160406.GetTunnelTypeOutput result) {
+ @Override
+ public void onSuccess(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs
+ .rev160406.@NonNull GetTunnelTypeOutput result) {
GetTunnelTypeOutputBuilder output = new GetTunnelTypeOutputBuilder()
.setTunnelType(result.getTunnelType());
settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>success()
.withResult(output.build()).build());
}
+ @Override
public void onFailure(Throwable throwable) {
LOG.debug("RPC Call to Get tunnel type failed for interface {}", tunnelName);
String errMsg = String.format("RPC to Get tunnel type failed for interface %s",
tunnelName);
settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>failed()
.withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
+
}
- });
+ },MoreExecutors.directExecutor());
return settableFuture;
} else {
LOG.debug("get tunnel type from ITM for interface name {}", input.getIntfName());
//Ignore the Futures for now
final SettableFuture<RpcResult<RemoveExternalTunnelEndpointOutput>> result = SettableFuture.create();
Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
- ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, meshedDpnList,
- input.getDestinationIp(), input.getTunnelType());
- InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
- .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
- WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
- transaction.delete(LogicalDatastoreType.CONFIGURATION, extPath);
- ListenableFuture<Void> futureCheck = transaction.submit();
- Futures.addCallback(futureCheck, new FutureCallback<Void>() {
-
+ FluentFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> {
+ ItmExternalTunnelDeleteWorker.deleteTunnels(meshedDpnList, input.getDestinationIp(),
+ input.getTunnelType(), tx);
+ InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
+ .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
+ tx.delete(extPath);
+ }
+ );
+ future.addCallback(new FutureCallback<Void>() {
@Override public void onSuccess(Void voidInstance) {
result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>success().build());
}
result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>failed()
.withError(RpcError.ErrorType.APPLICATION, msg, error).build());
}
- });
+ }, MoreExecutors.directExecutor());
return result;
}
RemoveExternalTunnelFromDpnsInput input) {
//Ignore the Futures for now
final SettableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
- List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dpnTEPsInfoCache, input.getDpnId()) ;
- ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, cfgDpnList,
- input.getDestinationIp(), input.getTunnelType());
- result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>success().build());
+ List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dpnTEPsInfoCache, input.getDpnId());
+ FluentFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> ItmExternalTunnelDeleteWorker.deleteTunnels(cfgDpnList, input.getDestinationIp(),
+ input.getTunnelType(), tx));
+
+ future.addCallback(new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void voidInstance) {
+ result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = "Unable to remove external tunnel from DPN";
+ LOG.error("remove ext tunnel failed. {}.", msg, error);
+ result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>failed()
+ .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ }, MoreExecutors.directExecutor());
return result;
}
BuildExternalTunnelFromDpnsInput input) {
//Ignore the Futures for now
final SettableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
- List<ListenableFuture<Void>> extTunnelResultList = externalTunnelAddWorker
- .buildTunnelsFromDpnToExternalEndPoint(input.getDpnId(), input.getDestinationIp(),input.getTunnelType());
- for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
- Futures.addCallback(extTunnelResult, new FutureCallback<Void>() {
-
- @Override
- public void onSuccess(Void voidInstance) {
- result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>success().build());
- }
+ FluentFuture<Void> extTunnelResultList =
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> externalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(input.getDpnId(),
+ input.getDestinationIp(),input.getTunnelType(), tx));
- @Override
- public void onFailure(Throwable error) {
- String msg = "Unable to create ext tunnel";
- LOG.error("create ext tunnel failed. {}.", msg, error);
- result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>failed()
- .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
- }
- });
- }
+ extTunnelResultList.addCallback(new FutureCallback<Void>() {
+
+ @Override
+ public void onSuccess(Void voidInstance) {
+ result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = "Unable to create ext tunnel";
+ LOG.error("create ext tunnel failed. {}.", msg, error);
+ result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>failed()
+ .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ }, MoreExecutors.directExecutor());
return result;
}
//Ignore the Futures for now
final SettableFuture<RpcResult<AddExternalTunnelEndpointOutput>> result = SettableFuture.create();
Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
- externalTunnelAddWorker.buildTunnelsToExternalEndPoint(meshedDpnList,
- input.getDestinationIp(), input.getTunnelType());
InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
.child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
DcGatewayIp dcGatewayIp =
new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp())
.setTunnnelType(input.getTunnelType()).build();
- WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
- writeTransaction.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
- ListenableFuture<Void> futureCheck = writeTransaction.submit();
- Futures.addCallback(futureCheck, new FutureCallback<Void>() {
+ FluentFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> {
+ externalTunnelAddWorker.buildTunnelsToExternalEndPoint(meshedDpnList, input.getDestinationIp(),
+ input.getTunnelType(), tx);
+ tx.put(extPath, dcGatewayIp, true);
+ }
+ );
+ future.addCallback(new FutureCallback<Void>() {
@Override public void onSuccess(Void voidInstance) {
result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>success().build());
}
result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>failed()
.withError(RpcError.ErrorType.APPLICATION, msg, error).build());
}
- });
+ }, MoreExecutors.directExecutor());
return result;
}
String.format("%s:%d","ITM Flow Entry ",serviceId), 0, 0,
ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
- ListenableFuture<Void> installFlowResult =
- mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
+ ListenableFuture<Void> installFlowResult = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> mdsalManager.addFlow(tx, input.getDpnId(), terminatingServiceTableFlow));
Futures.addCallback(installFlowResult, new FutureCallback<Void>() {
@Override
LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}",
input.getDpnId(), input.getServiceId());
final SettableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>> result = SettableFuture.create();
- Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
- getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5,
- String.format("%s:%d","ITM Flow Entry ",input.getServiceId()), 0, 0,
- ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),
- getTunnelMatchesForServiceId(input.getServiceId()), null);
- ListenableFuture<Void> installFlowResult =
- mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
- Futures.addCallback(installFlowResult, new FutureCallback<Void>() {
+ ListenableFuture<Void> removeFlowResult = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ tx -> mdsalManager.removeFlow(tx, input.getDpnId(),
+ getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, input.getServiceId()),
+ NwConstants.INTERNAL_TUNNEL_TABLE));
+ Futures.addCallback(removeFlowResult, new FutureCallback<Void>() {
@Override
public void onSuccess(Void voidInstance) {
IpAddress dstIp = input.getDestinationIp() ;
InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
.child(ExternalTunnel.class,
- new ExternalTunnelKey(String.valueOf(dstIp.getValue()),
- srcDpn.toString(), input.getTunnelType()));
+ new ExternalTunnelKey(dstIp.stringValue(), srcDpn.toString(), input.getTunnelType()));
Optional<ExternalTunnel> optExtTunnel = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
return result;
}
for (TransportZone tzone : transportZones.getTransportZone()) {
- if (!tzone.getTunnelType().equals(TunnelTypeVxlan.class)) {
+ if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
continue;
}
foundVxlanTzone = true;
.child(TransportZone.class, new TransportZoneKey(transportZone))
.child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
.build();
- WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
- //TO DO: add retry if it fails
-
- transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
-
- ListenableFuture<Void> futureCheck = transaction.submit();
- Futures.addCallback(futureCheck, new FutureCallback<Void>() {
-
+ FluentFuture<Void> future =
+ retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(path));
+ future.addCallback(new FutureCallback<Void>() {
@Override public void onSuccess(Void voidInstance) {
result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>success().build());
}
result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
.withError(RpcError.ErrorType.APPLICATION, msg, error).build());
}
- });
-
+ }, MoreExecutors.directExecutor());
}
} else {
result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
return result;
}
for (TransportZone tzone : transportZones.getTransportZone()) {
- if (!tzone.getTunnelType().equals(TunnelTypeVxlan.class)) {
+ if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
continue;
}
String transportZone = tzone.getZoneName();
.build();
DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey).setIpAddress(hwIp)
.setNodeId(nodeId).setTopologyId(input.getTopologyId()).build();
- WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
//TO DO: add retry if it fails
- transaction.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
+ FluentFuture<Void> future = retryingTxRunner
+ .callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.put(path, deviceVtep, true));
- ListenableFuture<Void> futureCheck = transaction.submit();
- Futures.addCallback(futureCheck, new FutureCallback<Void>() {
+ future.addCallback(new FutureCallback<Void>() {
@Override public void onSuccess(Void voidInstance) {
result.set(RpcResultBuilder.<AddL2GwDeviceOutput>success().build());
result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
.withError(RpcError.ErrorType.APPLICATION, msg, error).build());
}
- });
+ }, MoreExecutors.directExecutor());
}
} else {
.child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey).setIpAddress(hwIp)
.setNodeId(nodeId.get(0)).setTopologyId(input.getTopologyId()).build();
- WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
- //TO DO: add retry if it fails
- LOG.trace("writing hWvtep{}",deviceVtep);
- writeTransaction.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
-
- if (nodeId.size() == 2) {
- LOG.trace("second node-id {}",nodeId.get(1));
- DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
- InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
- .child(TransportZone.class, new TransportZoneKey(transportZone))
- .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
- DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().withKey(deviceVtepKey2).setIpAddress(hwIp)
- .setNodeId(nodeId.get(1))
- .setTopologyId(input.getTopologyId()).build();
- //TO DO: add retry if it fails
- LOG.trace("writing {}",deviceVtep2);
- writeTransaction.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
- }
- ListenableFuture<Void> futureCheck = writeTransaction.submit();
- Futures.addCallback(futureCheck, new FutureCallback<Void>() {
-
+ LOG.trace("writing hWvtep{}", deviceVtep);
+ FluentFuture<Void> future =
+ retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> {
+ tx.put(path, deviceVtep, true);
+ if (nodeId.size() == 2) {
+ LOG.trace("second node-id {}", nodeId.get(1));
+ DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
+ InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
+ .child(TransportZone.class, new TransportZoneKey(transportZone))
+ .child(Subnets.class, subnetsKey)
+ .child(DeviceVteps.class, deviceVtepKey2).build();
+ DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().withKey(deviceVtepKey2)
+ .setIpAddress(hwIp).setNodeId(nodeId.get(1))
+ .setTopologyId(input.getTopologyId()).build();
+ LOG.trace("writing {}", deviceVtep2);
+ tx.put(path2, deviceVtep2, true);
+ }
+ });
+ future.addCallback(new FutureCallback<Void>() {
@Override
public void onSuccess(Void voidInstance) {
result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>success().build());
return result;
}
SubnetsKey subnetsKey = tzones.getTransportZone().get(0).getSubnets().get(0).key();
- DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
- InstanceIdentifier<DeviceVteps> path =
- InstanceIdentifier.builder(TransportZones.class)
- .child(TransportZone.class, new TransportZoneKey(transportZone))
- .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
- deviceVtepKey).build();
- WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
- //TO DO: add retry if it fails
- transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
-
- DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
- InstanceIdentifier<DeviceVteps> path2 =
- InstanceIdentifier.builder(TransportZones.class)
- .child(TransportZone.class, new TransportZoneKey(transportZone))
- .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
- deviceVtepKey2).build();
- //TO DO: add retry if it fails
- transaction.delete(LogicalDatastoreType.CONFIGURATION, path2);
- ListenableFuture<Void> futureCheck = transaction.submit();
- Futures.addCallback(futureCheck, new FutureCallback<Void>() {
+ FluentFuture<Void> future =
+ retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> {
+ DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
+ InstanceIdentifier<DeviceVteps> path =
+ InstanceIdentifier.builder(TransportZones.class)
+ .child(TransportZone.class, new TransportZoneKey(transportZone))
+ .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
+ deviceVtepKey).build();
+ tx.delete(path);
+ DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
+ InstanceIdentifier<DeviceVteps> path2 =
+ InstanceIdentifier.builder(TransportZones.class)
+ .child(TransportZone.class, new TransportZoneKey(transportZone))
+ .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
+ deviceVtepKey2).build();
+ tx.delete(path2);
+ }
+ );
+
+ future.addCallback(new FutureCallback<Void>() {
@Override
public void onSuccess(Void voidInstance) {
.withError(RpcError.ErrorType.APPLICATION, msg, error)
.build());
}
- });
+ }, MoreExecutors.directExecutor());
}
return result;
} catch (Exception e) {
public ListenableFuture<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
- List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
+ List<DcGatewayIp> dcGatewayIpList = new ArrayList<>();
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ tx -> dcGatewayIpList.addAll(getDcGatewayIpList(tx))).isDone();
+
String dcgwIpStr = input.getDcgwIp();
IpAddress dcgwIpAddr = IpAddressBuilder.getDefaultInstance(dcgwIpStr);
long retVal;
- if (dcGatewayIpList != null && !dcGatewayIpList.isEmpty()
+ if (!dcGatewayIpList.isEmpty()
&& dcGatewayIpList.stream().anyMatch(gwIp -> Objects.equal(gwIp.getIpAddress(), dcgwIpAddr))) {
//Match found
retVal = 1;
.network.topology.topology.Node.class).getNodeId().getValue();
}
- private ListenableFuture<GetEgressActionsForTunnelOutput> getEgressActionsForInterface(String interfaceName,
- Long tunnelKey, Integer actionKey) throws ReadFailedException {
- int actionKeyStart = actionKey == null ? 0 : actionKey;
+ private ListenableFuture<GetEgressActionsForTunnelOutput>
+ getEgressActionsForInternalTunnels(String interfaceName, Long tunnelKey, Integer actionKey)
+ throws ExecutionException, InterruptedException, OperationFailedException {
+
DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
if (interfaceInfo == null) {
throw new IllegalStateException("Interface information not present in config DS for" + interfaceName);
}
- Optional<StateTunnelList> ifState = tunnelStateCache
- .get(tunnelStateCache.getStateTunnelListIdentifier(interfaceName));
- if (ifState.isPresent()) {
- String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType());
- List<Action> actions = getEgressActionInfosForInterface(tunnelType, ifState.get().getPortNumber(),
- tunnelKey, actionKeyStart).stream().map(ActionInfo::buildAction).collect(Collectors.toList());
- return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder().setAction(actions).build());
+
+ String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType());
+ if (!tunnelType.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_VXLAN)) {
+ throw new IllegalArgumentException(tunnelType + " tunnel not handled by ITM");
+ }
+
+ Optional<DPNTEPsInfo> dpntePsInfoOptional = dpnTEPsInfoCache.get(InstanceIdentifier.builder(DpnEndpoints.class)
+ .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(new BigInteger(dpnTepStateCache
+ .getTunnelEndPointInfoFromCache(interfaceInfo.getTunnelName()).getDstEndPointInfo()))).build());
+ Integer dstId;
+ if (dpntePsInfoOptional.isPresent()) {
+ dstId = dpntePsInfoOptional.get().getDstId();
+ } else {
+ dstId = directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME, interfaceInfo.getRemoteDPN().toString());
}
- throw new IllegalStateException("Interface information not present in oper DS for" + interfaceName);
- }
- private static List<ActionInfo> getEgressActionInfosForInterface(String tunnelType, String portNo, Long tunnelKey,
- int actionKeyStart) {
List<ActionInfo> result = new ArrayList<>();
- switch (tunnelType) {
- case ITMConstants.TUNNEL_TYPE_GRE:
- case ITMConstants.TUNNEL_TYPE_MPLSoGRE:
- // Invoke IFM RPC and pass it on to the caller.
- LOG.warn("Interface Type {} not handled by ITM", tunnelType);
- break;
- case ITMConstants.TUNNEL_TYPE_VXLAN:
- //TODO tunnel_id to encode GRE key, once it is supported
- // Until then, tunnel_id should be "cleaned", otherwise it stores the value coming from a VXLAN tunnel
- result.add(new ActionSetFieldTunnelId(actionKeyStart++,
- BigInteger.valueOf(tunnelKey != null ? tunnelKey : 0L)));
- result.add(new ActionOutput(actionKeyStart, new Uri(portNo)));
- break;
-
- default:
- LOG.warn("Interface Type {} not handled yet", tunnelType);
- break;
- }
- return result;
+ long regValue = MetaDataUtil.getRemoteDpnMetadatForEgressTunnelTable(dstId);
+ int actionKeyStart = actionKey == null ? 0 : actionKey;
+ result.add(new ActionSetFieldTunnelId(actionKeyStart++,
+ BigInteger.valueOf(tunnelKey != null ? tunnelKey : 0L)));
+ result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, MetaDataUtil.REG6_START_INDEX,
+ MetaDataUtil.REG6_END_INDEX, regValue));
+ result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_TUNNEL_TABLE));
+
+ return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
+ .setAction(result.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
+ }
+
+ public static List<DcGatewayIp> getDcGatewayIpList(TypedReadWriteTransaction<Datastore.Configuration> tx)
+ throws ExecutionException, InterruptedException {
+ List<DcGatewayIp> dcGatewayIpList = new ArrayList<>();
+ FluentFuture<Optional<DcGatewayIpList>> future =
+ tx.read(InstanceIdentifier.builder(DcGatewayIpList.class).build());
+ future.addCallback(new FutureCallback<Optional<DcGatewayIpList>>() {
+ @Override
+ public void onSuccess(@NonNull Optional<DcGatewayIpList> optional) {
+ try {
+ Optional<DcGatewayIpList> opt = future.get();
+ if (opt.isPresent()) {
+ DcGatewayIpList list = opt.get();
+ if (list != null) {
+ dcGatewayIpList.addAll(list.getDcGatewayIp());
+ }
+ }
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("DcGateway IpList read failed", e);
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ LOG.error("DcGateway IpList read failed", error);
+ }
+ }, MoreExecutors.directExecutor());
+ return dcGatewayIpList;
}
}