com.google.common.util.concurrent.ListenableFuture Java Examples

The following examples show how to use com.google.common.util.concurrent.ListenableFuture. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SqlTaskExecution.java    From presto with Apache License 2.0 6 votes vote down vote up
@Override
public ListenableFuture<?> processFor(Duration duration)
{
    Driver driver;
    synchronized (this) {
        // if close() was called before we get here, there's not point in even creating the driver
        if (closed) {
            return Futures.immediateFuture(null);
        }

        if (this.driver == null) {
            this.driver = driverSplitRunnerFactory.createDriver(driverContext, partitionedSplit);
        }

        driver = this.driver;
    }

    return driver.processFor(duration);
}
 
Example #2
Source File: TestingMethodInvocationStat.java    From drift with Apache License 2.0 6 votes vote down vote up
@Override
public void recordResult(long startTime, ListenableFuture<Object> result)
{
    invocations.incrementAndGet();
    result.addListener(
            () -> {
                lastStartTime.set(startTime);
                try {
                    result.get();
                    successes.incrementAndGet();
                }
                catch (Throwable throwable) {
                    failures.incrementAndGet();
                }
            },
            directExecutor());
}
 
Example #3
Source File: DeviceServiceImpl.java    From Groza with Apache License 2.0 6 votes vote down vote up
@Override
public ListenableFuture<List<Device>> findDevicesByQuery(DeviceSearchQuery query) {
    ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(query.toEntitySearchQuery());
    ListenableFuture<List<Device>> devices = Futures.transformAsync(relations, r -> {
        EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection();
        List<ListenableFuture<Device>> futures = new ArrayList<>();
        for (EntityRelation relation : r) {
            EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom();
            if (entityId.getEntityType() == EntityType.DEVICE) {
                futures.add(findDeviceByIdAsync(new DeviceId(entityId.getId())));
            }
        }
        return Futures.successfulAsList(futures);
    });

    devices = Futures.transform(devices, new Function<List<Device>, List<Device>>() {
        @Nullable
        @Override
        public List<Device> apply(@Nullable List<Device> deviceList) {
            return deviceList == null ? Collections.emptyList() : deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList());
        }
    });

    return devices;
}
 
Example #4
Source File: QueueClient.java    From ProjectAres with GNU Affero General Public License v3.0 6 votes vote down vote up
public ListenableFuture<?> publishAsync(final Exchange exchange, final Message message, final @Nullable BasicProperties properties, final @Nullable Publish publish) {
    // NOTE: Serialization must happen synchronously, because getter methods may not be thread-safe
    final String payload = gson.toJson(message);
    final AMQP.BasicProperties finalProperties = getProperties(message, properties);
    final Publish finalPublish = Publish.forMessage(message, publish);

    if(this.executorService == null) throw new IllegalStateException("Not connected");
    return this.executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                publish(exchange, payload, finalProperties, finalPublish);
            } catch(Throwable e) {
                logger.log(Level.SEVERE, "Unhandled exception publishing message type " + finalProperties.getType(), e);
            }
        }
    });
}
 
Example #5
Source File: MobileServicePush.java    From azure-mobile-apps-android-client with Apache License 2.0 6 votes vote down vote up
/**
 * Unregisters the client for native notifications
 *
 * @param callback The operation callback
 * @deprecated use {@link #unregister()} instead
 */
public void unregister(final UnregisterCallback callback) {
    ListenableFuture<Void> deleteInstallationFuture = deleteInstallation();

    Futures.addCallback(deleteInstallationFuture, new FutureCallback<Void>() {
        @Override
        public void onFailure(Throwable exception) {
            if (exception instanceof Exception) {
                callback.onUnregister((Exception) exception);
            }
        }

        @Override
        public void onSuccess(Void v) {
            callback.onUnregister(null);
        }
    }, MoreExecutors.directExecutor());
}
 
Example #6
Source File: GroupsServiceImpl.java    From connector-sdk with Apache License 2.0 6 votes vote down vote up
private static <T> ListenableFuture<T> batchRequest(
    AbstractGoogleJsonClientRequest<T> requestToExecute,
    RetryPolicy retryPolicy,
    BatchRequestService batchService)
    throws IOException {
  AsyncRequest<T> request =
      new AsyncRequest<>(requestToExecute, retryPolicy, GROUP_SERVICE_STATS);
  try {
    API_RATE_LIMITER.acquire();
    batchService.add(request);
  } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    throw new IOException("Interrupted while batching request", e);
  }
  return request.getFuture();
}
 
Example #7
Source File: MobileServiceTable.java    From azure-mobile-apps-android-client with Apache License 2.0 6 votes vote down vote up
/**
 * Executes a query to retrieve all the table rows
 *
 * @param query The Query instance to execute
 */
public ListenableFuture<MobileServiceList<E>> execute(Query query) {
    final SettableFuture<MobileServiceList<E>> future = SettableFuture.create();
    ListenableFuture<JsonElement> internalFuture = mInternalTable.execute(query);
    Futures.addCallback(internalFuture, new FutureCallback<JsonElement>() {
        @Override
        public void onFailure(Throwable exc) {
            future.setException(exc);
        }

        @Override
        public void onSuccess(JsonElement result) {
            processQueryResults(result, future);
        }
    }, MoreExecutors.directExecutor());

    return future;
}
 
Example #8
Source File: HealthCheckDirectiveHandler.java    From arcusplatform with Apache License 2.0 6 votes vote down vote up
private ListenableFuture<HealthCheckResponse> ping() {
   PlatformMessage msg = PlatformMessage.buildRequest(MessageBody.ping(), AlexaUtil.ADDRESS_BRIDGE, STATUS_SERVICE)
         .withCorrelationId(IrisUUID.randomUUID().toString())
         .create();

   ListenableFuture<PlatformMessage> future = platSvc.request(
      msg,
      (pm) -> Objects.equals(msg.getCorrelationId(), pm.getCorrelationId()), config.getHealthCheckTimeoutSecs()
   );

   return Futures.transform(future, (Function<PlatformMessage, HealthCheckResponse>) input -> {
      HealthCheckResponse response = new HealthCheckResponse();
      response.setHealthy(true);
      response.setDescription("The system is currently healthy");
      return response;
   }, MoreExecutors.directExecutor());
}
 
Example #9
Source File: JavascriptEvaluation.java    From android-test with Apache License 2.0 6 votes vote down vote up
@Override
public ListenableFuture<String> apply(final PreparedScript in) {
  if (null != in.conduit) {
    return Futures.<String>immediateFailedFuture(
        new RuntimeException("Conduit script cannot be used"));
  } else {
    final ValueCallbackFuture<String> result = new ValueCallbackFuture<String>();
    if (Looper.myLooper() == Looper.getMainLooper()) {
      in.view.evaluateJavascript(in.script, result);
    } else {
      in.view.post(
          new Runnable() {
            @Override
            public void run() {
              in.view.evaluateJavascript(in.script, result);
            }
          });
    }
    return result;
  }
}
 
Example #10
Source File: GaService.java    From GreenBits with GNU General Public License v3.0 6 votes vote down vote up
public ListenableFuture<String>
sendTransaction(final List<byte[]> sigs, final Object twoFacData) {
    // FIXME: The server should return the full limits including is_fiat from send_tx
    return Futures.transform(mClient.sendTransaction(sigs, twoFacData),
                             new Function<String, String>() {
               @Override
               public String apply(final String txHash) {
                   try {
                       mLimitsData = mClient.getSpendingLimits();
                   } catch (final Exception e) {
                       // We don't know what the new limit is so nuke it
                       mLimitsData.mData.put("total", 0);
                       e.printStackTrace();
                   }
                   return txHash;
               }
    }, mExecutor);
}
 
Example #11
Source File: LocalCache.java    From codebuff with BSD 2-Clause "Simplified" License 6 votes vote down vote up
ListenableFuture<V> loadAsync(
  final K key,
  final int hash,
  final LoadingValueReference<K, V> loadingValueReference,
  CacheLoader<? super K, V> loader) {
  final ListenableFuture<V> loadingFuture = loadingValueReference.loadFuture(key, loader);
  loadingFuture.addListener(new Runnable() {
                              @Override
                              public void run() {
                                try {
                                  getAndRecordStats(key, hash, loadingValueReference, loadingFuture);
                                } catch (Throwable t) {
                                  logger.log(Level.WARNING, "Exception thrown during refresh", t);
                                  loadingValueReference.setException(t);
                                }
                              }
                            }, directExecutor());
  return loadingFuture;
}
 
Example #12
Source File: IdentityGroup.java    From connector-sdk with Apache License 2.0 6 votes vote down vote up
/** Removes {@link IdentityGroup} from Cloud Identity Groups API using {@code service}. */
@Override
public ListenableFuture<Boolean> unmap(IdentityService service) throws IOException {
  ListenableFuture<Operation> deleteGroup = service.deleteGroup(groupResourceName.get());
  return Futures.transform(
      deleteGroup,
      new Function<Operation, Boolean>() {
        @Override
        @Nullable
        public Boolean apply(@Nullable Operation input) {
          try {
            validateOperation(input);
            return true;
          } catch (IOException e) {
            logger.log(Level.WARNING, String.format("Failed to delete Group %s", groupKey), e);
            return false;
          }
        }
      },
      getExecutor());
}
 
Example #13
Source File: BaseAlarmService.java    From iotplatform with Apache License 2.0 6 votes vote down vote up
@Override
public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(AlarmId alarmId) {
    log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId);
    validateId(alarmId, "Incorrect alarmId " + alarmId);
    return Futures.transform(alarmDao.findAlarmByIdAsync(alarmId.getId()),
            (AsyncFunction<Alarm, AlarmInfo>) alarm1 -> {
                AlarmInfo alarmInfo = new AlarmInfo(alarm1);
                return Futures.transform(
                        entityService.fetchEntityNameAsync(alarmInfo.getOriginator()), (Function<String, AlarmInfo>)
                                originatorName -> {
                                    alarmInfo.setOriginatorName(originatorName);
                                    return alarmInfo;
                                }
                );
            });
}
 
Example #14
Source File: LocalCache.java    From codebuff with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Refreshes the value associated with {@code key}, unless another thread is already doing so.
 * Returns the newly refreshed value associated with {@code key} if it was refreshed inline, or
 * {@code null} if another thread is performing the refresh or if an error occurs during
 * refresh.
 */

@Nullable
V refresh(K key, int hash, CacheLoader<? super K, V> loader, boolean checkTime) {
  final LoadingValueReference<K, V> loadingValueReference = insertLoadingValueReference(key, hash, checkTime);
  if (loadingValueReference == null) {
    return null;
  }
  ListenableFuture<V> result = loadAsync(key, hash, loadingValueReference, loader);
  if (result.isDone()) {
    try {
      return Uninterruptibles.getUninterruptibly(result);
    } catch (Throwable t) {
      // don't let refresh exceptions propagate; error was already logged
    }
  }
  return null;
}
 
Example #15
Source File: AbstractConfiguredObjectTest.java    From qpid-broker-j with Apache License 2.0 6 votes vote down vote up
@Test
public void testGetChildren_NewChild()
{
    TestCar car = _model.getObjectFactory().create(TestCar.class, Collections.<String, Object>singletonMap(ConfiguredObject.NAME, "myCar"), null);

    String engineName = "myEngine";
    Map<String, Object> engineAttributes = new HashMap<>();
    engineAttributes.put(ConfiguredObject.NAME, engineName);

    TestEngine engine = (TestEngine) car.createChild(TestEngine.class, engineAttributes);

    // Check we can observe the new child from the parent

    assertEquals((long) 1, (long) car.getChildren(TestEngine.class).size());
    assertEquals(engine, car.getChildById(TestEngine.class, engine.getId()));
    assertEquals(engine, car.getChildByName(TestEngine.class, engine.getName()));

    ListenableFuture attainedChild = car.getAttainedChildByName(TestEngine.class, engine.getName());
    assertNotNull(attainedChild);
    assertTrue("Engine should have already attained state", attainedChild.isDone());
}
 
Example #16
Source File: AssetController.java    From iotplatform with Apache License 2.0 5 votes vote down vote up
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/asset/types", method = RequestMethod.GET)
@ResponseBody
public List<TenantAssetType> getAssetTypes() throws IoTPException {
  try {
    SecurityUser user = getCurrentUser();
    TenantId tenantId = user.getTenantId();
    ListenableFuture<List<TenantAssetType>> assetTypes = assetService.findAssetTypesByTenantId(tenantId);
    return checkNotNull(assetTypes.get());
  } catch (Exception e) {
    throw handleException(e);
  }
}
 
Example #17
Source File: SqlTaskManager.java    From presto with Apache License 2.0 5 votes vote down vote up
@Override
public ListenableFuture<TaskStatus> getTaskStatus(TaskId taskId, TaskState currentState)
{
    requireNonNull(taskId, "taskId is null");
    requireNonNull(currentState, "currentState is null");

    SqlTask sqlTask = tasks.getUnchecked(taskId);
    sqlTask.recordHeartbeat();
    return sqlTask.getTaskStatus(currentState);
}
 
Example #18
Source File: ZKDiscoveryService.java    From twill with Apache License 2.0 5 votes vote down vote up
ListenableFuture<?> asyncCancel() {
  if (!cancelled.compareAndSet(false, true)) {
    return Futures.immediateFuture(null);
  }

  // Take a snapshot of the volatile path.
  String path = this.path;

  // If it is null, meaning cancel is called before the ephemeral node is created, hence
  // setPath() will be called in future (through zk callback when creation is completed)
  // so that deletion will be done in setPath().
  if (path == null) {
    return Futures.immediateFuture(null);
  }

  // Remove this Cancellable from the map so that upon session expiration won't try to register.
  lock.lock();
  try {
    discoverables.remove(discoverable, this);
  } finally {
    lock.unlock();
  }

  // Delete the path. It's ok if the path not exists
  // (e.g. what session expired and before node has been re-created)
  try {
    return ZKOperations.ignoreError(zkClient.delete(path), KeeperException.NoNodeException.class, path);
  } catch (Exception e) {
    return Futures.immediateFailedFuture(e);
  }
}
 
Example #19
Source File: OperatorContext.java    From presto with Apache License 2.0 5 votes vote down vote up
public void recordBlocked(ListenableFuture<?> blocked)
{
    requireNonNull(blocked, "blocked is null");

    BlockedMonitor monitor = new BlockedMonitor();

    BlockedMonitor oldMonitor = blockedMonitor.getAndSet(monitor);
    if (oldMonitor != null) {
        oldMonitor.run();
    }

    blocked.addListener(monitor, executor);
    // Do not register blocked with driver context.  The driver handles this directly.
}
 
Example #20
Source File: BrokerImpl.java    From qpid-broker-j with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
@Override
protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
                                                                      final Map<String, Object> attributes)
{
    if (childClass == VirtualHostNode.class)
    {
        return (ListenableFuture<C>) createVirtualHostNodeAsync(attributes);
    }
    else
    {
        return super.addChildAsync(childClass, attributes);
    }
}
 
Example #21
Source File: JpaAlarmDao.java    From iotplatform with Apache License 2.0 5 votes vote down vote up
@Override
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
  return service.submit(() -> {
    List<AlarmEntity> latest = alarmRepository.findLatestByOriginatorAndType(
        UUIDConverter.fromTimeUUID(tenantId.getId()), UUIDConverter.fromTimeUUID(originator.getId()),
        originator.getEntityType(), type, new PageRequest(0, 1));
    return latest.isEmpty() ? null : DaoUtil.getData(latest.get(0));
  });
}
 
Example #22
Source File: TestEpochsAreUnique.java    From hadoop with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
@Override
public ListenableFuture<T> answer(InvocationOnMock invocation)
    throws Throwable {
  if (r.nextFloat() < faultProbability) {
    return Futures.immediateFailedFuture(
        new IOException("Injected fault"));
  }
  return (ListenableFuture<T>)invocation.callRealMethod();
}
 
Example #23
Source File: TopicTreeStartup.java    From hivemq-community-edition with Apache License 2.0 5 votes vote down vote up
/**
 * Populates the topic tree with all information from the ClientSessionPersistence
 */
private void populateTopicTree() {
    final ListenableFuture<Set<String>> clientsFuture = clientSessionPersistence.getAllClients();
    // Blocking. The TopicTreeStartup needs to be done before new connections are allowed.
    try {
        final Set<String> clients = clientsFuture.get();
        for (final String client : clients) {
            final Set<Topic> clientSubscriptions = clientSessionSubscriptionPersistence.getSubscriptions(client);
            final ClientSession session = clientSessionPersistence.getSession(client, false);
            if (session == null || session.getSessionExpiryInterval() == SESSION_EXPIRE_ON_DISCONNECT) {
                // We don't have to remove the subscription from the topic tree, since it is not added to the topic tree yet.
                clientSessionSubscriptionPersistence.removeAllLocally(client);
                continue;
            }

            for (final Topic topic : clientSubscriptions) {
                final SharedSubscription sharedSubscription = sharedSubscriptionService.checkForSharedSubscription(topic.getTopic());
                if (sharedSubscription == null) {
                    topicTree.addTopic(client, topic, SubscriptionFlags.getDefaultFlags(false, topic.isRetainAsPublished(), topic.isNoLocal()), null);
                } else {
                    topicTree.addTopic(client, new Topic(sharedSubscription.getTopicFilter(), topic.getQoS(), topic.isNoLocal(), topic.isRetainAsPublished()), SubscriptionFlags.getDefaultFlags(true, topic.isRetainAsPublished(), topic.isNoLocal()), sharedSubscription.getShareName());
                }
            }
        }
    } catch (final Exception ex) {
        log.error("Failed to bootstrap topic tree.", ex);
    }
}
 
Example #24
Source File: S3ScanWriter.java    From emodb with Apache License 2.0 5 votes vote down vote up
/**
 * Starts an asynchronous upload and returns a ListenableFuture for handling the result.
 */
synchronized ListenableFuture<String> upload() {
    // Reset values from possible prior attempt
    _attempts += 1;
    _bytesTransferred = 0;

    // Separate the future returned to the caller from the future generated by submitting the
    // putObject request.  If the writer is closed then uploadFuture may be canceled before it executes,
    // in which case it may not trigger any callbacks.  To ensure there is always a callback resultFuture is
    // tracked independently and, in the event that the upload is aborted, gets set on abort().
    _resultFuture = SettableFuture.create();

    _uploadFuture = _uploadService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                ProgressListener progressListener = new ProgressListener() {
                    @Override
                    public void progressChanged(ProgressEvent progressEvent) {
                        // getBytesTransferred() returns zero for all events not pertaining to the file transfer
                        _bytesTransferred += progressEvent.getBytesTransferred();
                    }
                };

                PutObjectRequest putObjectRequest = new PutObjectRequest(_bucket, _key, _file);
                putObjectRequest.setGeneralProgressListener(progressListener);
                PutObjectResult result = _amazonS3.putObject(putObjectRequest);
                _resultFuture.set(result.getETag());
            } catch (Throwable t) {
                _resultFuture.setException(t);
            }
        }
    });

    return _resultFuture;
}
 
Example #25
Source File: TestApacheThriftMethodInvoker.java    From drift with Apache License 2.0 5 votes vote down vote up
private static int logApacheThriftInvocationHandler(HostAndPort address, List<DriftLogEntry> entries)
{
    ApacheThriftClientConfig config = new ApacheThriftClientConfig();
    ApacheThriftConnectionFactoryConfig factoryConfig = new ApacheThriftConnectionFactoryConfig();
    try (ApacheThriftMethodInvokerFactory<Void> methodInvokerFactory = new ApacheThriftMethodInvokerFactory<>(factoryConfig, clientIdentity -> config)) {
        MethodInvoker methodInvoker = methodInvokerFactory.createMethodInvoker(null);

        ParameterMetadata parameter = new ParameterMetadata(
                (short) 1,
                "messages",
                (ThriftCodec<Object>) codecManager.getCodec(list(codecManager.getCodec(DriftLogEntry.class).getType())));

        MethodMetadata methodMetadata = new MethodMetadata(
                "Log",
                ImmutableList.of(parameter),
                (ThriftCodec<Object>) (Object) codecManager.getCodec(DriftResultCode.class),
                ImmutableMap.of(),
                ImmutableMap.of(),
                false,
                true);

        ListenableFuture<Object> future = methodInvoker.invoke(new InvokeRequest(methodMetadata, () -> address, ImmutableMap.of(), ImmutableList.of(entries)));
        assertEquals(future.get(), DRIFT_OK);

        return 1;
    }
    catch (Exception e) {
        throw new RuntimeException(e);
    }
}
 
Example #26
Source File: CFCExecFileSystem.java    From bazel-buildfarm with Apache License 2.0 5 votes vote down vote up
private ListenableFuture<Void> linkDirectory(
    Path execPath, Digest digest, Map<Digest, Directory> directoriesIndex) {
  return transformAsync(
      fileCache.putDirectory(digest, directoriesIndex, fetchService),
      (cachePath) -> {
        Files.createSymbolicLink(execPath, cachePath);
        return immediateFuture(null);
      },
      fetchService);
}
 
Example #27
Source File: ThrowingServiceHandler.java    From drift with Apache License 2.0 5 votes vote down vote up
@Override
public synchronized ListenableFuture<String> await()
{
    createFuture.set(null);
    if (awaitFuture == null) {
        awaitFuture = SettableFuture.create();
    }
    return awaitFuture;
}
 
Example #28
Source File: Peer.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Asks the connected peer for the given transaction from its memory pool. Transactions in the chain cannot be
 * retrieved this way because peers don't have a transaction ID to transaction-pos-on-disk index, and besides,
 * in future many peers will delete old transaction data they don't need.
 */
@SuppressWarnings("unchecked")
// The 'unchecked conversion' warning being suppressed here comes from the sendSingleGetData() formally returning
// ListenableFuture instead of ListenableFuture<Transaction>. This is okay as sendSingleGetData() actually returns
// ListenableFuture<Transaction> in this context. Note that sendSingleGetData() is also used for Blocks.
public ListenableFuture<Transaction> getPeerMempoolTransaction(Sha256Hash hash) {
    // This does not need to be locked.
    // TODO: Unit test this method.
    log.info("Request to fetch peer mempool tx  {}", hash);
    GetDataMessage getdata = new GetDataMessage(params);
    getdata.addTransaction(hash);
    return sendSingleGetData(getdata);
}
 
Example #29
Source File: ExampleAsync.java    From async-datastore-client with Apache License 2.0 5 votes vote down vote up
private static ListenableFuture<MutationResult> addData(final Datastore datastore) {
  final Insert insert = QueryBuilder.insert("employee", 1234567L)
      .value("fullname", "Fred Blinge")
      .value("inserted", new Date())
      .value("age", 40);
  return datastore.executeAsync(insert);
}
 
Example #30
Source File: MultipleJavaClassesTestContextProvider.java    From intellij with Apache License 2.0 5 votes vote down vote up
@Nullable
private static TestContext fromClasses(
    ListenableFuture<TargetInfo> target, Set<PsiClass> classes) {
  Map<PsiClass, Collection<Location<?>>> methodsPerClass =
      classes.stream().collect(Collectors.toMap(c -> c, c -> ImmutableList.of()));
  String filter = BlazeJUnitTestFilterFlags.testFilterForClassesAndMethods(methodsPerClass);
  if (filter == null || filter.isEmpty()) {
    return null;
  }

  PsiClass sampleClass =
      classes.stream()
          .min(
              Comparator.comparing(
                  PsiClass::getName, Comparator.nullsLast(Comparator.naturalOrder())))
          .orElse(null);
  if (sampleClass == null) {
    return null;
  }
  String name = sampleClass.getName();
  if (name != null && classes.size() > 1) {
    name += String.format(" and %s others", classes.size() - 1);
  }
  return TestContext.builder(sampleClass, ExecutorType.DEBUG_SUPPORTED_TYPES)
      .setTarget(target)
      .setTestFilter(filter)
      .setDescription(name)
      .build();
}