Skip to content

Commit 467149e

Browse files
pareshgooglerhgoogle
authored andcommitted
feat: add X-Goog-Request-Reason header support
1 parent b1a933a commit 467149e

3 files changed

Lines changed: 81 additions & 26 deletions

File tree

src/main/java/net/starschema/clouddb/jdbc/BQConnection.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ public BQConnection(String url, Properties loginProp, HttpTransport httpTranspor
246246
// extract UA String
247247
String userAgent = caseInsensitiveProps.getProperty("useragent");
248248

249+
// extract requestReason property
250+
String requestReason = caseInsensitiveProps.getProperty("requestreason");
251+
249252
// extract any labels
250253
this.labels = tryParseLabels(caseInsensitiveProps.getProperty("labels"));
251254
// extract custom endpoint for connections through restricted VPC
@@ -287,7 +290,8 @@ public BQConnection(String url, Properties loginProp, HttpTransport httpTranspor
287290
rootUrl,
288291
httpTransport,
289292
targetServiceAccounts,
290-
this.getProjectId());
293+
this.getProjectId(),
294+
requestReason);
291295
this.logger.info("Authorized with service account");
292296
} catch (GeneralSecurityException e) {
293297
throw new BQSQLException(e);
@@ -305,7 +309,8 @@ public BQConnection(String url, Properties loginProp, HttpTransport httpTranspor
305309
rootUrl,
306310
httpTransport,
307311
targetServiceAccounts,
308-
this.getProjectId());
312+
this.getProjectId(),
313+
requestReason);
309314
this.logger.info("Authorized with OAuth access token");
310315
} catch (SQLException e) {
311316
throw new BQSQLException(e);
@@ -320,7 +325,8 @@ public BQConnection(String url, Properties loginProp, HttpTransport httpTranspor
320325
rootUrl,
321326
httpTransport,
322327
targetServiceAccounts,
323-
this.getProjectId());
328+
this.getProjectId(),
329+
requestReason);
324330
} catch (IOException e) {
325331
throw new BQSQLException(e);
326332
}

src/main/java/net/starschema/clouddb/jdbc/Oauth2Bigquery.java

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
*/
2323
package net.starschema.clouddb.jdbc;
2424

25-
import com.google.api.client.http.HttpHeaders;
2625
import com.google.api.client.http.HttpRequest;
2726
import com.google.api.client.http.HttpResponse;
2827
import com.google.api.client.http.HttpTransport;
@@ -31,7 +30,6 @@
3130
import com.google.api.client.json.gson.GsonFactory;
3231
import com.google.api.services.bigquery.Bigquery;
3332
import com.google.api.services.bigquery.Bigquery.Builder;
34-
import com.google.api.services.bigquery.BigqueryRequest;
3533
import com.google.api.services.bigquery.BigqueryRequestInitializer;
3634
import com.google.api.services.bigquery.BigqueryScopes;
3735
import com.google.api.services.bigquery.MinifiedBigquery;
@@ -101,13 +99,15 @@ private static Bigquery.Builder createBqBuilderForCredential(
10199
String rootUrl,
102100
List<String> targetServiceAccounts,
103101
@Nullable String oauthToken,
104-
@Nullable String projectId) {
102+
@Nullable String projectId,
103+
@Nullable String requestReason) {
105104

106105
// If targetServiceAccounts is empty this returns the original credential
107106
credential = impersonateServiceAccount(credential, targetServiceAccounts, projectId);
108107

109108
HttpRequestTimeoutInitializer httpRequestInitializer =
110-
createRequestTimeoutInitalizer(credential, connectTimeout, readTimeout);
109+
createRequestTimeoutInitalizer(
110+
credential, connectTimeout, readTimeout, requestReason, userAgent);
111111

112112
Bigquery.Builder bqBuilder =
113113
new Builder(httpTransport, JSON_FACTORY, httpRequestInitializer)
@@ -140,7 +140,11 @@ private static Bigquery.Builder createBqBuilderForCredential(
140140
* @return HttpRequestTimeoutInitializer suitable for use with Bigquery.Builder
141141
*/
142142
private static HttpRequestTimeoutInitializer createRequestTimeoutInitalizer(
143-
GoogleCredentials credential, Integer connectTimeout, Integer readTimeout) {
143+
GoogleCredentials credential,
144+
Integer connectTimeout,
145+
Integer readTimeout,
146+
String requestReason,
147+
String userAgent) {
144148
HttpRequestTimeoutInitializer httpRequestInitializer =
145149
new HttpRequestTimeoutInitializer(credential);
146150
if (connectTimeout != null) {
@@ -149,6 +153,12 @@ private static HttpRequestTimeoutInitializer createRequestTimeoutInitalizer(
149153
if (readTimeout != null) {
150154
httpRequestInitializer.setReadTimeout(readTimeout);
151155
}
156+
if (requestReason != null) {
157+
httpRequestInitializer.setRequestReason(requestReason);
158+
}
159+
if (userAgent != null) {
160+
httpRequestInitializer.setUserAgent(userAgent);
161+
}
152162

153163
return httpRequestInitializer;
154164
}
@@ -168,7 +178,8 @@ public static Bigquery authorizeViaToken(
168178
String rootUrl,
169179
HttpTransport httpTransport,
170180
List<String> targetServiceAccounts,
171-
String projectId)
181+
String projectId,
182+
String requestReason)
172183
throws SQLException {
173184
GoogleCredentials credential =
174185
GoogleCredentials.create(new AccessToken(oauthToken, null))
@@ -186,7 +197,8 @@ public static Bigquery authorizeViaToken(
186197
rootUrl,
187198
targetServiceAccounts,
188199
oauthToken,
189-
projectId);
200+
projectId,
201+
requestReason);
190202

191203
return new MinifiedBigquery(bqBuilder);
192204
}
@@ -279,7 +291,8 @@ public static Bigquery authorizeViaService(
279291
String rootUrl,
280292
HttpTransport httpTransport,
281293
List<String> targetServiceAccounts,
282-
String projectId)
294+
String projectId,
295+
String requestReason)
283296
throws GeneralSecurityException, IOException {
284297
GoogleCredentials credential =
285298
createServiceAccountCredential(
@@ -297,7 +310,8 @@ public static Bigquery authorizeViaService(
297310
rootUrl,
298311
targetServiceAccounts,
299312
/* oauthToken= */ null,
300-
projectId);
313+
projectId,
314+
requestReason);
301315

302316
return new MinifiedBigquery(bqBuilder);
303317
}
@@ -333,7 +347,8 @@ public static Bigquery authorizeViaApplicationDefault(
333347
String rootUrl,
334348
HttpTransport httpTransport,
335349
List<String> targetServiceAccounts,
336-
String projectId)
350+
String projectId,
351+
String requestReason)
337352
throws IOException {
338353
GoogleCredentials credential =
339354
GoogleCredentials.getApplicationDefault().createScoped(GenerateScopes(false));
@@ -350,7 +365,8 @@ public static Bigquery authorizeViaApplicationDefault(
350365
rootUrl,
351366
targetServiceAccounts,
352367
/* oauthToken= */ null,
353-
projectId);
368+
projectId,
369+
requestReason);
354370

355371
return new MinifiedBigquery(bqBuilder);
356372
}
@@ -459,9 +475,11 @@ private static PrivateKey getPrivateKeyFromCredentials(String keyPath, String pa
459475
return (PrivateKey) keystore.getKey(keystore.aliases().nextElement(), password.toCharArray());
460476
}
461477

462-
private static class HttpRequestTimeoutInitializer extends HttpCredentialsAdapter {
478+
static class HttpRequestTimeoutInitializer extends HttpCredentialsAdapter {
463479
private Integer readTimeout = null;
464480
private Integer connectTimeout = null;
481+
private String requestReason = null;
482+
private String userAgent = null;
465483

466484
public HttpRequestTimeoutInitializer(GoogleCredentials credential) {
467485
super(credential);
@@ -475,6 +493,18 @@ public void setConnectTimeout(Integer timeout) {
475493
connectTimeout = timeout;
476494
}
477495

496+
public void setRequestReason(String requestReason) {
497+
this.requestReason = requestReason;
498+
}
499+
500+
public String getRequestReason() {
501+
return requestReason;
502+
}
503+
504+
public void setUserAgent(String userAgent) {
505+
this.userAgent = userAgent;
506+
}
507+
478508
@Override
479509
public void initialize(HttpRequest httpRequest) throws IOException {
480510
super.initialize(httpRequest);
@@ -485,6 +515,12 @@ public void initialize(HttpRequest httpRequest) throws IOException {
485515
if (readTimeout != null) {
486516
httpRequest.setReadTimeout(readTimeout);
487517
}
518+
if (userAgent != null) {
519+
httpRequest.getHeaders().setUserAgent(userAgent);
520+
}
521+
if (requestReason != null) {
522+
httpRequest.getHeaders().set("X-Goog-Request-Reason", requestReason);
523+
}
488524
}
489525

490526
@Override
@@ -520,16 +556,5 @@ public String getOauthToken() {
520556
public void setOauthToken(String oauthToken) {
521557
this.oauthToken = oauthToken;
522558
}
523-
524-
@Override
525-
public void initializeBigqueryRequest(BigqueryRequest<?> request) throws IOException {
526-
if (userAgent != null) {
527-
HttpHeaders currentHeaders = request.getRequestHeaders();
528-
529-
currentHeaders.setUserAgent(userAgent);
530-
531-
request.setRequestHeaders(currentHeaders);
532-
}
533-
}
534559
}
535560
}

src/test/java/net/starschema/clouddb/jdbc/JdbcUrlTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,30 @@ public void rootUrlOverrideWorks() throws IOException, SQLException {
924924
request.getUrl().startsWith("https://restricted.googleapis.com/bigquery/v2/"));
925925
}
926926

927+
@Test
928+
public void urlWithRequestReasonSendsHeader() throws Exception {
929+
properties = getProperties("/vpcaccount.properties");
930+
String url = getUrl("/vpcaccount.properties", null) + "&requestReason=test_reason";
931+
String mockResponse =
932+
"{ \"jobComplete\": true, "
933+
+ "\"totalRows\": \"0\", "
934+
+ "\"rows\": [], "
935+
+ "\"totalBytesProcessed\": \"0\", "
936+
+ "\"cacheHit\": false }";
937+
MockHttpTransport mockTransport =
938+
new MockHttpTransport.Builder()
939+
.setLowLevelHttpResponse(new MockLowLevelHttpResponse().setContent(mockResponse))
940+
.build();
941+
bq = new BQConnection(url, properties, mockTransport);
942+
BQStatement stmt = new BQStatement(properties.getProperty("projectid"), bq);
943+
String sqlStmt = "SELECT word from publicdata:samples.shakespeare LIMIT 100";
944+
945+
stmt.executeQuery(sqlStmt);
946+
947+
MockLowLevelHttpRequest request = mockTransport.getLowLevelHttpRequest();
948+
Assert.assertEquals("test_reason", request.getFirstHeaderValue("X-Goog-Request-Reason"));
949+
}
950+
927951
@Test
928952
public void timeoutMsRejectsBadValues() throws Exception {
929953
try {

0 commit comments

Comments
 (0)