docs: @Override
    public CompletableFuture<Data> getAsync(Face face, Interest interest) {
      final CompletableFuture futureData = new CompletableFuture<>();
  
      // send interest
      logger.log(Level.FINER, "Sending interest for: " + interest.getName().toUri());
      try {
        face.expressInterest(interest, new OnData() {
          @Override
          public void onData(Interest interest, Data data) {
            logger.log(Level.FINER, "Retrieved data: " + data.getName().toUri());
            futureData.complete(data);
          }
        }, new OnTimeout() {
          @Override
          public void onTimeout(Interest interest) {
            String message = interest.getInterestLifetimeMilliseconds() + "ms timeout exceeded";
            futureData.completeExceptionally(new TimeoutException(message));
          }
        });
      } catch (IOException e) {
        logger.log(Level.FINE, "IO failure while sending interest: ", e);
        futureData.completeExceptionally(e);
      }
  
      return futureData;
    }