public static CompletableFuture<AsyncConnection> createAsyncConnection(URI connectionUri,
    Configuration conf, final User user, Map<String, byte[]> connectionAttributes) {
    return TraceUtil.tracedFuture(() -> {
      ConnectionRegistry registry;
      Configuration appliedConf;
      try {
        if (connectionUri != null) {
          appliedConf = new Configuration(conf);
          Strings.applyURIQueriesToConf(connectionUri, appliedConf);
          registry = ConnectionRegistryFactory.create(connectionUri, appliedConf, user);
        } else {
          appliedConf = conf;
          registry = ConnectionRegistryFactory.create(appliedConf, user);
        }
      } catch (Exception e) {
        return FutureUtils.failedFuture(e);
      }
      CompletableFuture<AsyncConnection> future = new CompletableFuture<>();
      addListener(registry.getClusterId(), (clusterId, error) -> {
        if (error != null) {
          registry.close();
          future.completeExceptionally(error);
          return;
        }
        if (clusterId == null) {
          registry.close();
          future.completeExceptionally(new IOException("clusterid came back null"));
          return;
        }
        Class<? extends AsyncConnection> clazz = appliedConf.getClass(
          HBASE_CLIENT_ASYNC_CONNECTION_IMPL, AsyncConnectionImpl.class, AsyncConnection.class);
        try {
          future.complete(user.runAs((PrivilegedExceptionAction<
            ? extends AsyncConnection>) () -> ReflectionUtils.newInstance(clazz, appliedConf,
              registry, clusterId, null, user, connectionAttributes)));
        } catch (Exception e) {
          registry.close();
          future.completeExceptionally(e);
        }
      });
      return future;
    }, "ConnectionFactory.createAsyncConnection");
  }
Create a new AsyncConnection instance using the passed {@code connectionUri}, {@code conf} and
{@code user}. AsyncConnection encapsulates all housekeeping for a connection to the cluster.
All tables and interfaces created from returned connection share zookeeper connection(if used),
meta cache, and connections to region servers and masters.
<p>
The caller is responsible for calling {@link AsyncConnection#close()} on the returned
connection instance.
<p>
Usually you should only create one AsyncConnection instance in your code and use it everywhere
as it is thread safe.
@param connectionUri        the connection uri for the hbase cluster
@param conf                 configuration
@param user                 the user the asynchronous connection is for
@param connectionAttributes attributes to be sent along to server during connection establish
@return AsyncConnection object wrapped by CompletableFuture
hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionFactory.java