Skip to content
This repository was archived by the owner on Sep 26, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import com.google.api.gax.rpc.ApiExceptionFactory;
import com.google.auth.Credentials;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
Expand All @@ -52,74 +53,64 @@
import java.util.Map.Entry;

/** A runnable object that creates and executes an HTTP request. */
// TODO(andrealin): AutoValue this class.
class HttpRequestRunnable<RequestT, ResponseT> implements Runnable {
private final HttpJsonCallOptions callOptions;
private final RequestT request;
private final ApiMethodDescriptor<RequestT, ResponseT> methodDescriptor;
private final HttpTransport httpTransport;
private final String endpoint;
private final JsonFactory jsonFactory;
private final ImmutableList<HttpJsonHeaderEnhancer> headerEnhancers;
private final SettableApiFuture<ResponseT> responseFuture;

private HttpRequestRunnable(
final HttpJsonCallOptions callOptions,
final RequestT request,
final ApiMethodDescriptor<RequestT, ResponseT> methodDescriptor,
final HttpTransport httpTransport,
String endpoint,
JsonFactory jsonFactory,
List<HttpJsonHeaderEnhancer> headerEnhancers,
SettableApiFuture<ResponseT> responseFuture) {
this.endpoint = endpoint;
this.jsonFactory = jsonFactory;
this.headerEnhancers = ImmutableList.copyOf(headerEnhancers);
this.callOptions = callOptions;
this.request = request;
this.methodDescriptor = methodDescriptor;
this.httpTransport = httpTransport;
this.responseFuture = responseFuture;
}
@AutoValue
abstract class HttpRequestRunnable<RequestT, ResponseT> implements Runnable {
abstract HttpJsonCallOptions getHttpJsonCallOptions();

abstract RequestT getRequest();

abstract ApiMethodDescriptor<RequestT, ResponseT> getApiMethodDescriptor();

abstract HttpTransport getHttpTransport();

abstract String getEndpoint();

abstract JsonFactory getJsonFactory();

abstract ImmutableList<HttpJsonHeaderEnhancer> getHeaderEnhancers();

abstract SettableApiFuture<ResponseT> getResponseFuture();

HttpRequest createHttpRequest() throws IOException {
GenericData tokenRequest = new GenericData();

HttpRequestFormatter<RequestT> requestFormatter = methodDescriptor.getRequestFormatter();
HttpRequestFormatter<RequestT> requestFormatter =
getApiMethodDescriptor().getRequestFormatter();

HttpRequestFactory requestFactory;
Credentials credentials = callOptions.getCredentials();
Credentials credentials = getHttpJsonCallOptions().getCredentials();
if (credentials != null) {
requestFactory = httpTransport.createRequestFactory(new HttpCredentialsAdapter(credentials));
requestFactory =
getHttpTransport().createRequestFactory(new HttpCredentialsAdapter(credentials));
} else {
requestFactory = httpTransport.createRequestFactory();
requestFactory = getHttpTransport().createRequestFactory();
}

// Create HTTP request body.
String requestBody = requestFormatter.getRequestBody(request);
String requestBody = requestFormatter.getRequestBody(getRequest());
JsonHttpContent jsonHttpContent = null;
if (!Strings.isNullOrEmpty(requestBody)) {
jsonFactory.createJsonParser(requestBody).parse(tokenRequest);
getJsonFactory().createJsonParser(requestBody).parse(tokenRequest);
jsonHttpContent =
new JsonHttpContent(jsonFactory, tokenRequest)
new JsonHttpContent(getJsonFactory(), tokenRequest)
.setMediaType((new HttpMediaType("application/json")));
}

// Populate URL path and query parameters.
GenericUrl url = new GenericUrl(endpoint + requestFormatter.getPath(request));
Map<String, List<String>> queryParams = requestFormatter.getQueryParamNames(request);
GenericUrl url = new GenericUrl(getEndpoint() + requestFormatter.getPath(getRequest()));
Map<String, List<String>> queryParams = requestFormatter.getQueryParamNames(getRequest());
for (Entry<String, List<String>> queryParam : queryParams.entrySet()) {
if (queryParam.getValue() != null) {
url.set(queryParam.getKey(), queryParam.getValue());
}
}

HttpRequest httpRequest =
requestFactory.buildRequest(methodDescriptor.getHttpMethod(), url, jsonHttpContent);
for (HttpJsonHeaderEnhancer enhancer : headerEnhancers) {
requestFactory.buildRequest(getApiMethodDescriptor().getHttpMethod(), url, jsonHttpContent);
for (HttpJsonHeaderEnhancer enhancer : getHeaderEnhancers()) {
enhancer.enhance(httpRequest.getHeaders());
}
httpRequest.setParser(new JsonObjectParser(jsonFactory));
httpRequest.setParser(new JsonObjectParser(getJsonFactory()));
return httpRequest;
}

Expand All @@ -135,85 +126,44 @@ public void run() {
HttpJsonStatusCode.of(httpResponse.getStatusCode(), httpResponse.getStatusMessage()),
false);
}
if (methodDescriptor.getResponseParser() != null) {
ResponseT response = methodDescriptor.getResponseParser().parse(httpResponse.getContent());
responseFuture.set(response);
if (getApiMethodDescriptor().getResponseParser() != null) {
ResponseT response =
getApiMethodDescriptor().getResponseParser().parse(httpResponse.getContent());
getResponseFuture().set(response);
} else {
responseFuture.set(null);
getResponseFuture().set(null);
}
} catch (Exception e) {
responseFuture.setException(e);
getResponseFuture().setException(e);
}
}

static <RequestT, ResponseT> Builder<RequestT, ResponseT> newBuilder() {
return new Builder<RequestT, ResponseT>()
return new AutoValue_HttpRequestRunnable.Builder<RequestT, ResponseT>()
.setHeaderEnhancers(new LinkedList<HttpJsonHeaderEnhancer>());
}

static class Builder<RequestT, ResponseT> {
private HttpJsonCallOptions callOptions;
private RequestT request;
private ApiMethodDescriptor<RequestT, ResponseT> methodDescriptor;
private HttpTransport httpTransport;
private String endpoint;
private JsonFactory jsonFactory;
private List<HttpJsonHeaderEnhancer> headerEnhancers;
private SettableApiFuture<ResponseT> responseFuture;

private Builder() {}

Builder<RequestT, ResponseT> setHttpJsonCallOptions(HttpJsonCallOptions callOptions) {
this.callOptions = callOptions;
return this;
}
@AutoValue.Builder
abstract static class Builder<RequestT, ResponseT> {
abstract Builder<RequestT, ResponseT> setHttpJsonCallOptions(HttpJsonCallOptions callOptions);

Builder<RequestT, ResponseT> setRequest(RequestT request) {
this.request = request;
return this;
}
abstract Builder<RequestT, ResponseT> setRequest(RequestT request);

Builder<RequestT, ResponseT> setApiMethodDescriptor(
ApiMethodDescriptor<RequestT, ResponseT> methodDescriptor) {
this.methodDescriptor = methodDescriptor;
return this;
}
abstract Builder<RequestT, ResponseT> setApiMethodDescriptor(
ApiMethodDescriptor<RequestT, ResponseT> methodDescriptor);

Builder<RequestT, ResponseT> setHttpTransport(HttpTransport httpTransport) {
this.httpTransport = httpTransport;
return this;
}
abstract Builder<RequestT, ResponseT> setHttpTransport(HttpTransport httpTransport);

Builder<RequestT, ResponseT> setEndpoint(String endpoint) {
this.endpoint = endpoint;
return this;
}
abstract Builder<RequestT, ResponseT> setEndpoint(String endpoint);

Builder<RequestT, ResponseT> setJsonFactory(JsonFactory jsonFactory) {
this.jsonFactory = jsonFactory;
return this;
}
abstract Builder<RequestT, ResponseT> setJsonFactory(JsonFactory jsonFactory);

Builder<RequestT, ResponseT> setHeaderEnhancers(List<HttpJsonHeaderEnhancer> headerEnhancers) {
this.headerEnhancers = headerEnhancers;
return this;
}
abstract Builder<RequestT, ResponseT> setHeaderEnhancers(
List<HttpJsonHeaderEnhancer> headerEnhancers);

Builder<RequestT, ResponseT> setApiFuture(SettableApiFuture<ResponseT> responseFuture) {
this.responseFuture = responseFuture;
return this;
}
abstract Builder<RequestT, ResponseT> setResponseFuture(
SettableApiFuture<ResponseT> responseFuture);

HttpRequestRunnable<RequestT, ResponseT> build() {
return new HttpRequestRunnable<>(
callOptions,
request,
methodDescriptor,
httpTransport,
endpoint,
jsonFactory,
headerEnhancers,
responseFuture);
}
abstract HttpRequestRunnable<RequestT, ResponseT> build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public <ResponseT, RequestT> ApiFuture<ResponseT> issueFutureUnaryCall(

HttpRequestRunnable<RequestT, ResponseT> runnable =
HttpRequestRunnable.<RequestT, ResponseT>newBuilder()
.setApiFuture(responseFuture)
.setResponseFuture(responseFuture)
.setApiMethodDescriptor(methodDescriptor)
.setHeaderEnhancers(headerEnhancers)
.setHttpJsonCallOptions(callOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.api.client.http.HttpRequest;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.core.SettableApiFuture;
import com.google.api.pathtemplate.PathTemplate;
import com.google.api.resourcenames.ResourceName;
import com.google.api.resourcenames.ResourceNameFactory;
Expand Down Expand Up @@ -136,6 +137,7 @@ public String getFieldValue(String s) {
.setApiMethodDescriptor(apiMethodDescriptor)
.setHttpTransport(new MockHttpTransport())
.setJsonFactory(new JacksonFactory())
.setResponseFuture(SettableApiFuture.<Void>create())
.build();

HttpRequest httpRequest = httpRequestRunnable.createHttpRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.api.client.http.HttpRequest;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.core.SettableApiFuture;
import com.google.api.gax.httpjson.testing.FakeApiMessage;
import com.google.api.pathtemplate.PathTemplate;
import com.google.auth.Credentials;
Expand Down Expand Up @@ -153,6 +154,7 @@ public String serialize(Void response) {
.setApiMethodDescriptor(methodDescriptor)
.setHttpTransport(new MockHttpTransport())
.setJsonFactory(new JacksonFactory())
.setResponseFuture(SettableApiFuture.<Void>create())

This comment was marked as spam.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The response future should not be nullable.

It seems common in google-cloud-java to have a Void type that represents the response type.

.build();
}

Expand Down