Skip to content

Commit

Permalink
Use abstract class
Browse files Browse the repository at this point in the history
  • Loading branch information
richardm-stripe committed Jun 7, 2021
1 parent 20dea96 commit 001fdc0
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 195 deletions.
85 changes: 85 additions & 0 deletions src/main/java/com/stripe/net/AbstractStripeResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.stripe.net;

import static java.util.Objects.requireNonNull;

import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.experimental.NonFinal;

/** Common interface representing an HTTP response from Stripe. */
@Accessors(fluent = true)
abstract class AbstractStripeResponse<T> {
/** The HTTP status code of the response. */
int code;

/** The HTTP headers of the response. */
HttpHeaders headers;

/** The body of the response. */
T body;

public final int code() {
return this.code;
}

public final HttpHeaders headers() {
return this.headers;
}

public final T body() {
return this.body;
}


/** Number of times the request was retried. Used for internal tests only. */
@NonFinal
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
int numRetries;

/**
* Gets the date of the request, as returned by Stripe.
*
* @return the date of the request, as returned by Stripe
*/
public Instant date() {
Optional<String> dateStr = this.headers.firstValue("Date");
if (!dateStr.isPresent()) {
return null;
}
return ZonedDateTime.parse(dateStr.get(), DateTimeFormatter.RFC_1123_DATE_TIME).toInstant();
}

/**
* Gets the idempotency key of the request, as returned by Stripe.
*
* @return the idempotency key of the request, as returned by Stripe
*/
public String idempotencyKey() {
return this.headers.firstValue("Idempotency-Key").orElse(null);
}

/**
* Gets the ID of the request, as returned by Stripe.
*
* @return the ID of the request, as returned by Stripe
*/
public String requestId() {
return this.headers.firstValue("Request-Id").orElse(null);
}

protected AbstractStripeResponse(int code, HttpHeaders headers, T body) {
requireNonNull(headers);
requireNonNull(body);

this.code = code;
this.headers = headers;
this.body = body;
}
}
12 changes: 6 additions & 6 deletions src/main/java/com/stripe/net/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ protected HttpClient() {}
*/
public StripeResponseStream requestStream(StripeRequest request) throws StripeException {
throw new UnsupportedOperationException(
"streamingRequest is unimplemented for this HttpClient");
"requestStream is unimplemented for this HttpClient");
}

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

private <T extends StripeResponseInterface> T sendWithTelemetry(
private <T extends AbstractStripeResponse<?>> T sendWithTelemetry(
StripeRequest request, RequestSendFunction<T> send) throws StripeException {
Optional<String> telemetryHeaderValue = requestTelemetry.getHeaderValue(request.headers());
if (telemetryHeaderValue.isPresent()) {
Expand All @@ -81,7 +81,7 @@ private <T extends StripeResponseInterface> T sendWithTelemetry(
* @throws StripeException If the request fails for any reason
*/
public StripeResponse requestWithTelemetry(StripeRequest request) throws StripeException {
return sendWithTelemetry(request, (r) -> this.request(r));
return sendWithTelemetry(request, this::request);
}

/**
Expand All @@ -94,10 +94,10 @@ public StripeResponse requestWithTelemetry(StripeRequest request) throws StripeE
*/
public StripeResponseStream requestStreamWithTelemetry(StripeRequest request)
throws StripeException {
return sendWithTelemetry(request, (r) -> this.requestStream(r));
return sendWithTelemetry(request, this::requestStream);
}

public <T extends StripeResponseInterface> T sendWithRetries(
public <T extends AbstractStripeResponse<?>> T sendWithRetries(
StripeRequest request, RequestSendFunction<T> send) throws StripeException {
ApiConnectionException requestException = null;
T response = null;
Expand Down Expand Up @@ -218,7 +218,7 @@ private static String formatAppInfo(Map<String, String> info) {
return str;
}

private <T extends StripeResponseInterface> boolean shouldRetry(
private <T extends AbstractStripeResponse<?>> boolean shouldRetry(
int numRetries, StripeException exception, StripeRequest request, T response) {
// Do not retry if we are out of retries.
if (numRetries >= request.options().getMaxNetworkRetries()) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/stripe/net/LiveStripeResponseGetter.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public InputStream requestStream(
handleApiError(response);
}

return responseStream.bodyStream();
return responseStream.body();
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/stripe/net/RequestTelemetry.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public Optional<String> getHeaderValue(HttpHeaders headers) {
* @param response the Stripe response
* @param duration the request duration
*/
public void maybeEnqueueMetrics(StripeResponseInterface response, Duration duration) {
public void maybeEnqueueMetrics(AbstractStripeResponse<?> response, Duration duration) {
if (!Stripe.enableTelemetry) {
return;
}
Expand Down
74 changes: 2 additions & 72 deletions src/main/java/com/stripe/net/StripeResponse.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,7 @@
package com.stripe.net;

import static java.util.Objects.requireNonNull;

import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import lombok.Getter;
import lombok.Setter;
import lombok.Value;
import lombok.experimental.Accessors;
import lombok.experimental.NonFinal;

/** A response from Stripe's API, with body represented as a String. */
@Value
@Accessors(fluent = true)
public class StripeResponse implements StripeResponseInterface {
/** The HTTP status code of the response. */
@Getter(onMethod_ = {@Override})
int code;

/** The HTTP headers of the response. */
@Getter(onMethod_ = {@Override})
HttpHeaders headers;

/** The body of the response. */
String body;

/** Number of times the request was retried. Used for internal tests only. */
@NonFinal
@Getter(onMethod_ = {@Override})
@Setter(onMethod_ = {@Override})
int numRetries;

public class StripeResponse extends AbstractStripeResponse<String> {
/**
* Initializes a new instance of the {@link StripeResponse} class.
*
Expand All @@ -42,45 +11,6 @@ public class StripeResponse implements StripeResponseInterface {
* @throws NullPointerException if {@code headers} or {@code body} is {@code null}
*/
public StripeResponse(int code, HttpHeaders headers, String body) {
requireNonNull(headers);
requireNonNull(body);

this.code = code;
this.headers = headers;
this.body = body;
}

/**
* Gets the date of the request, as returned by Stripe.
*
* @return the date of the request, as returned by Stripe
*/
@Override
public Instant date() {
Optional<String> dateStr = this.headers.firstValue("Date");
if (!dateStr.isPresent()) {
return null;
}
return ZonedDateTime.parse(dateStr.get(), DateTimeFormatter.RFC_1123_DATE_TIME).toInstant();
}

/**
* Gets the idempotency key of the request, as returned by Stripe.
*
* @return the idempotency key of the request, as returned by Stripe
*/
@Override
public String idempotencyKey() {
return this.headers.firstValue("Idempotency-Key").orElse(null);
}

/**
* Gets the ID of the request, as returned by Stripe.
*
* @return the ID of the request, as returned by Stripe
*/
@Override
public String requestId() {
return this.headers.firstValue("Request-Id").orElse(null);
super(code, headers, body);
}
}
37 changes: 0 additions & 37 deletions src/main/java/com/stripe/net/StripeResponseInterface.java

This file was deleted.

83 changes: 5 additions & 78 deletions src/main/java/com/stripe/net/StripeResponseStream.java
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
package com.stripe.net;

import static java.util.Objects.requireNonNull;

import com.stripe.util.StreamUtils;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.Value;
import lombok.experimental.Accessors;
import lombok.experimental.NonFinal;

/** A response from Stripe's API, with a body represented as an InputStream. */
@Value
@Accessors(fluent = true)
public class StripeResponseStream implements StripeResponseInterface {
/** The HTTP status code of the response. */
@Getter(onMethod_ = {@Override})
int code;

/** The HTTP headers of the response. */
@Getter(onMethod_ = {@Override})
HttpHeaders headers;

/** The body of the response. */
@NonFinal
@Getter(AccessLevel.PACKAGE)
InputStream bodyStream;

/** Number of times the request was retried. Used for internal tests only. */
@NonFinal
@Getter(onMethod_ = {@Override})
@Setter(onMethod_ = {@Override})
int numRetries;

public class StripeResponseStream extends AbstractStripeResponse<InputStream> {
/**
* Initializes a new instance of the {@link StripeResponseStream} class.
*
Expand All @@ -47,13 +13,8 @@ public class StripeResponseStream implements StripeResponseInterface {
* @param bodyStream streaming body response
* @throws NullPointerException if {@code headers} or {@code body} is {@code null}
*/
public StripeResponseStream(int code, HttpHeaders headers, InputStream bodyStream) {
requireNonNull(headers);
requireNonNull(bodyStream);

this.code = code;
this.headers = headers;
this.bodyStream = bodyStream;
public StripeResponseStream(int code, HttpHeaders headers, InputStream body) {
super(code, headers, body);
}

/**
Expand All @@ -62,42 +23,8 @@ public StripeResponseStream(int code, HttpHeaders headers, InputStream bodyStrea
* @return the StripeResponse
*/
public StripeResponse unstream() throws IOException {
final String bodyString = StreamUtils.readToEnd(this.bodyStream, ApiResource.CHARSET);
this.bodyStream.close();
final String bodyString = StreamUtils.readToEnd(this.body, ApiResource.CHARSET);
this.body.close();
return new StripeResponse(this.code, this.headers, bodyString);
}

/**
* Gets the date of the request, as returned by Stripe.
*
* @return the date of the request, as returned by Stripe
*/
@Override
public Instant date() {
Optional<String> dateStr = this.headers.firstValue("Date");
if (!dateStr.isPresent()) {
return null;
}
return ZonedDateTime.parse(dateStr.get(), DateTimeFormatter.RFC_1123_DATE_TIME).toInstant();
}

/**
* Gets the idempotency key of the request, as returned by Stripe.
*
* @return the idempotency key of the request, as returned by Stripe
*/
@Override
public String idempotencyKey() {
return this.headers.firstValue("Idempotency-Key").orElse(null);
}

/**
* Gets the ID of the request, as returned by Stripe.
*
* @return the ID of the request, as returned by Stripe
*/
@Override
public String requestId() {
return this.headers.firstValue("Request-Id").orElse(null);
}
}

0 comments on commit 001fdc0

Please sign in to comment.