112
112
import com .google .cloud .spanner .connection .ClientSideStatementValueConverters .StringValueConverter ;
113
113
import com .google .cloud .spanner .connection .ConnectionProperty .Context ;
114
114
import com .google .cloud .spanner .connection .DirectedReadOptionsUtil .DirectedReadOptionsConverter ;
115
+ import com .google .common .collect .ImmutableList ;
115
116
import com .google .common .collect .ImmutableMap ;
116
117
import com .google .spanner .v1 .DirectedReadOptions ;
117
118
import java .time .Duration ;
118
- import java .util .Map ;
119
119
120
120
/**
121
121
* Utility class that defines all known connection properties. This class will eventually replace
122
122
* the list of {@link com.google.cloud.spanner.connection.ConnectionOptions.ConnectionProperty} in
123
123
* {@link ConnectionOptions}.
124
124
*/
125
- class ConnectionProperties {
125
+ public class ConnectionProperties {
126
126
private static final ImmutableMap .Builder <String , ConnectionProperty <?>>
127
127
CONNECTION_PROPERTIES_BUILDER = ImmutableMap .builder ();
128
128
129
+ private static final Boolean [] BOOLEANS = new Boolean [] {Boolean .TRUE , Boolean .FALSE };
130
+
129
131
static final ConnectionProperty <ConnectionState .Type > CONNECTION_STATE_TYPE =
130
132
create (
131
133
"connection_state_type" ,
132
134
"The type of connection state to use for this connection. Can only be set at start up. "
133
135
+ "If no value is set, then the database dialect default will be used, "
134
136
+ "which is NON_TRANSACTIONAL for GoogleSQL and TRANSACTIONAL for PostgreSQL." ,
135
137
null ,
138
+ ConnectionState .Type .values (),
136
139
ConnectionStateTypeConverter .INSTANCE ,
137
140
Context .STARTUP );
138
141
static final ConnectionProperty <String > TRACING_PREFIX =
@@ -148,6 +151,7 @@ class ConnectionProperties {
148
151
LENIENT_PROPERTY_NAME ,
149
152
"Silently ignore unknown properties in the connection string/properties (true/false)" ,
150
153
DEFAULT_LENIENT ,
154
+ BOOLEANS ,
151
155
BooleanConverter .INSTANCE ,
152
156
Context .STARTUP );
153
157
static final ConnectionProperty <String > ENDPOINT =
@@ -167,6 +171,7 @@ class ConnectionProperties {
167
171
+ "The instance and database in the connection string will automatically be created if these do not yet exist on the emulator. "
168
172
+ "Add dialect=postgresql to the connection string to make sure that the database that is created uses the PostgreSQL dialect." ,
169
173
false ,
174
+ BOOLEANS ,
170
175
BooleanConverter .INSTANCE ,
171
176
Context .STARTUP );
172
177
static final ConnectionProperty <Boolean > USE_AUTO_SAVEPOINTS_FOR_EMULATOR =
@@ -175,13 +180,15 @@ class ConnectionProperties {
175
180
"Automatically creates savepoints for each statement in a read/write transaction when using the Emulator. "
176
181
+ "This is no longer needed when using Emulator version 1.5.23 or higher." ,
177
182
false ,
183
+ BOOLEANS ,
178
184
BooleanConverter .INSTANCE ,
179
185
Context .STARTUP );
180
186
static final ConnectionProperty <Boolean > USE_PLAIN_TEXT =
181
187
create (
182
188
USE_PLAIN_TEXT_PROPERTY_NAME ,
183
189
"Use a plain text communication channel (i.e. non-TLS) for communicating with the server (true/false). Set this value to true for communication with the Cloud Spanner emulator." ,
184
190
DEFAULT_USE_PLAIN_TEXT ,
191
+ BOOLEANS ,
185
192
BooleanConverter .INSTANCE ,
186
193
Context .STARTUP );
187
194
@@ -226,6 +233,7 @@ class ConnectionProperties {
226
233
DIALECT_PROPERTY_NAME ,
227
234
"Sets the dialect to use for new databases that are created by this connection." ,
228
235
Dialect .GOOGLE_STANDARD_SQL ,
236
+ Dialect .values (),
229
237
DialectConverter .INSTANCE ,
230
238
Context .STARTUP );
231
239
static final ConnectionProperty <Boolean > TRACK_SESSION_LEAKS =
@@ -238,6 +246,7 @@ class ConnectionProperties {
238
246
+ "actual session leak is detected. The stack trace of the exception will "
239
247
+ "in that case not contain the call stack of when the session was checked out." ,
240
248
DEFAULT_TRACK_SESSION_LEAKS ,
249
+ BOOLEANS ,
241
250
BooleanConverter .INSTANCE ,
242
251
Context .STARTUP );
243
252
static final ConnectionProperty <Boolean > TRACK_CONNECTION_LEAKS =
@@ -250,13 +259,15 @@ class ConnectionProperties {
250
259
+ "actual connection leak is detected. The stack trace of the exception will "
251
260
+ "in that case not contain the call stack of when the connection was created." ,
252
261
DEFAULT_TRACK_CONNECTION_LEAKS ,
262
+ BOOLEANS ,
253
263
BooleanConverter .INSTANCE ,
254
264
Context .STARTUP );
255
265
static final ConnectionProperty <Boolean > ROUTE_TO_LEADER =
256
266
create (
257
267
ROUTE_TO_LEADER_PROPERTY_NAME ,
258
268
"Should read/write transactions and partitioned DML be routed to leader region (true/false)" ,
259
269
DEFAULT_ROUTE_TO_LEADER ,
270
+ BOOLEANS ,
260
271
BooleanConverter .INSTANCE ,
261
272
Context .STARTUP );
262
273
static final ConnectionProperty <Boolean > USE_VIRTUAL_THREADS =
@@ -265,6 +276,7 @@ class ConnectionProperties {
265
276
"Use a virtual thread instead of a platform thread for each connection (true/false). "
266
277
+ "This option only has any effect if the application is running on Java 21 or higher. In all other cases, the option is ignored." ,
267
278
DEFAULT_USE_VIRTUAL_THREADS ,
279
+ BOOLEANS ,
268
280
BooleanConverter .INSTANCE ,
269
281
Context .STARTUP );
270
282
static final ConnectionProperty <Boolean > USE_VIRTUAL_GRPC_TRANSPORT_THREADS =
@@ -273,6 +285,7 @@ class ConnectionProperties {
273
285
"Use a virtual thread instead of a platform thread for the gRPC executor (true/false). "
274
286
+ "This option only has any effect if the application is running on Java 21 or higher. In all other cases, the option is ignored." ,
275
287
DEFAULT_USE_VIRTUAL_GRPC_TRANSPORT_THREADS ,
288
+ BOOLEANS ,
276
289
BooleanConverter .INSTANCE ,
277
290
Context .STARTUP );
278
291
static final ConnectionProperty <Boolean > ENABLE_EXTENDED_TRACING =
@@ -282,6 +295,7 @@ class ConnectionProperties {
282
295
+ "by this connection. The SQL string is added as the standard OpenTelemetry "
283
296
+ "attribute 'db.statement'." ,
284
297
DEFAULT_ENABLE_EXTENDED_TRACING ,
298
+ BOOLEANS ,
285
299
BooleanConverter .INSTANCE ,
286
300
Context .STARTUP );
287
301
static final ConnectionProperty <Boolean > ENABLE_API_TRACING =
@@ -292,6 +306,7 @@ class ConnectionProperties {
292
306
+ "or if you want to debug potential latency problems caused by RPCs that are "
293
307
+ "being retried." ,
294
308
DEFAULT_ENABLE_API_TRACING ,
309
+ BOOLEANS ,
295
310
BooleanConverter .INSTANCE ,
296
311
Context .STARTUP );
297
312
static final ConnectionProperty <Boolean > ENABLE_END_TO_END_TRACING =
@@ -302,6 +317,7 @@ class ConnectionProperties {
302
317
+ "Server side traces can only go to Google Cloud Trace, so to see end to end traces, "
303
318
+ "the application should configure an exporter that exports the traces to Google Cloud Trace." ,
304
319
DEFAULT_ENABLE_END_TO_END_TRACING ,
320
+ BOOLEANS ,
305
321
BooleanConverter .INSTANCE ,
306
322
Context .STARTUP );
307
323
static final ConnectionProperty <Integer > MIN_SESSIONS =
@@ -345,20 +361,24 @@ class ConnectionProperties {
345
361
AUTOCOMMIT_PROPERTY_NAME ,
346
362
"Should the connection start in autocommit (true/false)" ,
347
363
DEFAULT_AUTOCOMMIT ,
364
+ BOOLEANS ,
348
365
BooleanConverter .INSTANCE ,
349
366
Context .USER );
350
367
static final ConnectionProperty <Boolean > READONLY =
351
368
create (
352
369
READONLY_PROPERTY_NAME ,
353
370
"Should the connection start in read-only mode (true/false)" ,
354
371
DEFAULT_READONLY ,
372
+ BOOLEANS ,
355
373
BooleanConverter .INSTANCE ,
356
374
Context .USER );
357
375
static final ConnectionProperty <AutocommitDmlMode > AUTOCOMMIT_DML_MODE =
358
376
create (
359
377
"autocommit_dml_mode" ,
360
- "Should the connection automatically retry Aborted errors (true/false)" ,
378
+ "Determines the transaction type that is used to execute "
379
+ + "DML statements when the connection is in auto-commit mode." ,
361
380
AutocommitDmlMode .TRANSACTIONAL ,
381
+ AutocommitDmlMode .values (),
362
382
AutocommitDmlModeConverter .INSTANCE ,
363
383
Context .USER );
364
384
static final ConnectionProperty <Boolean > RETRY_ABORTS_INTERNALLY =
@@ -371,13 +391,15 @@ class ConnectionProperties {
371
391
RETRY_ABORTS_INTERNALLY_PROPERTY_NAME ,
372
392
"Should the connection automatically retry Aborted errors (true/false)" ,
373
393
DEFAULT_RETRY_ABORTS_INTERNALLY ,
394
+ BOOLEANS ,
374
395
BooleanConverter .INSTANCE ,
375
396
Context .USER );
376
397
static final ConnectionProperty <Boolean > RETURN_COMMIT_STATS =
377
398
create (
378
399
"returnCommitStats" ,
379
400
"Request that Spanner returns commit statistics for read/write transactions (true/false)" ,
380
401
DEFAULT_RETURN_COMMIT_STATS ,
402
+ BOOLEANS ,
381
403
BooleanConverter .INSTANCE ,
382
404
Context .USER );
383
405
static final ConnectionProperty <Boolean > DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE =
@@ -389,6 +411,7 @@ class ConnectionProperties {
389
411
+ "the first write operation in a read/write transaction will be executed using the read/write transaction. Enabling this mode can reduce locking "
390
412
+ "and improve performance for applications that can handle the lower transaction isolation semantics." ,
391
413
DEFAULT_DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE ,
414
+ BOOLEANS ,
392
415
BooleanConverter .INSTANCE ,
393
416
Context .USER );
394
417
static final ConnectionProperty <Boolean > KEEP_TRANSACTION_ALIVE =
@@ -398,6 +421,7 @@ class ConnectionProperties {
398
421
+ "if no other statements are being executed. This option should be used with caution, as it can keep transactions alive and hold on to locks "
399
422
+ "longer than intended. This option should typically be used for CLI-type application that might wait for user input for a longer period of time." ,
400
423
DEFAULT_KEEP_TRANSACTION_ALIVE ,
424
+ BOOLEANS ,
401
425
BooleanConverter .INSTANCE ,
402
426
Context .USER );
403
427
@@ -415,6 +439,7 @@ class ConnectionProperties {
415
439
+ "Executing a query that cannot be partitioned will fail. "
416
440
+ "Executing a query in a read/write transaction will also fail." ,
417
441
DEFAULT_AUTO_PARTITION_MODE ,
442
+ BOOLEANS ,
418
443
BooleanConverter .INSTANCE ,
419
444
Context .USER );
420
445
static final ConnectionProperty <Boolean > DATA_BOOST_ENABLED =
@@ -423,6 +448,7 @@ class ConnectionProperties {
423
448
"Enable data boost for all partitioned queries that are executed by this connection. "
424
449
+ "This setting is only used for partitioned queries and is ignored by all other statements." ,
425
450
DEFAULT_DATA_BOOST_ENABLED ,
451
+ BOOLEANS ,
426
452
BooleanConverter .INSTANCE ,
427
453
Context .USER );
428
454
static final ConnectionProperty <Integer > MAX_PARTITIONS =
@@ -468,20 +494,23 @@ class ConnectionProperties {
468
494
RPC_PRIORITY_NAME ,
469
495
"Sets the priority for all RPC invocations from this connection (HIGH/MEDIUM/LOW). The default is HIGH." ,
470
496
DEFAULT_RPC_PRIORITY ,
497
+ RpcPriority .values (),
471
498
RpcPriorityConverter .INSTANCE ,
472
499
Context .USER );
473
500
static final ConnectionProperty <SavepointSupport > SAVEPOINT_SUPPORT =
474
501
create (
475
502
"savepoint_support" ,
476
503
"Determines the behavior of the connection when savepoints are used." ,
477
504
SavepointSupport .FAIL_AFTER_ROLLBACK ,
505
+ SavepointSupport .values (),
478
506
SavepointSupportConverter .INSTANCE ,
479
507
Context .USER );
480
508
static final ConnectionProperty <DdlInTransactionMode > DDL_IN_TRANSACTION_MODE =
481
509
create (
482
510
DDL_IN_TRANSACTION_MODE_PROPERTY_NAME ,
483
511
"Determines how the connection should handle DDL statements in a read/write transaction." ,
484
512
DEFAULT_DDL_IN_TRANSACTION_MODE ,
513
+ DdlInTransactionMode .values (),
485
514
DdlInTransactionModeConverter .INSTANCE ,
486
515
Context .USER );
487
516
static final ConnectionProperty <Duration > MAX_COMMIT_DELAY =
@@ -504,6 +533,7 @@ class ConnectionProperties {
504
533
+ "This setting is only in read/write transactions. DML statements in auto-commit mode "
505
534
+ "are executed directly." ,
506
535
DEFAULT_AUTO_BATCH_DML ,
536
+ BOOLEANS ,
507
537
BooleanConverter .INSTANCE ,
508
538
Context .USER );
509
539
static final ConnectionProperty <Long > AUTO_BATCH_DML_UPDATE_COUNT =
@@ -538,23 +568,45 @@ class ConnectionProperties {
538
568
+ AUTO_BATCH_DML_UPDATE_COUNT_VERIFICATION_PROPERTY_NAME
539
569
+ " to false." ,
540
570
DEFAULT_AUTO_BATCH_DML_UPDATE_COUNT_VERIFICATION ,
571
+ BOOLEANS ,
541
572
BooleanConverter .INSTANCE ,
542
573
Context .USER );
543
574
544
- static final Map <String , ConnectionProperty <?>> CONNECTION_PROPERTIES =
575
+ static final ImmutableMap <String , ConnectionProperty <?>> CONNECTION_PROPERTIES =
545
576
CONNECTION_PROPERTIES_BUILDER .build ();
546
577
578
+ /** The list of all supported connection properties. */
579
+ public static ImmutableList <ConnectionProperty <?>> VALID_CONNECTION_PROPERTIES =
580
+ ImmutableList .copyOf (ConnectionProperties .CONNECTION_PROPERTIES .values ());
581
+
547
582
/** Utility method for creating a new core {@link ConnectionProperty}. */
548
583
private static <T > ConnectionProperty <T > create (
549
584
String name ,
550
585
String description ,
551
586
T defaultValue ,
552
587
ClientSideStatementValueConverter <T > converter ,
553
588
Context context ) {
554
- ConnectionProperty <T > property =
555
- ConnectionProperty .create (name , description , defaultValue , converter , context );
556
- CONNECTION_PROPERTIES_BUILDER .put (property .getKey (), property );
557
- return property ;
589
+ return create (name , description , defaultValue , null , converter , context );
590
+ }
591
+
592
+ /** Utility method for creating a new core {@link ConnectionProperty}. */
593
+ private static <T > ConnectionProperty <T > create (
594
+ String name ,
595
+ String description ,
596
+ T defaultValue ,
597
+ T [] validValues ,
598
+ ClientSideStatementValueConverter <T > converter ,
599
+ Context context ) {
600
+ try {
601
+ ConnectionProperty <T > property =
602
+ ConnectionProperty .create (
603
+ name , description , defaultValue , validValues , converter , context );
604
+ CONNECTION_PROPERTIES_BUILDER .put (property .getKey (), property );
605
+ return property ;
606
+ } catch (Throwable t ) {
607
+ t .printStackTrace ();
608
+ }
609
+ return null ;
558
610
}
559
611
560
612
/** Parse the connection properties that can be found in the given connection URL. */
0 commit comments