public static <R, S, P extends Message, Q extends Message, T extends Message>
    CompletableFuture<Long>
    rowCount(AsyncTable<?> table, ColumnInterpreter<R, S, P, Q, T> ci, Scan scan) {
    CompletableFuture<Long> future = new CompletableFuture<>();
    AggregateRequest req;
    try {
      req = validateArgAndGetPB(scan, ci, true, true);
    } catch (IOException e) {
      future.completeExceptionally(e);
      return future;
    }
    AbstractAggregationCallback<Long> callback =
      new AbstractAggregationCallback<>(future, req, AggregateService::getRowNum) {

        private final AtomicLong count = new AtomicLong(0L);

        @Override
        protected void aggregate(RegionInfo region, AggregateResponse resp) throws IOException {
          count.addAndGet(resp.getFirstPart(0).asReadOnlyByteBuffer().getLong());
        }

        @Override
        protected Long getFinalResult() {
          return count.get();
        }
      };
    table
      .coprocessorService(AggregateService::newStub,
        (stub, controller, rpcCallback) -> stub.getRowNum(controller, req, rpcCallback), callback)
      .fromRow(nullToEmpty(scan.getStartRow()), scan.includeStartRow())
      .toRow(nullToEmpty(scan.getStopRow()), scan.includeStopRow()).execute();
    return future;
  }
This client class is for invoking the aggregate functions deployed on the Region Server side via
the AggregateService. This class will implement the supporting functionality for
summing/processing the individual results obtained from the AggregateService for each region.
hbase-endpoint/src/main/java/org/apache/hadoop/hbase/client/coprocessor/AsyncAggregationClient.java