use of com.google.common.util.concurrent.FutureCallback in project cdap by caskdata.
the class ResourceCoordinator method fetchAndProcessAllResources.
/**
* Fetches all {@link ResourceRequirement} and perform assignment for the one that changed. Also, it will
* remove assignments for the resource requirements that are removed.
*/
private void fetchAndProcessAllResources(final Watcher watcher) {
Futures.addCallback(zkClient.getChildren(CoordinationConstants.REQUIREMENTS_PATH, watcher), wrapCallback(new FutureCallback<NodeChildren>() {
@Override
public void onSuccess(NodeChildren result) {
Set<String> children = ImmutableSet.copyOf(result.getChildren());
// Handle new resources
for (String child : children) {
String path = CoordinationConstants.REQUIREMENTS_PATH + "/" + child;
Watcher requirementWatcher = wrapWatcher(new ResourceRequirementWatcher(path));
fetchAndProcessRequirement(path, requirementWatcher);
}
// Handle removed resources
for (String removed : ImmutableSet.copyOf(Sets.difference(requirements.keySet(), children))) {
ResourceRequirement requirement = requirements.remove(removed);
LOG.info("Requirement deleted {}", requirement);
// Delete the assignment node.
removeAssignment(removed);
}
}
@Override
public void onFailure(Throwable t) {
// If the resource path node doesn't exists, resort to watch for exists.
if (t instanceof KeeperException.NoNodeException) {
beginWatch(watcher);
}
// Otherwise, it's a unexpected failure.
LOG.error("Failed to getChildren on ZK node {}{}", zkClient.getConnectString(), CoordinationConstants.REQUIREMENTS_PATH, t);
doNotifyFailed(t);
}
}), executor);
}
use of com.google.common.util.concurrent.FutureCallback in project netvirt by opendaylight.
the class NaptEventHandler method handleEvent.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void handleEvent(final NAPTEntryEvent naptEntryEvent) {
/*
Flow programming logic of the OUTBOUND NAPT TABLE :
1) Get the internal IP address, port number, router ID from the event.
2) Use the NAPT service getExternalAddressMapping() to get the External IP and the port.
3) Build the flow for replacing the Internal IP and port with the External IP and port.
a) Write the matching criteria.
b) Match the router ID in the metadata.
d) Write the VPN ID to the metadata.
e) Write the other data.
f) Set the apply actions instruction with the action setfield.
4) Write the flow to the OUTBOUND NAPT Table and forward to FIB table for routing the traffic.
Flow programming logic of the INBOUND NAPT TABLE :
Same as Outbound table logic except that :
1) Build the flow for replacing the External IP and port with the Internal IP and port.
2) Match the VPN ID in the metadata.
3) Write the router ID to the metadata.
5) Write the flow to the INBOUND NAPT Table and forward to FIB table for routing the traffic.
*/
try {
Long routerId = naptEntryEvent.getRouterId();
LOG.trace("handleEvent : Time Elapsed before procesing snat ({}:{}) packet is {} ms," + "routerId: {},isPktProcessed:{}", naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), System.currentTimeMillis() - naptEntryEvent.getObjectCreationTime(), routerId, naptEntryEvent.isPktProcessed());
// Get the DPN ID
BigInteger dpnId = NatUtil.getPrimaryNaptfromRouterId(dataBroker, routerId);
long bgpVpnId = NatConstants.INVALID_ID;
if (dpnId == null) {
LOG.warn("handleEvent : dpnId is null. Assuming the router ID {} as the BGP VPN ID and proceeding....", routerId);
bgpVpnId = routerId;
LOG.debug("handleEvent : BGP VPN ID {}", bgpVpnId);
String vpnName = NatUtil.getRouterName(dataBroker, bgpVpnId);
String routerName = NatUtil.getRouterIdfromVpnInstance(dataBroker, vpnName);
if (routerName == null) {
LOG.error("handleEvent : Unable to find router for VpnName {}", vpnName);
return;
}
routerId = NatUtil.getVpnId(dataBroker, routerName);
LOG.debug("handleEvent : Router ID {}", routerId);
dpnId = NatUtil.getPrimaryNaptfromRouterId(dataBroker, routerId);
if (dpnId == null) {
LOG.error("handleEvent : dpnId is null for the router {}", routerId);
return;
}
}
if (naptEntryEvent.getOperation() == NAPTEntryEvent.Operation.ADD) {
LOG.debug("handleEvent : Inside Add operation of NaptEventHandler");
// Build and install the NAPT translation flows in the Outbound and Inbound NAPT tables
if (!naptEntryEvent.isPktProcessed()) {
// Get the External Gateway MAC Address
String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterId(dataBroker, routerId);
if (extGwMacAddress != null) {
LOG.debug("handleEvent : External Gateway MAC address {} found for External Router ID {}", extGwMacAddress, routerId);
} else {
LOG.error("handleEvent : No External Gateway MAC address found for External Router ID {}", routerId);
return;
}
// Get the external network ID from the ExternalRouter model
Uuid networkId = NatUtil.getNetworkIdFromRouterId(dataBroker, routerId);
if (networkId == null) {
LOG.error("handleEvent : networkId is null");
return;
}
// Get the VPN ID from the ExternalNetworks model
Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
if (vpnUuid == null) {
LOG.error("handleEvent : vpnUuid is null");
return;
}
Long vpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
// Get the internal IpAddress, internal port number from the event
String internalIpAddress = naptEntryEvent.getIpAddress();
int internalPort = naptEntryEvent.getPortNumber();
SessionAddress internalAddress = new SessionAddress(internalIpAddress, internalPort);
NAPTEntryEvent.Protocol protocol = naptEntryEvent.getProtocol();
// Get the external IP address for the corresponding internal IP address
SessionAddress externalAddress = naptManager.getExternalAddressMapping(routerId, internalAddress, naptEntryEvent.getProtocol());
if (externalAddress == null) {
LOG.error("handleEvent : externalAddress is null");
return;
}
Long vpnIdFromExternalSubnet = getVpnIdFromExternalSubnet(routerId, externalAddress.getIpAddress());
if (vpnIdFromExternalSubnet != NatConstants.INVALID_ID) {
vpnId = vpnIdFromExternalSubnet;
}
// Added External Gateway MAC Address
Future<RpcResult<AddFlowOutput>> addFlowResult = buildAndInstallNatFlowsOptionalRpc(dpnId, NwConstants.INBOUND_NAPT_TABLE, vpnId, routerId, bgpVpnId, externalAddress, internalAddress, protocol, extGwMacAddress, true);
final BigInteger finalDpnId = dpnId;
final Long finalVpnId = vpnId;
final Long finalRouterId = routerId;
final long finalBgpVpnId = bgpVpnId;
Futures.addCallback(JdkFutureAdapters.listenInPoolThread(addFlowResult), new FutureCallback<RpcResult<AddFlowOutput>>() {
@Override
public void onSuccess(@Nullable RpcResult<AddFlowOutput> result) {
LOG.debug("handleEvent : Configured inbound rule for {} to {}", internalAddress, externalAddress);
Future<RpcResult<AddFlowOutput>> addFlowResult = buildAndInstallNatFlowsOptionalRpc(finalDpnId, NwConstants.OUTBOUND_NAPT_TABLE, finalVpnId, finalRouterId, finalBgpVpnId, internalAddress, externalAddress, protocol, extGwMacAddress, true);
Futures.addCallback(JdkFutureAdapters.listenInPoolThread(addFlowResult), new FutureCallback<RpcResult<AddFlowOutput>>() {
@Override
public void onSuccess(@Nullable RpcResult<AddFlowOutput> result) {
LOG.debug("handleEvent : Configured outbound rule, sending packet out" + "from {} to {}", internalAddress, externalAddress);
prepareAndSendPacketOut(naptEntryEvent, finalRouterId);
}
@Override
public void onFailure(@Nonnull Throwable throwable) {
LOG.error("handleEvent : Error configuring outbound " + "SNAT flows using RPC for SNAT connection from {} to {}", internalAddress, externalAddress);
}
}, MoreExecutors.directExecutor());
}
@Override
public void onFailure(@Nonnull Throwable throwable) {
LOG.error("handleEvent : Error configuring inbound SNAT flows " + "using RPC for SNAT connection from {} to {}", internalAddress, externalAddress);
}
}, MoreExecutors.directExecutor());
NatPacketProcessingState state = naptEntryEvent.getState();
if (state != null) {
state.setFlowInstalledTime(System.currentTimeMillis());
}
} else {
prepareAndSendPacketOut(naptEntryEvent, routerId);
}
LOG.trace("handleEvent : Time elapsed after Processsing snat ({}:{}) packet: {}ms,isPktProcessed:{} ", naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), System.currentTimeMillis() - naptEntryEvent.getObjectCreationTime(), naptEntryEvent.isPktProcessed());
} else {
LOG.debug("handleEvent : Inside delete Operation of NaptEventHandler");
removeNatFlows(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId, naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber());
LOG.info("handleEvent : exited for removeEvent for IP {}, port {}, routerID : {}", naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), routerId);
}
} catch (Exception e) {
LOG.error("handleEvent :Exception in NaptEventHandler.handleEvent() payload {}", naptEntryEvent, e);
}
}
use of com.google.common.util.concurrent.FutureCallback in project netvirt by opendaylight.
the class ExternalRoutersListener method delFibTsAndReverseTraffic.
protected void delFibTsAndReverseTraffic(final BigInteger dpnId, long routerId, String extIp, final String vpnName, Uuid extNetworkId, long tempLabel, String gwMacAddress, boolean switchOver, WriteTransaction removeFlowInvTx) {
LOG.debug("delFibTsAndReverseTraffic : Removing fib entry for externalIp {} in routerId {}", extIp, routerId);
String routerName = NatUtil.getRouterName(dataBroker, routerId);
if (routerName == null) {
LOG.error("delFibTsAndReverseTraffic : Could not retrieve Router Name from Router ID {} ", routerId);
return;
}
ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, extNetworkId);
if (extNwProvType == null) {
LOG.error("delFibTsAndReverseTraffic : External Network Provider Type Missing");
return;
}
/* Remove the flow table19->44 and table36->44 entries for SNAT reverse traffic flow if the
* external network provided type is VxLAN
*/
if (extNwProvType == ProviderTypes.VXLAN) {
evpnSnatFlowProgrammer.evpnDelFibTsAndReverseTraffic(dpnId, routerId, extIp, vpnName, gwMacAddress, removeFlowInvTx);
return;
}
if (tempLabel < 0) {
LOG.error("delFibTsAndReverseTraffic : Label not found for externalIp {} with router id {}", extIp, routerId);
return;
}
final long label = tempLabel;
final String externalIp = NatUtil.validateAndAddNetworkMask(extIp);
RemoveFibEntryInput input = new RemoveFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setIpAddress(externalIp).setServiceId(label).setIpAddressSource(RemoveFibEntryInput.IpAddressSource.ExternalFixedIP).build();
Future<RpcResult<Void>> future = fibService.removeFibEntry(input);
removeTunnelTableEntry(dpnId, label, removeFlowInvTx);
removeLFibTableEntry(dpnId, label, removeFlowInvTx);
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
// Remove the flow table 25->44 If there is no FIP Match on table 25 (PDNAT_TABLE)
NatUtil.removePreDnatToSnatTableEntry(mdsalManager, dpnId, removeFlowInvTx);
}
if (!switchOver) {
ListenableFuture<RpcResult<Void>> labelFuture = Futures.transformAsync(JdkFutureAdapters.listenInPoolThread(future), (AsyncFunction<RpcResult<Void>, RpcResult<Void>>) result -> {
if (result.isSuccessful()) {
NatUtil.removePreDnatToSnatTableEntry(mdsalManager, dpnId, removeFlowInvTx);
RemoveVpnLabelInput labelInput = new RemoveVpnLabelInputBuilder().setVpnName(vpnName).setIpPrefix(externalIp).build();
Future<RpcResult<Void>> labelFuture1 = vpnService.removeVpnLabel(labelInput);
return JdkFutureAdapters.listenInPoolThread(labelFuture1);
} else {
String errMsg = String.format("RPC call to remove custom FIB entries on dpn %s for " + "prefix %s Failed - %s", dpnId, externalIp, result.getErrors());
LOG.error(errMsg);
return Futures.immediateFailedFuture(new RuntimeException(errMsg));
}
});
Futures.addCallback(labelFuture, new FutureCallback<RpcResult<Void>>() {
@Override
public void onFailure(@Nonnull Throwable error) {
LOG.error("delFibTsAndReverseTraffic : Error in removing the label:{} or custom fib entries" + "got external ip {}", label, extIp, error);
}
@Override
public void onSuccess(@Nonnull RpcResult<Void> result) {
if (result.isSuccessful()) {
LOG.debug("delFibTsAndReverseTraffic : Successfully removed the label for the prefix {} " + "from VPN {}", externalIp, vpnName);
} else {
LOG.error("delFibTsAndReverseTraffic : Error in removing the label for prefix {} " + " from VPN {}, {}", externalIp, vpnName, result.getErrors());
}
}
}, MoreExecutors.directExecutor());
} else {
LOG.debug("delFibTsAndReverseTraffic: switch-over is happened on DpnId {}. No need to release allocated " + "label {} for external fixed ip {} for router {}", dpnId, label, externalIp, routerId);
}
}
use of com.google.common.util.concurrent.FutureCallback in project netvirt by opendaylight.
the class VpnFloatingIpHandler method cleanupFibEntries.
@Override
public void cleanupFibEntries(final BigInteger dpnId, final String vpnName, final String externalIp, final long label, WriteTransaction removeFlowInvTx, ProviderTypes provType) {
// Remove Prefix from BGP
String rd = NatUtil.getVpnRd(dataBroker, vpnName);
String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
NatUtil.removePrefixFromBGP(bgpManager, fibManager, rd, fibExternalIp, vpnName, LOG);
// Remove custom FIB routes
// Future<RpcResult<java.lang.Void>> removeFibEntry(RemoveFibEntryInput input);
RemoveFibEntryInput input = new RemoveFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setIpAddress(fibExternalIp).setServiceId(label).setIpAddressSource(RemoveFibEntryInput.IpAddressSource.FloatingIP).build();
Future<RpcResult<Void>> future = fibService.removeFibEntry(input);
ListenableFuture<RpcResult<Void>> labelFuture = Futures.transformAsync(JdkFutureAdapters.listenInPoolThread(future), (AsyncFunction<RpcResult<Void>, RpcResult<Void>>) result -> {
if (result.isSuccessful()) {
Boolean removeTunnelFlow = Boolean.TRUE;
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
if (NatUtil.isFloatingIpPresentForDpn(dataBroker, dpnId, rd, vpnName, externalIp, false)) {
removeTunnelFlow = Boolean.FALSE;
}
}
if (removeTunnelFlow) {
removeTunnelTableEntry(dpnId, label, removeFlowInvTx);
}
removeLFibTableEntry(dpnId, label, removeFlowInvTx);
RemoveVpnLabelInput labelInput = new RemoveVpnLabelInputBuilder().setVpnName(vpnName).setIpPrefix(externalIp).build();
Future<RpcResult<Void>> labelFuture1 = vpnService.removeVpnLabel(labelInput);
return JdkFutureAdapters.listenInPoolThread(labelFuture1);
} else {
String errMsg = String.format("onRemoveFloatingIp :RPC call to remove custom FIB entries " + "on dpn %s for prefix %s Failed - %s", dpnId, externalIp, result.getErrors());
LOG.error(errMsg);
return Futures.immediateFailedFuture(new RuntimeException(errMsg));
}
}, MoreExecutors.directExecutor());
Futures.addCallback(labelFuture, new FutureCallback<RpcResult<Void>>() {
@Override
public void onFailure(@Nonnull Throwable error) {
LOG.error("onRemoveFloatingIp : Error in removing the label or custom fib entries", error);
}
@Override
public void onSuccess(@Nonnull RpcResult<Void> result) {
if (result.isSuccessful()) {
LOG.debug("onRemoveFloatingIp : Successfully removed the label for the prefix {} from VPN {}", externalIp, vpnName);
} else {
LOG.error("onRemoveFloatingIp : Error in removing the label for prefix {} from VPN {}, {}", externalIp, vpnName, result.getErrors());
}
}
}, MoreExecutors.directExecutor());
}
use of com.google.common.util.concurrent.FutureCallback in project netvirt by opendaylight.
the class VrfEntryListener method populateFibOnNewDpn.
public void populateFibOnNewDpn(final BigInteger dpnId, final long vpnId, final String rd, final FutureCallback<List<Void>> callback) {
LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd);
InstanceIdentifier<VrfTables> id = buildVrfId(rd);
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
List<SubTransaction> txnObjects = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.info("populateFibOnNewDpn: dpn: {}: VRF Table not yet available for RD {}", dpnId, rd);
if (callback != null) {
List<ListenableFuture<Void>> futures = new ArrayList<>();
ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return;
}
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
List<ListenableFuture<Void>> futures = new ArrayList<>();
synchronized (vpnInstance.getVpnInstanceName().intern()) {
futures.add(retryingTxRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
for (final VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
SubnetRoute subnetRoute = vrfEntry.getAugmentation(SubnetRoute.class);
if (subnetRoute != null) {
long elanTag = subnetRoute.getElantag();
installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, tx);
installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry, NwConstants.ADD_FLOW, tx);
continue;
}
RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
if (routerInt != null) {
LOG.trace("Router augmented vrfentry found rd:{}, uuid:{}, ip:{}, mac:{}", rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId, routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()), NwConstants.ADD_FLOW);
continue;
}
// Handle local flow creation for imports
if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
java.util.Optional<Long> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
if (optionalLabel.isPresent()) {
List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri)) {
if (lri.getDpnId().equals(dpnId)) {
createLocalFibEntry(vpnId, rd, vrfEntry);
continue;
}
}
}
}
boolean shouldCreateRemoteFibEntry = shouldCreateFibEntryForVrfAndVpnIdOnDpn(vpnId, vrfEntry, dpnId);
if (shouldCreateRemoteFibEntry) {
LOG.trace("Will create remote FIB entry for vrfEntry {} on DPN {}", vrfEntry, dpnId);
if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
bgpRouteVrfEntryHandler.createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(), vrfEntry, tx, txnObjects);
} else {
createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(), vrfEntry, tx);
}
}
}
}));
if (callback != null) {
ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
}
return futures;
});
}
Aggregations