Skip to content

Commit d5bc95f

Browse files
aseeringBot
authored andcommitted
feat: port secure_context testing support to executor proxy
1 parent c8d69cc commit d5bc95f

1 file changed

Lines changed: 75 additions & 9 deletions

File tree

‎java-spanner/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java‎

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -737,14 +737,16 @@ public synchronized void bufferMutations(List<Mutation> mutations) throws Spanne
737737
}
738738

739739
/** Execute a batch of updates in a read-write transaction. */
740-
public synchronized long[] executeBatchDml(@Nonnull List<Statement> stmts)
741-
throws SpannerException {
740+
public synchronized long[] executeBatchDml(
741+
@Nonnull List<Statement> stmts, Options.UpdateOption... options) throws SpannerException {
742742
for (int i = 0; i < stmts.size(); i++) {
743743
LOGGER.log(
744744
Level.INFO, String.format("executeBatchDml [%d]: %s", i + 1, stmts.get(i).toString()));
745745
}
746+
List<Options.UpdateOption> allOptions = new ArrayList<>(java.util.Arrays.asList(options));
747+
allOptions.add(Options.tag("batch-update-transaction-tag"));
746748
return getTransactionForWrite()
747-
.batchUpdate(stmts, Options.tag("batch-update-transaction-tag"));
749+
.batchUpdate(stmts, allOptions.toArray(new Options.UpdateOption[0]));
748750
}
749751

750752
/** Finish active transaction in given finishMode, then send outcome back to client. */
@@ -2199,13 +2201,54 @@ private Status executeGenerateDbPartitionsRead(
21992201
}
22002202

22012203
/** Execute action that generates database partitions for the given query. */
2204+
private Options.ReadQueryUpdateTransactionOption buildSecureContextOption(
2205+
Map<String, com.google.spanner.executor.v1.Value> secureContextMap) {
2206+
if (secureContextMap != null && !secureContextMap.isEmpty()) {
2207+
com.google.spanner.v1.RequestOptions.ClientContext.Builder clientContextBuilder =
2208+
com.google.spanner.v1.RequestOptions.ClientContext.newBuilder();
2209+
for (Map.Entry<String, com.google.spanner.executor.v1.Value> entry :
2210+
secureContextMap.entrySet()) {
2211+
com.google.protobuf.Value.Builder valueBuilder = com.google.protobuf.Value.newBuilder();
2212+
if (entry.getValue().getValueTypeCase()
2213+
== com.google.spanner.executor.v1.Value.ValueTypeCase.IS_NULL
2214+
&& entry.getValue().getIsNull()) {
2215+
valueBuilder.setNullValue(com.google.protobuf.NullValue.NULL_VALUE);
2216+
} else if (entry.getValue().getValueTypeCase()
2217+
== com.google.spanner.executor.v1.Value.ValueTypeCase.STRING_VALUE) {
2218+
valueBuilder.setStringValue(entry.getValue().getStringValue());
2219+
} else {
2220+
throw new IllegalArgumentException(
2221+
"Unsupported secure parameter value type in executor proxy");
2222+
}
2223+
clientContextBuilder.putSecureContext(entry.getKey(), valueBuilder.build());
2224+
}
2225+
return Options.clientContext(clientContextBuilder.build());
2226+
}
2227+
return null;
2228+
}
2229+
2230+
@SuppressWarnings("unchecked")
2231+
private <T> void addSecureContextOption(
2232+
Map<String, com.google.spanner.executor.v1.Value> secureContextMap,
2233+
List<T> optionsList,
2234+
Class<?> optionClass) {
2235+
Options.ReadQueryUpdateTransactionOption secureContextOption =
2236+
buildSecureContextOption(secureContextMap);
2237+
if (secureContextOption != null && optionClass.isInstance(secureContextOption)) {
2238+
optionsList.add((T) secureContextOption);
2239+
}
2240+
}
2241+
22022242
private Status executeGenerateDbPartitionsQuery(
22032243
GenerateDbPartitionsForQueryAction action,
22042244
OutcomeSender sender,
22052245
ExecutionFlowContext executionContext) {
22062246
try {
22072247
BatchReadOnlyTransaction batchTxn = executionContext.getBatchTxn();
22082248
Statement.Builder stmt = Statement.newBuilder(action.getQuery().getSql());
2249+
List<Options.QueryOption> queryOptions = new ArrayList<>();
2250+
addSecureContextOption(
2251+
action.getQuery().getSecureContextMap(), queryOptions, Options.QueryOption.class);
22092252
for (int i = 0; i < action.getQuery().getParamsCount(); ++i) {
22102253
stmt.bind(action.getQuery().getParams(i).getName())
22112254
.to(
@@ -2217,7 +2260,9 @@ private Status executeGenerateDbPartitionsQuery(
22172260
PartitionOptions.newBuilder()
22182261
.setPartitionSizeBytes(action.getDesiredBytesPerPartition())
22192262
.build();
2220-
List<Partition> parts = batchTxn.partitionQuery(partitionOptions, stmt.build());
2263+
List<Partition> parts =
2264+
batchTxn.partitionQuery(
2265+
partitionOptions, stmt.build(), queryOptions.toArray(new Options.QueryOption[0]));
22212266
List<BatchPartition> batchPartitions = new ArrayList<>();
22222267
for (Partition part : parts) {
22232268
batchPartitions.add(
@@ -2283,11 +2328,15 @@ private Status executePartitionedUpdate(
22832328
PartitionedUpdateAction action, DatabaseClient dbClient, OutcomeSender sender) {
22842329
try {
22852330
ExecutePartitionedUpdateOptions options = action.getOptions();
2331+
List<Options.UpdateOption> optionsList = new ArrayList<>();
2332+
optionsList.add(Options.tag(options.getTag()));
2333+
optionsList.add(Options.priority(RpcPriority.fromProto(options.getRpcPriority())));
2334+
addSecureContextOption(
2335+
action.getUpdate().getSecureContextMap(), optionsList, Options.UpdateOption.class);
22862336
Long count =
22872337
dbClient.executePartitionedUpdate(
22882338
Statement.of(action.getUpdate().getSql()),
2289-
Options.tag(options.getTag()),
2290-
Options.priority(RpcPriority.fromProto(options.getRpcPriority())));
2339+
optionsList.toArray(new Options.UpdateOption[0]));
22912340
SpannerActionOutcome outcome =
22922341
SpannerActionOutcome.newBuilder()
22932342
.setStatus(toProto(Status.OK))
@@ -2740,7 +2789,11 @@ private Status executeQuery(
27402789
String.format(
27412790
"Finish query building, ready to execute %s\n",
27422791
executionContext.getTransactionSeed()));
2743-
ResultSet result = txn.executeQuery(stmt.build(), Options.tag("query-tag"));
2792+
List<Options.QueryOption> queryOptions = new ArrayList<>();
2793+
queryOptions.add(Options.tag("query-tag"));
2794+
addSecureContextOption(action.getSecureContextMap(), queryOptions, Options.QueryOption.class);
2795+
ResultSet result =
2796+
txn.executeQuery(stmt.build(), queryOptions.toArray(new Options.QueryOption[0]));
27442797
LOGGER.log(
27452798
Level.INFO,
27462799
String.format("Parsing query result %s\n", executionContext.getTransactionSeed()));
@@ -2770,10 +2823,14 @@ private Status executeCloudDmlUpdate(
27702823
update.getParams(i).getType(), update.getParams(i).getValue()));
27712824
}
27722825
sender.initForQuery();
2826+
List<Options.QueryOption> queryOptions = new ArrayList<>();
2827+
queryOptions.add(Options.tag("dml-transaction-tag"));
2828+
addSecureContextOption(
2829+
action.getUpdate().getSecureContextMap(), queryOptions, Options.QueryOption.class);
27732830
ResultSet result =
27742831
executionContext
27752832
.getTransactionForWrite()
2776-
.executeQuery(stmt.build(), Options.tag("dml-transaction-tag"));
2833+
.executeQuery(stmt.build(), queryOptions.toArray(new Options.QueryOption[0]));
27772834
LOGGER.log(
27782835
Level.INFO,
27792836
String.format("Parsing Dml result %s\n", executionContext.getTransactionSeed()));
@@ -2804,7 +2861,16 @@ private Status executeCloudBatchDmlUpdates(
28042861
}
28052862
queries.add(stmt.build());
28062863
}
2807-
long[] rowCounts = executionContext.executeBatchDml(queries);
2864+
Map<String, com.google.spanner.executor.v1.Value> secureContextMap =
2865+
new java.util.HashMap<>();
2866+
for (int i = 0; i < action.getUpdatesCount(); ++i) {
2867+
secureContextMap.putAll(action.getUpdates(i).getSecureContextMap());
2868+
}
2869+
List<Options.UpdateOption> optionsList = new ArrayList<>();
2870+
addSecureContextOption(secureContextMap, optionsList, Options.UpdateOption.class);
2871+
long[] rowCounts =
2872+
executionContext.executeBatchDml(
2873+
queries, optionsList.toArray(new Options.UpdateOption[0]));
28082874
sender.initForQuery();
28092875
for (long rowCount : rowCounts) {
28102876
sender.appendRowsModifiedInDml(rowCount);

0 commit comments

Comments
 (0)