Skip to content

Commit 2bdec26

Browse files
⚠️ Make RequestOptions & RawRequestOptions constructors private and add Stripe-Request-Trigger header (#2172)
* add "prepare" to justfile * add Stripe-Request-Trigger header * Simplify builders * Use additionalHeaders directly in RawRequestOptions * regenerate * add comment about broken test * make constuctors private
1 parent 409eb1e commit 2bdec26

7 files changed

Lines changed: 131 additions & 111 deletions

File tree

justfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import? '../sdk-codegen/utils.just'
55
_default:
66
just --list --unsorted
77

8+
# ⭐ run format and tests to prepare for CI
9+
[no-exit-message]
10+
prepare: format test
11+
812
# ⭐ run the whole test suite
913
[no-exit-message]
1014
test *args:

src/main/java/com/stripe/model/v2/core/Event.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ protected StripeObject fetchRelatedObject(RelatedObject relatedObject) throws St
9999
}
100100

101101
RequestOptions.RequestOptionsBuilder optsBuilder = new RequestOptions.RequestOptionsBuilder();
102-
// optsBuilder.setStripeRequestTrigger("event=" + id); // TODO https://go/j/DEVSDK-3018
102+
optsBuilder.setStripeRequestTrigger("event=" + id);
103103

104104
if (context != null) {
105105
optsBuilder.setStripeAccount(context);

src/main/java/com/stripe/model/v2/core/EventNotification.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,12 @@ public static EventNotification fromJson(String payload, StripeClient client) {
106106
}
107107

108108
private RawRequestOptions getRequestOptions() {
109-
if (context == null) {
110-
return null;
109+
RawRequestOptions.RawRequestOptionsBuilder builder =
110+
RawRequestOptions.builder().setStripeRequestTrigger("event=" + id);
111+
if (context != null) {
112+
builder.setStripeContext(context.toString());
111113
}
112-
return new RawRequestOptions.RawRequestOptionsBuilder()
113-
.setStripeContext(context.toString())
114-
.build();
114+
return builder.build();
115115
}
116116

117117
/* retrieves the full payload for an event. Protected because individual push classes use it, but type it correctly */

src/main/java/com/stripe/net/RawRequestOptions.java

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,9 @@
88
public class RawRequestOptions extends RequestOptions {
99
private Map<String, String> additionalHeaders;
1010

11-
public RawRequestOptions(
12-
Authenticator authenticator,
13-
String clientId,
14-
String idempotencyKey,
15-
String stripeContext,
16-
String stripeAccount,
17-
String stripeVersionOverride,
18-
String baseUrl,
19-
Integer connectTimeout,
20-
Integer readTimeout,
21-
Integer maxNetworkRetries,
22-
Proxy connectionProxy,
23-
PasswordAuthentication proxyCredential,
24-
Map<String, String> additionalHeaders) {
25-
super(
26-
authenticator,
27-
clientId,
28-
idempotencyKey,
29-
stripeContext,
30-
stripeAccount,
31-
stripeVersionOverride,
32-
baseUrl,
33-
connectTimeout,
34-
readTimeout,
35-
maxNetworkRetries,
36-
connectionProxy,
37-
proxyCredential);
38-
this.additionalHeaders = additionalHeaders;
11+
private RawRequestOptions(RawRequestOptionsBuilder builder) {
12+
super(builder);
13+
this.additionalHeaders = builder.additionalHeaders;
3914
}
4015

4116
public Map<String, String> getAdditionalHeaders() {
@@ -88,6 +63,12 @@ public RawRequestOptionsBuilder setStripeContext(StripeContext stripeContext) {
8863
return this;
8964
}
9065

66+
@Override
67+
public RawRequestOptionsBuilder setStripeRequestTrigger(String stripeRequestTrigger) {
68+
super.setStripeRequestTrigger(stripeRequestTrigger);
69+
return this;
70+
}
71+
9172
@Override
9273
public RawRequestOptionsBuilder setStripeAccount(String stripeAccount) {
9374
super.setStripeAccount(stripeAccount);
@@ -132,20 +113,7 @@ public RawRequestOptionsBuilder setProxyCredential(PasswordAuthentication proxyC
132113

133114
@Override
134115
public RawRequestOptions build() {
135-
return new RawRequestOptions(
136-
authenticator,
137-
normalizeClientId(this.clientId),
138-
normalizeIdempotencyKey(this.idempotencyKey),
139-
normalizeStripeContext(this.stripeContext),
140-
normalizeStripeAccount(this.stripeAccount),
141-
normalizeStripeVersion(this.stripeVersionOverride),
142-
normalizeBaseUrl(this.baseUrl),
143-
connectTimeout,
144-
readTimeout,
145-
maxNetworkRetries,
146-
connectionProxy,
147-
proxyCredential,
148-
additionalHeaders);
116+
return new RawRequestOptions(this);
149117
}
150118
}
151119
}

src/main/java/com/stripe/net/RequestOptions.java

Lines changed: 89 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class RequestOptions {
1313
private final Authenticator authenticator;
1414
private final String clientId;
1515
private final String stripeContext;
16+
private final String stripeRequestTrigger;
1617
private final String idempotencyKey;
1718
private final String stripeAccount;
1819
private final String baseUrl;
@@ -31,15 +32,15 @@ public class RequestOptions {
3132
private final PasswordAuthentication proxyCredential;
3233

3334
public static RequestOptions getDefault() {
34-
return new RequestOptions(
35-
null, null, null, null, null, null, null, null, null, null, null, null);
35+
return new RequestOptionsBuilder().build();
3636
}
3737

38-
protected RequestOptions(
38+
private RequestOptions(
3939
Authenticator authenticator,
4040
String clientId,
4141
String idempotencyKey,
4242
String stripeContext,
43+
String stripeRequestTrigger,
4344
String stripeAccount,
4445
String stripeVersionOverride,
4546
String baseUrl,
@@ -52,6 +53,7 @@ protected RequestOptions(
5253
this.clientId = clientId;
5354
this.idempotencyKey = idempotencyKey;
5455
this.stripeContext = stripeContext;
56+
this.stripeRequestTrigger = stripeRequestTrigger;
5557
this.stripeAccount = stripeAccount;
5658
this.stripeVersionOverride = stripeVersionOverride;
5759
this.baseUrl = baseUrl;
@@ -62,6 +64,23 @@ protected RequestOptions(
6264
this.proxyCredential = proxyCredential;
6365
}
6466

67+
RequestOptions(RequestOptionsBuilder builder) {
68+
this(
69+
builder.authenticator,
70+
normalizeClientId(builder.clientId),
71+
normalizeIdempotencyKey(builder.idempotencyKey),
72+
builder.stripeContext,
73+
builder.stripeRequestTrigger,
74+
normalizeStripeAccount(builder.stripeAccount),
75+
normalizeStripeVersion(builder.stripeVersionOverride),
76+
normalizeBaseUrl(builder.baseUrl),
77+
builder.connectTimeout,
78+
builder.readTimeout,
79+
builder.maxNetworkRetries,
80+
builder.connectionProxy,
81+
builder.proxyCredential);
82+
}
83+
6584
public Authenticator getAuthenticator() {
6685
return this.authenticator;
6786
}
@@ -82,6 +101,10 @@ public String getStripeContext() {
82101
return stripeContext;
83102
}
84103

104+
public String getStripeRequestTrigger() {
105+
return stripeRequestTrigger;
106+
}
107+
85108
public String getIdempotencyKey() {
86109
return idempotencyKey;
87110
}
@@ -153,6 +176,7 @@ public RequestOptionsBuilder toBuilderFullCopy() {
153176
.setClientId(this.clientId)
154177
.setIdempotencyKey(this.idempotencyKey)
155178
.setStripeAccount(this.stripeAccount)
179+
.setStripeRequestTrigger(this.stripeRequestTrigger)
156180
.setConnectTimeout(this.connectTimeout)
157181
.setReadTimeout(this.readTimeout)
158182
.setMaxNetworkRetries(this.maxNetworkRetries)
@@ -166,6 +190,7 @@ public static class RequestOptionsBuilder {
166190
protected String clientId;
167191
protected String idempotencyKey;
168192
protected String stripeContext;
193+
protected String stripeRequestTrigger;
169194
protected String stripeAccount;
170195
protected String stripeVersionOverride;
171196
protected Integer connectTimeout;
@@ -251,6 +276,15 @@ public RequestOptionsBuilder clearStripeContext() {
251276
return this;
252277
}
253278

279+
public String getStripeRequestTrigger() {
280+
return stripeRequestTrigger;
281+
}
282+
283+
public RequestOptionsBuilder setStripeRequestTrigger(String stripeRequestTrigger) {
284+
this.stripeRequestTrigger = stripeRequestTrigger;
285+
return this;
286+
}
287+
254288
public RequestOptionsBuilder setIdempotencyKey(String idempotencyKey) {
255289
this.idempotencyKey = idempotencyKey;
256290
return this;
@@ -366,19 +400,7 @@ public RequestOptionsBuilder setBaseUrl(final String baseUrl) {
366400

367401
/** Constructs a {@link RequestOptions} with the specified values. */
368402
public RequestOptions build() {
369-
return new RequestOptions(
370-
this.authenticator,
371-
normalizeClientId(this.clientId),
372-
normalizeIdempotencyKey(this.idempotencyKey),
373-
stripeContext,
374-
normalizeStripeAccount(this.stripeAccount),
375-
normalizeStripeVersion(this.stripeVersionOverride),
376-
normalizeBaseUrl(this.baseUrl),
377-
connectTimeout,
378-
readTimeout,
379-
maxNetworkRetries,
380-
connectionProxy,
381-
proxyCredential);
403+
return new RequestOptions(this);
382404
}
383405
}
384406

@@ -468,20 +490,17 @@ protected static String normalizeStripeAccount(String stripeAccount) {
468490

469491
static RequestOptions merge(StripeResponseGetterOptions clientOptions, RequestOptions options) {
470492
if (options == null) {
471-
return new RequestOptions(
472-
clientOptions.getAuthenticator(), // authenticator
473-
clientOptions.getClientId(), // clientId
474-
null, // idempotencyKey
475-
clientOptions.getStripeContext(), // stripeContext
476-
clientOptions.getStripeAccount(), // stripeAccount
477-
null, // stripeVersionOverride
478-
null, // baseUrl
479-
clientOptions.getConnectTimeout(), // connectTimeout
480-
clientOptions.getReadTimeout(), // readTimeout
481-
clientOptions.getMaxNetworkRetries(), // maxNetworkRetries
482-
clientOptions.getConnectionProxy(), // connectionProxy
483-
clientOptions.getProxyCredential() // proxyCredential
484-
);
493+
return new RequestOptionsBuilder()
494+
.setAuthenticator(clientOptions.getAuthenticator())
495+
.setClientId(clientOptions.getClientId())
496+
.setStripeContext(clientOptions.getStripeContext())
497+
.setStripeAccount(clientOptions.getStripeAccount())
498+
.setConnectTimeout(clientOptions.getConnectTimeout())
499+
.setReadTimeout(clientOptions.getReadTimeout())
500+
.setMaxNetworkRetries(clientOptions.getMaxNetworkRetries())
501+
.setConnectionProxy(clientOptions.getConnectionProxy())
502+
.setProxyCredential(clientOptions.getProxyCredential())
503+
.build();
485504
}
486505

487506
// callers need to be able to explicitly unset context per-request
@@ -498,33 +517,46 @@ static RequestOptions merge(StripeResponseGetterOptions clientOptions, RequestOp
498517
} else {
499518
stripeContext = clientOptions.getStripeContext();
500519
}
501-
return new RequestOptions(
502-
options.getAuthenticator() != null
503-
? options.getAuthenticator()
504-
: clientOptions.getAuthenticator(),
505-
options.getClientId() != null ? options.getClientId() : clientOptions.getClientId(),
506-
options.getIdempotencyKey(),
507-
stripeContext,
508-
options.getStripeAccount() != null
509-
? options.getStripeAccount()
510-
: clientOptions.getStripeAccount(),
511-
RequestOptions.unsafeGetStripeVersionOverride(options),
512-
options.getBaseUrl(),
513-
options.getConnectTimeout() != null
514-
? options.getConnectTimeout()
515-
: clientOptions.getConnectTimeout(),
516-
options.getReadTimeout() != null
517-
? options.getReadTimeout()
518-
: clientOptions.getReadTimeout(),
519-
options.getMaxNetworkRetries() != null
520-
? options.getMaxNetworkRetries()
521-
: clientOptions.getMaxNetworkRetries(),
522-
options.getConnectionProxy() != null
523-
? options.getConnectionProxy()
524-
: clientOptions.getConnectionProxy(),
525-
options.getProxyCredential() != null
526-
? options.getProxyCredential()
527-
: clientOptions.getProxyCredential());
520+
521+
return RequestOptionsBuilder.unsafeSetStripeVersionOverride(
522+
new RequestOptionsBuilder()
523+
.setAuthenticator(
524+
options.getAuthenticator() != null
525+
? options.getAuthenticator()
526+
: clientOptions.getAuthenticator())
527+
.setClientId(
528+
options.getClientId() != null
529+
? options.getClientId()
530+
: clientOptions.getClientId())
531+
.setIdempotencyKey(options.getIdempotencyKey())
532+
.setStripeContext(stripeContext)
533+
.setStripeRequestTrigger(options.getStripeRequestTrigger())
534+
.setStripeAccount(
535+
options.getStripeAccount() != null
536+
? options.getStripeAccount()
537+
: clientOptions.getStripeAccount())
538+
.setConnectTimeout(
539+
options.getConnectTimeout() != null
540+
? options.getConnectTimeout()
541+
: clientOptions.getConnectTimeout())
542+
.setReadTimeout(
543+
options.getReadTimeout() != null
544+
? options.getReadTimeout()
545+
: clientOptions.getReadTimeout())
546+
.setMaxNetworkRetries(
547+
options.getMaxNetworkRetries() != null
548+
? options.getMaxNetworkRetries()
549+
: clientOptions.getMaxNetworkRetries())
550+
.setConnectionProxy(
551+
options.getConnectionProxy() != null
552+
? options.getConnectionProxy()
553+
: clientOptions.getConnectionProxy())
554+
.setProxyCredential(
555+
options.getProxyCredential() != null
556+
? options.getProxyCredential()
557+
: clientOptions.getProxyCredential()),
558+
RequestOptions.unsafeGetStripeVersionOverride(options))
559+
.build();
528560
}
529561

530562
public static class InvalidRequestOptionsException extends RuntimeException {

src/main/java/com/stripe/net/StripeRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ private static HttpHeaders buildHeaders(
321321
headerMap.put("Stripe-Context", Arrays.asList(options.getStripeContext()));
322322
}
323323

324+
// Stripe-Request-Trigger
325+
if (options.getStripeRequestTrigger() != null) {
326+
headerMap.put("Stripe-Request-Trigger", Arrays.asList(options.getStripeRequestTrigger()));
327+
}
328+
324329
// Stripe-Account
325330
if (options.getStripeAccount() != null) {
326331
headerMap.put("Stripe-Account", Arrays.asList(options.getStripeAccount()));

src/test/java/com/stripe/model/v2/EventTests.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88
import com.stripe.model.billing.Meter;
99
import com.stripe.model.v2.core.Event;
1010
import com.stripe.net.ApiResource;
11+
import com.stripe.net.HttpHeaders;
12+
import com.stripe.net.StripeResponse;
1113
import java.io.IOException;
1214
import java.time.Instant;
15+
import java.util.Collections;
1316
import org.junit.jupiter.api.BeforeEach;
1417
import org.junit.jupiter.api.Test;
18+
import org.mockito.Mockito;
19+
import org.mockito.stubbing.Answer;
1520

1621
public class EventTests extends BaseStripeTest {
1722
public static String v2PayloadNoData = null;
@@ -115,12 +120,13 @@ public void retrieveObjectFetchesAndDeserializesObject() throws StripeException,
115120
V1BillingMeterErrorReportTriggeredEvent event =
116121
(V1BillingMeterErrorReportTriggeredEvent) Event.parse(v2PayloadNoData);
117122
event.setResponseGetter(networkSpy);
118-
stubRequest(
119-
ApiResource.RequestMethod.GET,
120-
"/v1/billing/meters/meter_123",
121-
null,
122-
Meter.class,
123-
getResourceAsString("/api_fixtures/billing_meter.json"));
123+
String fixtureJson = getResourceAsString("/api_fixtures/billing_meter.json");
124+
Mockito.doAnswer(
125+
(Answer<StripeResponse>)
126+
invocation ->
127+
new StripeResponse(200, HttpHeaders.of(Collections.emptyMap()), fixtureJson))
128+
.when(httpClientSpy)
129+
.request(Mockito.any());
124130

125131
assertEquals("/v1/billing/meters/meter_123", event.getRelatedObject().getUrl());
126132
assertEquals("meter_123", event.getRelatedObject().getId());
@@ -141,6 +147,11 @@ public void retrieveObjectFetchesAndDeserializesObject() throws StripeException,
141147
assertEquals("active", meter.getStatus());
142148
assertNull(meter.getStatusTransitions().getDeactivatedAt());
143149
assertEquals(1727303036, meter.getUpdated());
150+
151+
verifyStripeRequest(
152+
req ->
153+
assertEquals(
154+
"event=evt_234", req.headers().firstValue("Stripe-Request-Trigger").orElse(null)));
144155
}
145156

146157
// FIXME (jar) this should no longer be possible; confirm this and remove before merge

0 commit comments

Comments
 (0)