docs: public static Result<TokenResponse> getTokenResult(TokenRequest tokenRequest, String envTag) {
          final AtomicReference<Result<TokenResponse>> reference = new AtomicReference<>();
          final Http2Client client = Http2Client.getInstance();
          final CountDownLatch latch = new CountDownLatch(1);
          final ClientConnection connection;
          try {
              if(tokenRequest.getServerUrl() != null) {
                  connection = client.connect(new URI(tokenRequest.getServerUrl()), Http2Client.WORKER, Http2Client.SSL, Http2Client.BUFFER_POOL, tokenRequest.enableHttp2 ? OptionMap.create(UndertowOptions.ENABLE_HTTP2, true): OptionMap.EMPTY).get();
              } else if(tokenRequest.getServiceId() != null) {
                  Cluster cluster = SingletonServiceFactory.getBean(Cluster.class);
                  String url = cluster.serviceToUrl("https", tokenRequest.getServiceId(), envTag, null);
                  connection = client.connect(new URI(url), Http2Client.WORKER, Http2Client.SSL, Http2Client.BUFFER_POOL, tokenRequest.enableHttp2 ? OptionMap.create(UndertowOptions.ENABLE_HTTP2, true): OptionMap.EMPTY).get();
              } else {
                  // both server_url and serviceId are empty in the config.
                  logger.error("Error: both server_url and serviceId are not configured in client.yml for " + tokenRequest.getClass());
                  throw new ClientException("both server_url and serviceId are not configured in client.yml for " + tokenRequest.getClass());
              }
          } catch (Exception e) {
              logger.error("cannot establish connection:", e);
              return Failure.of(new Status(ESTABLISH_CONNECTION_ERROR, tokenRequest.getServerUrl() != null? tokenRequest.getServerUrl() : tokenRequest.getServiceId()));
          }
  
          try {
              IClientRequestComposable requestComposer = ClientRequestComposerProvider.getInstance().getComposer(ClientRequestComposerProvider.ClientRequestComposers.CLIENT_CREDENTIAL_REQUEST_COMPOSER);
  
              connection.getIoThread().execute(new TokenRequestAction(tokenRequest, requestComposer, connection, reference, latch));
  
              latch.await(4, TimeUnit.SECONDS);
          } catch (Exception e) {
              logger.error("IOException: ", e);
              return Failure.of(new Status(FAIL_TO_SEND_REQUEST));
          } finally {
              IoUtils.safeClose(connection);
          }
  
          //if reference.get() is null at this point, mostly likely couldn't get token within latch.await() timeout.
          return reference.get() == null ? Failure.of(new Status(GET_TOKEN_TIMEOUT)) : reference.get();
      }