use of com.google.common.util.concurrent.Futures in project android_packages_apps_Dialer by LineageOS.
the class DialerFutureSerializer method submitAsync.
/**
* Enqueues a task to run when the previous task (if any) completes.
*
* <p>Cancellation does not propagate from the output future to the future returned from {@code
* callable}, but if the output future is cancelled before {@link AsyncCallable#call()} is
* invoked, {@link AsyncCallable#call()} will not be invoked.
*/
public <T> ListenableFuture<T> submitAsync(final AsyncCallable<T> callable, Executor executor) {
AtomicBoolean wasCancelled = new AtomicBoolean(false);
final AsyncCallable<T> task = () -> {
if (wasCancelled.get()) {
return immediateCancelledFuture();
}
return callable.call();
};
/*
* Three futures are at play here:
* taskFuture is the future that comes from the callable.
* newFuture is the future we use to track the serialization of our task.
* oldFuture is the previous task's newFuture.
*
* newFuture is guaranteed to only complete once all tasks previously submitted to this instance
* once the futures returned from those submissions have completed.
*/
final SettableFuture<Object> newFuture = SettableFuture.create();
final ListenableFuture<?> oldFuture = ref.getAndSet(newFuture);
// Invoke our task once the previous future completes.
final ListenableFuture<T> taskFuture = Futures.nonCancellationPropagating(Futures.submitAsync(task, runnable -> oldFuture.addListener(runnable, executor)));
// newFuture's lifetime is determined by taskFuture, unless taskFuture is cancelled, in which
// case it falls back to oldFuture's. This is to ensure that if the future we return is
// cancelled, we don't begin execution of the next task until after oldFuture completes.
taskFuture.addListener(() -> {
if (taskFuture.isCancelled()) {
// Since the value of oldFuture can only ever be immediateFuture(null) or setFuture of a
// future that eventually came from immediateFuture(null), this doesn't leak throwables
// or completion values.
wasCancelled.set(true);
newFuture.setFuture(oldFuture);
} else {
newFuture.set(null);
}
}, directExecutor());
return taskFuture;
}
use of com.google.common.util.concurrent.Futures in project netvirt by opendaylight.
the class VrfEntryListener method cleanUpDpnForVpn.
public void cleanUpDpnForVpn(final Uint64 dpnId, final Uint32 vpnId, final String rd, final FutureCallback<List<?>> callback) {
LOG.trace("cleanUpDpnForVpn: Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
InstanceIdentifier<VrfTables> id = buildVrfId(rd);
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
List<SubTransaction> txnObjects = new ArrayList<>();
final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
List<ListenableFuture<?>> futures = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.error("cleanUpDpnForVpn: VRF Table not available for RD {}", rd);
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
}
final ReentrantLock lock = lockFor(vpnInstance);
lock.lock();
try {
futures.add(retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId());
for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry().values()) {
/* parentRd is only filled for external PNF cases where the interface on the external
* network VPN are used to cleanup the flows. For all other cases, use "rd" for
* #fibUtil.isInterfacePresentInDpn().
* */
String parentRd = vrfEntry.getParentVpnRd() != null ? vrfEntry.getParentVpnRd() : rd;
/* Handle subnet routes here */
SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
if (subnetRoute != null && !fibUtil.isInterfacePresentInDpn(parentRd, dpnId)) {
LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Cleaning subnetroute {} on dpn {}" + " for vpn {}", vrfEntry.getDestPrefix(), dpnId, rd);
baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW, TransactionAdapter.toWriteTransaction(tx), null);
Map<RoutePathsKey, RoutePaths> keyRoutePathsMap = vrfEntry.getRoutePaths();
if (keyRoutePathsMap != null) {
for (RoutePaths routePath : keyRoutePathsMap.values()) {
makeLFibTableEntry(dpnId, routePath.getLabel(), null, DEFAULT_FIB_FLOW_PRIORITY, NwConstants.DEL_FLOW, tx);
LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Released subnetroute label {}" + " for rd {} prefix {}", routePath.getLabel(), rd, vrfEntry.getDestPrefix());
}
}
installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry, NwConstants.DEL_FLOW, tx);
continue;
}
// ping responder for router interfaces
RouterInterface routerInt = vrfEntry.augmentation(RouterInterface.class);
if (routerInt != null) {
LOG.trace("Router augmented vrfentry found for rd:{}, uuid:{}, ip:{}, mac:{}", rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId, routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()), NwConstants.DEL_FLOW);
continue;
}
// Handle local flow deletion for imports
if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
java.util.Optional<Uint32> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
if (optionalLabel.isPresent()) {
List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri) && Objects.equals(lri.getDpnId(), dpnId)) {
deleteLocalFibEntry(vpnId, rd, vrfEntry);
}
}
}
// Passing null as we don't know the dpn
// to which prefix is attached at this point
List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnInstance.getVpnId(), vrfEntry.getDestPrefix());
Optional<Routes> extraRouteOptional;
// an adjacency in the vpn
if (usedRds != null && !usedRds.isEmpty()) {
if (usedRds.size() > 1) {
LOG.error("The extra route prefix is still present in some DPNs");
return;
} else {
extraRouteOptional = VpnExtraRouteHelper.getVpnExtraroutes(dataBroker, vpnName, usedRds.get(0), vrfEntry.getDestPrefix());
}
} else {
extraRouteOptional = Optional.empty();
}
if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
bgpRouteVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().key(), vrfEntry, extraRouteOptional, TransactionAdapter.toWriteTransaction(tx), txnObjects);
} else {
if (subnetRoute == null || !fibUtil.isInterfacePresentInDpn(parentRd, dpnId)) {
baseVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().key(), vrfEntry, extraRouteOptional, TransactionAdapter.toWriteTransaction(tx));
}
}
}
}));
} finally {
lock.unlock();
}
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
});
}
use of com.google.common.util.concurrent.Futures in project netvirt by opendaylight.
the class VrfEntryListener method populateFibOnNewDpn.
public void populateFibOnNewDpn(final Uint64 dpnId, final Uint32 vpnId, final String rd, final FutureCallback<List<?>> callback) {
LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
InstanceIdentifier<VrfTables> id = buildVrfId(rd);
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
List<ListenableFuture<?>> futures = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.info("populateFibOnNewDpn: dpn: {}: VRF Table not yet available for RD {}", dpnId, rd);
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
}
final ReentrantLock lock = lockFor(vpnInstance);
lock.lock();
try {
futures.add(retryingTxRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry().values()) {
SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
if (subnetRoute != null) {
long elanTag = subnetRoute.getElantag().toJava();
installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, tx);
installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry, NwConstants.ADD_FLOW, tx);
continue;
}
RouterInterface routerInt = vrfEntry.augmentation(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<Uint32> 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 (Objects.equals(lri.getDpnId(), dpnId)) {
try {
int etherType = NWUtil.getEtherTypeFromIpPrefix(vrfEntry.getDestPrefix());
createLocalFibEntry(vpnId, rd, vrfEntry, etherType);
} catch (IllegalArgumentException ex) {
LOG.warn("Unable to get etherType for IP Prefix {}", vrfEntry.getDestPrefix());
}
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())) {
List<SubTransaction> txnObjects = new ArrayList<>();
bgpRouteVrfEntryHandler.createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(), vrfEntry, TransactionAdapter.toWriteTransaction(tx), txnObjects);
} else {
createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(), vrfEntry, tx);
}
}
}
}));
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
} finally {
lock.unlock();
}
return futures;
});
}
use of com.google.common.util.concurrent.Futures in project thingsboard by thingsboard.
the class BaseAssetService method findAssetsByQuery.
@Override
public ListenableFuture<List<Asset>> findAssetsByQuery(TenantId tenantId, AssetSearchQuery query) {
ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery());
ListenableFuture<List<Asset>> assets = Futures.transformAsync(relations, r -> {
EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection();
List<ListenableFuture<Asset>> futures = new ArrayList<>();
for (EntityRelation relation : r) {
EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom();
if (entityId.getEntityType() == EntityType.ASSET) {
futures.add(findAssetByIdAsync(tenantId, new AssetId(entityId.getId())));
}
}
return Futures.successfulAsList(futures);
}, MoreExecutors.directExecutor());
assets = Futures.transform(assets, assetList -> assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()), MoreExecutors.directExecutor());
return assets;
}
use of com.google.common.util.concurrent.Futures in project thingsboard by thingsboard.
the class TbAbstractSubCtx method resolve.
public void resolve(TenantId tenantId, CustomerId customerId, UserId userId) {
List<ListenableFuture<DynamicValueKeySub>> futures = new ArrayList<>();
for (DynamicValueKey key : dynamicValues.keySet()) {
switch(key.getSourceType()) {
case CURRENT_TENANT:
futures.add(resolveEntityValue(tenantId, tenantId, key));
break;
case CURRENT_CUSTOMER:
if (customerId != null && !customerId.isNullUid()) {
futures.add(resolveEntityValue(tenantId, customerId, key));
}
break;
case CURRENT_USER:
if (userId != null && !userId.isNullUid()) {
futures.add(resolveEntityValue(tenantId, userId, key));
}
break;
}
}
try {
Map<EntityId, Map<String, DynamicValueKeySub>> tmpSubMap = new HashMap<>();
for (DynamicValueKeySub sub : Futures.successfulAsList(futures).get()) {
tmpSubMap.computeIfAbsent(sub.getEntityId(), tmp -> new HashMap<>()).put(sub.getKey().getSourceAttribute(), sub);
}
for (EntityId entityId : tmpSubMap.keySet()) {
Map<String, Long> keyStates = new HashMap<>();
Map<String, DynamicValueKeySub> dynamicValueKeySubMap = tmpSubMap.get(entityId);
dynamicValueKeySubMap.forEach((k, v) -> keyStates.put(k, v.getLastUpdateTs()));
int subIdx = sessionRef.getSessionSubIdSeq().incrementAndGet();
TbAttributeSubscription sub = TbAttributeSubscription.builder().serviceId(serviceId).sessionId(sessionRef.getSessionId()).subscriptionId(subIdx).tenantId(sessionRef.getSecurityCtx().getTenantId()).entityId(entityId).updateConsumer((s, subscriptionUpdate) -> dynamicValueSubUpdate(s, subscriptionUpdate, dynamicValueKeySubMap)).allKeys(false).keyStates(keyStates).scope(TbAttributeSubscriptionScope.SERVER_SCOPE).build();
subToDynamicValueKeySet.add(subIdx);
localSubscriptionService.addSubscription(sub);
}
} catch (InterruptedException | ExecutionException e) {
log.info("[{}][{}][{}] Failed to resolve dynamic values: {}", tenantId, customerId, userId, dynamicValues.keySet());
}
}
Aggregations