code: public static URI buildURI(String urlTemplate, Map<String, String> keys, Map<String, String> queryParams) {
      // Compute base url
      String url = urlTemplate;
      if (keys != null && keys.size() != 0) {
        url = StrSubstitutor.replace(urlTemplate, keys);
      }
  
      try {
        URIBuilder uriBuilder = new URIBuilder(url);
        // Append query parameters
        if (queryParams != null && queryParams.size() != 0) {
          for (Map.Entry<String, String> entry : queryParams.entrySet()) {
            uriBuilder.addParameter(entry.getKey(), entry.getValue());
          }
        }
        return uriBuilder.build();
      } catch (URISyntaxException e) {
        throw new RuntimeException("Fail to build uri", e);
      }
    }
docs: Given a url template, interpolate with keys and build the URI after adding query parameters
  
  <p>
  With url template: http://test.com/resource/(urn:${resourceId})/entities/(entity:${entityId}),
  keys: { "resourceId": 123, "entityId": 456 }, queryParams: { "locale": "en_US" }, the outpuT URI is:
  http://test.com/resource/(urn:123)/entities/(entity:456)?locale=en_US
  </p>
  
  @param urlTemplate url template
  @param keys data map to interpolate url template
  @param queryParams query parameters added to the url
  @return a uri