Skip to content

Commit

Permalink
Allow per-request base URIs in HttpClient
Browse files Browse the repository at this point in the history
  • Loading branch information
adutra committed Jan 8, 2024
1 parent ee2ce33 commit 9d7f429
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ enum Method {

HttpRequest newRequest();

HttpRequest newRequest(URI baseUri);

static Builder builder() {
return new HttpClientBuilderImpl();
}

URI getBaseUri();

@Override
void close();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ public HttpClient.Builder addTracing() {

@Override
public HttpClient build() {
HttpUtils.checkArgument(
baseUri != null, "Cannot construct Http client. Must have a non-null uri");
HttpUtils.checkArgument(
mapper != null, "Cannot construct Http client. Must have a non-null object mapper");
if (sslContext == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
*/
package org.projectnessie.client.http;

import static java.util.Objects.requireNonNull;
import static org.projectnessie.client.http.impl.HttpUtils.checkArgument;

import java.net.URI;
import org.projectnessie.client.http.HttpClient.Method;
import org.projectnessie.client.http.impl.HttpHeaders;
import org.projectnessie.client.http.impl.HttpRuntimeConfig;
Expand All @@ -31,7 +35,16 @@ public abstract class HttpRequest
protected String accept = "application/json; charset=utf-8";

protected HttpRequest(HttpRuntimeConfig config) {
this.uriBuilder = new UriBuilder(config.getBaseUri());
this(config, config.getBaseUri());
}

protected HttpRequest(HttpRuntimeConfig config, URI baseUri) {
requireNonNull(baseUri, "Base URI cannot be null");
checkArgument(
"http".equals(baseUri.getScheme()) || "https".equals(baseUri.getScheme()),
"Base URI must be a valid http or https address: %s",
baseUri);
this.uriBuilder = new UriBuilder(baseUri);
this.config = config;

int clientSpec = config.getClientSpec();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.fasterxml.jackson.databind.ObjectWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
Expand All @@ -47,6 +48,10 @@ protected BaseHttpRequest(HttpRuntimeConfig config) {
super(config);
}

protected BaseHttpRequest(HttpRuntimeConfig config, URI baseUri) {
super(config, baseUri);
}

protected boolean prepareRequest(RequestContext context) {
headers.put(HEADER_ACCEPT, accept);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,17 @@ static ImmutableHttpRuntimeConfig.Builder builder() {
@Value.Check
default void check() {
URI baseUri = getBaseUri();
if (!"http".equals(baseUri.getScheme()) && !"https".equals(baseUri.getScheme())) {
throw new IllegalArgumentException(
String.format(
"Cannot start http client. %s must be a valid http or https address", baseUri));
if (baseUri != null) {
if (!"http".equals(baseUri.getScheme()) && !"https".equals(baseUri.getScheme())) {
throw new IllegalArgumentException(
String.format(
"Cannot start http client. %s must be a valid http or https address", baseUri));
}
}
}

@Nullable
@jakarta.annotation.Nullable
URI getBaseUri();

ObjectMapper getMapper();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ public JavaHttpClient(HttpRuntimeConfig config) {

@Override
public HttpRequest newRequest() {
return new JavaRequest(this.config, (req, handler) -> client.send(req, handler));
return new JavaRequest(this.config, client::send);
}

@Override
public URI getBaseUri() {
return config.getBaseUri();
public HttpRequest newRequest(URI baseUri) {
return new JavaRequest(this.config, baseUri, client::send);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ HttpResponse<T> send(HttpRequest request, HttpResponse.BodyHandler<T> responseBo
this.exchange = exchange;
}

JavaRequest(HttpRuntimeConfig config, URI baseUri, HttpExchange<InputStream> exchange) {
super(config, baseUri);
this.exchange = exchange;
}

@Override
public org.projectnessie.client.http.HttpResponse executeRequest(Method method, Object body)
throws HttpClientException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public HttpRequest newRequest() {
}

@Override
public URI getBaseUri() {
return config.getBaseUri();
public HttpRequest newRequest(URI baseUri) {
return new UrlConnectionRequest(config, baseUri);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ final class UrlConnectionRequest extends BaseHttpRequest {
super(config);
}

UrlConnectionRequest(HttpRuntimeConfig config, URI baseUri) {
super(config, baseUri);
}

@Override
public HttpResponse executeRequest(Method method, Object body) throws HttpClientException {
URI uri = uriBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,41 @@ void testGet() throws Exception {
}
}

@Test
void testPerRequestBaseUri() throws Exception {
ExampleBean inputBean = new ExampleBean("x", 1, NOW);
HttpTestServer.RequestHandler handler =
(req, resp) -> {
soft.assertThat(req.getMethod()).isEqualTo("GET");
String response = MAPPER.writeValueAsString(inputBean);
writeResponseBody(resp, response);
};
try (HttpTestServer server = new HttpTestServer(handler)) {
try (HttpClient client = createClient(null, b -> {})) {
ExampleBean bean = client.newRequest(server.getUri()).get().readEntity(ExampleBean.class);
soft.assertThat(bean).isEqualTo(inputBean);
}
}
}

@Test
void testNullPerRequestBaseUri() {
try (HttpClient client = createClient(null, b -> {})) {
assertThatThrownBy(() -> client.newRequest(null))
.isInstanceOf(NullPointerException.class)
.hasMessage("Base URI cannot be null");
}
}

@Test
void testInvalidPerRequestBaseUri() {
try (HttpClient client = createClient(null, b -> {})) {
assertThatThrownBy(() -> client.newRequest(URI.create("file:///foo/bar/baz")))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Base URI must be a valid http or https address");
}
}

@Test
void testPut() throws Exception {
ExampleBean inputBean = new ExampleBean("x", 1, NOW);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,6 @@ void testIncompatibleAuthProvider() {
.hasMessage("HttpClientBuilder only accepts instances of HttpAuthentication");
}

@Test
void testNullUri() {
assertThatThrownBy(
() ->
createClientBuilderFromSystemSettings()
.withUri((URI) null)
.build(NessieApiV1.class))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Cannot construct Http client. Must have a non-null uri");
}

@Test
void testNoUri() {
assertThatThrownBy(() -> createClientBuilderFromSystemSettings().build(NessieApiV1.class))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Cannot construct Http client. Must have a non-null uri");
}

@Test
void testInvalidUriScheme() {
assertThatThrownBy(
Expand Down

0 comments on commit 9d7f429

Please sign in to comment.