Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into richardm-stripe-cli…
Browse files Browse the repository at this point in the history
…ent-usage
  • Loading branch information
richardm-stripe committed Jan 17, 2024
2 parents 27097f3 + 43c477d commit 67348d7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 41 deletions.
41 changes: 8 additions & 33 deletions src/main/java/com/stripe/net/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
import com.stripe.Stripe;
import com.stripe.exception.ApiConnectionException;
import com.stripe.exception.StripeException;
import com.stripe.util.Stopwatch;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;

/** Base abstract class for HTTP clients used to send requests to Stripe's API. */
Expand All @@ -20,8 +18,6 @@ public abstract class HttpClient {
/** Minimum sleep time between tries to send HTTP requests after network failure. */
public static final Duration minNetworkRetriesDelay = Duration.ofMillis(500);

private final RequestTelemetry requestTelemetry = new RequestTelemetry();

/** A value indicating whether the client should sleep between automatic request retries. */
boolean networkRetriesSleep = true;

Expand Down Expand Up @@ -52,48 +48,27 @@ public StripeResponseStream requestStream(StripeRequest request) throws StripeEx
private interface RequestSendFunction<R> {
R apply(StripeRequest request) throws StripeException;
}

private <T extends AbstractStripeResponse<?>> T sendWithTelemetry(
StripeRequest request, RequestSendFunction<T> send) throws StripeException {
Optional<String> telemetryHeaderValue = requestTelemetry.getHeaderValue(request.headers());
if (telemetryHeaderValue.isPresent()) {
request =
request.withAdditionalHeader(RequestTelemetry.HEADER_NAME, telemetryHeaderValue.get());
}

Stopwatch stopwatch = Stopwatch.startNew();

T response = send.apply(request);

stopwatch.stop();

requestTelemetry.maybeEnqueueMetrics(response, stopwatch.getElapsed(), request.usage());

return response;
}

/**
* Sends the given request to Stripe's API, handling telemetry if not disabled.
*
* @param request the request
* @return the response
* @throws StripeException If the request fails for any reason
* @deprecated Use {@link #request(StripeRequest)} instead.
*/
@Deprecated
public StripeResponse requestWithTelemetry(StripeRequest request) throws StripeException {
return sendWithTelemetry(request, this::request);
return this.request(request);
}

/**
* Sends the given request to Stripe's API, streaming the response, and handling telemetry if not
* disabled.
*
* @param request the request
* @return the response
* @throws StripeException If the request fails for any reason
* @deprecated Use {@link #requestStream(StripeRequest)} instead.
*/
@Deprecated
public StripeResponseStream requestStreamWithTelemetry(StripeRequest request)
throws StripeException {
return sendWithTelemetry(request, this::requestStream);
return this.requestStream(request);
}

public <T extends AbstractStripeResponse<?>> T sendWithRetries(
Expand Down Expand Up @@ -142,7 +117,7 @@ public <T extends AbstractStripeResponse<?>> T sendWithRetries(
* @throws StripeException If the request fails for any reason
*/
public StripeResponse requestWithRetries(StripeRequest request) throws StripeException {
return sendWithRetries(request, (r) -> this.requestWithTelemetry(r));
return sendWithRetries(request, (r) -> this.request(r));
}

/**
Expand All @@ -155,7 +130,7 @@ public StripeResponse requestWithRetries(StripeRequest request) throws StripeExc
*/
public StripeResponseStream requestStreamWithRetries(StripeRequest request)
throws StripeException {
return sendWithRetries(request, (r) -> this.requestStreamWithTelemetry(r));
return sendWithRetries(request, (r) -> this.requestStream(r));
}

/**
Expand Down
51 changes: 43 additions & 8 deletions src/main/java/com/stripe/net/LiveStripeResponseGetter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,40 @@
import com.stripe.exception.oauth.UnsupportedResponseTypeException;
import com.stripe.model.*;
import com.stripe.model.oauth.OAuthError;
import com.stripe.util.Stopwatch;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class LiveStripeResponseGetter implements StripeResponseGetter {
private final HttpClient httpClient;
private final StripeResponseGetterOptions options;

private final RequestTelemetry requestTelemetry = new RequestTelemetry();

@FunctionalInterface
private interface RequestSendFunction<R> {
R apply(StripeRequest request) throws StripeException;
}

private <T extends AbstractStripeResponse<?>> T sendWithTelemetry(
StripeRequest request, List<String> usage, RequestSendFunction<T> send)
throws StripeException {

Stopwatch stopwatch = Stopwatch.startNew();

T response = send.apply(request);

stopwatch.stop();

requestTelemetry.maybeEnqueueMetrics(response, stopwatch.getElapsed(), usage);

return response;
}

/**
* Initializes a new instance of the {@link LiveStripeResponseGetter} class with default
* parameters.
Expand All @@ -46,12 +71,19 @@ public LiveStripeResponseGetter(StripeResponseGetterOptions options, HttpClient
private StripeRequest toStripeRequest(ApiRequest apiRequest) throws StripeException {
String fullUrl = fullUrl(apiRequest);

return new StripeRequest(
apiRequest.getMethod(),
fullUrl,
apiRequest.getParams(),
RequestOptions.merge(this.options, apiRequest.getOptions()),
apiRequest.getUsage());
Optional<String> telemetryHeaderValue = requestTelemetry.pollPayload();
StripeRequest request =
new StripeRequest(
apiRequest.getMethod(),
fullUrl,
apiRequest.getParams(),
RequestOptions.merge(this.options, apiRequest.getOptions()),
apiRequest.getUsage());
if (telemetryHeaderValue.isPresent()) {
request =
request.withAdditionalHeader(RequestTelemetry.HEADER_NAME, telemetryHeaderValue.get());
}
return request;
}

@Override
Expand All @@ -60,7 +92,8 @@ public <T extends StripeObjectInterface> T request(ApiRequest apiRequest, Type t
throws StripeException {

StripeRequest request = toStripeRequest(apiRequest);
StripeResponse response = httpClient.requestWithRetries(request);
StripeResponse response =
sendWithTelemetry(request, apiRequest.getUsage(), r -> httpClient.requestWithRetries(r));

int responseCode = response.code();
String responseBody = response.body();
Expand Down Expand Up @@ -90,7 +123,9 @@ public <T extends StripeObjectInterface> T request(ApiRequest apiRequest, Type t
@Override
public InputStream requestStream(ApiRequest apiRequest) throws StripeException {
StripeRequest request = toStripeRequest(apiRequest);
StripeResponseStream responseStream = httpClient.requestStreamWithRetries(request);
StripeResponseStream responseStream =
sendWithTelemetry(
request, apiRequest.getUsage(), r -> httpClient.requestStreamWithRetries(r));

int responseCode = responseStream.code();

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/stripe/net/RequestTelemetry.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ class RequestTelemetry {
* metrics, or if telemetry is disabled, then the returned {@code Optional} is empty.
*
* @param headers the request headers
* @deprecated Use {$ling {@link #pollPayload()} instead.
*/
@Deprecated
public Optional<String> getHeaderValue(HttpHeaders headers) {
if (headers.firstValue(HEADER_NAME).isPresent()) {
return Optional.empty();
}

return this.pollPayload();
}

public Optional<String> pollPayload() {
RequestMetrics requestMetrics = prevRequestMetrics.poll();
if (requestMetrics == null) {
return Optional.empty();
Expand Down

0 comments on commit 67348d7

Please sign in to comment.