Skip to content
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
64 changes: 64 additions & 0 deletions src/main/java/com/stripe/StripeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.stripe.net.Webhook.Signature;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import lombok.Builder;
import lombok.Getter;

/**
Expand Down Expand Up @@ -41,6 +42,62 @@ protected StripeResponseGetter getResponseGetter() {
return responseGetter;
}

/** Gets the current StripeContext from the client's configuration. Used in unit testing. */
protected String getContext() {
// TODO(major): add getOptions to the StripeResponseGetter interface? that would simplify this
if (!(responseGetter instanceof LiveStripeResponseGetter)) {
return null;
}

LiveStripeResponseGetter liveGetter = (LiveStripeResponseGetter) responseGetter;
StripeResponseGetterOptions options = liveGetter.getOptions();

return options.getStripeContext();
}

/**
* Creates a new StripeClient with the same configuration as this client but with a custom
* StripeContext. This method is useful for creating thread-safe clients with different contexts,
* such as when processing webhooks in parallel where each webhook has its own context.
*
* <p>The new client will share the same configuration (API key, timeouts, proxy settings, etc.)
* and HTTP client as this client, but will have the specified context. This allows for efficient
* parallel processing without reinitializing HTTP connections.
*
* @param context the custom stripe_context to use for the new client
* @return a new StripeClient with the custom context
* @throws IllegalStateException if this client doesn't use a LiveStripeResponseGetter
*/
public StripeClient withStripeContext(StripeContext context) {
// Convert StripeContext to String
String contextString = (context == null) ? null : context.toString();

StripeResponseGetter responseGetter = this.getResponseGetter();

// We can only create a new client for LiveStripeResponseGetter because it's the only class with
// `getOptions()`. If we add that method to the interface in a later major, we could remove this
// check.
if (!(responseGetter instanceof LiveStripeResponseGetter)) {
throw new IllegalStateException(
"Cannot create a client with custom context for non-Live response getters");
}

LiveStripeResponseGetter liveGetter = (LiveStripeResponseGetter) responseGetter;

// Create a new LiveStripeResponseGetter with updated context, reusing the HTTP client
LiveStripeResponseGetter newResponseGetter =
liveGetter.withNewOptions(
options -> {
ClientStripeResponseGetterOptions existingOptions =
(ClientStripeResponseGetterOptions) options;

return existingOptions.toBuilder().stripeContext(contextString).build();
});

// Create and return a new StripeClient with the new response getter
return new StripeClient(newResponseGetter);
}

/**
* Returns an StripeEvent instance using the provided JSON payload. Throws a JsonSyntaxException
* if the payload is not valid JSON, and a SignatureVerificationException if the signature
Expand Down Expand Up @@ -1116,6 +1173,8 @@ public com.stripe.service.WebhookEndpointService webhookEndpoints() {
}

// The end of the section generated from our OpenAPI spec
@SuppressWarnings("ObjectToString")
@Builder(toBuilder = true)
static class ClientStripeResponseGetterOptions extends StripeResponseGetterOptions {
// When adding setting here keep them in sync with settings in RequestOptions and
// in the RequestOptions.merge method
Expand Down Expand Up @@ -1521,4 +1580,9 @@ public StripeResponse rawRequest(
public StripeObject deserialize(String rawJson, ApiMode apiMode) throws StripeException {
return StripeObject.deserializeStripeObject(rawJson, this.getResponseGetter(), apiMode);
}

public StripeEventNotificationHandler notificationHandler(
String webhookSecret, StripeEventNotificationHandler.FallbackCallback fallbackCallback) {
return new StripeEventNotificationHandler(webhookSecret, this, fallbackCallback);
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/stripe/StripeContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public StripeContext pop() {
/**
* Converts the context to a string by joining segments with '/'.
*
* @return string representation of the context segments joined by '/', `null` if there are no
* segments (useful for clearing context)
* @return string representation of the context segments joined by '/'. If there are no segments,
* returns an empty string (useful for clearing context).
*/
@Override
public String toString() {
Expand Down
Loading
Loading