42
42
import java .util .Set ;
43
43
import java .util .regex .Matcher ;
44
44
import java .util .regex .Pattern ;
45
+ import javax .annotation .Nullable ;
45
46
46
47
/**
47
48
* Internal connection API for Google Cloud Spanner. This class may introduce breaking changes
@@ -152,6 +153,7 @@ public String[] getValidValues() {
152
153
private static final String DEFAULT_NUM_CHANNELS = null ;
153
154
private static final String DEFAULT_USER_AGENT = null ;
154
155
private static final String DEFAULT_OPTIMIZER_VERSION = "" ;
156
+ private static final boolean DEFAULT_LENIENT = false ;
155
157
156
158
private static final String PLAIN_TEXT_PROTOCOL = "http:" ;
157
159
private static final String HOST_PROTOCOL = "https:" ;
@@ -176,6 +178,8 @@ public String[] getValidValues() {
176
178
private static final String USER_AGENT_PROPERTY_NAME = "userAgent" ;
177
179
/** Query optimizer version to use for a connection. */
178
180
private static final String OPTIMIZER_VERSION_PROPERTY_NAME = "optimizerVersion" ;
181
+ /** Name of the 'lenientMode' connection property. */
182
+ public static final String LENIENT_PROPERTY_NAME = "lenient" ;
179
183
180
184
/** All valid connection properties. */
181
185
public static final Set <ConnectionProperty > VALID_PROPERTIES =
@@ -212,7 +216,11 @@ public String[] getValidValues() {
212
216
"The custom user-agent property name to use when communicating with Cloud Spanner. This property is intended for internal library usage, and should not be set by applications." ),
213
217
ConnectionProperty .createStringProperty (
214
218
OPTIMIZER_VERSION_PROPERTY_NAME ,
215
- "Sets the default query optimizer version to use for this connection." ))));
219
+ "Sets the default query optimizer version to use for this connection." ),
220
+ ConnectionProperty .createBooleanProperty (
221
+ LENIENT_PROPERTY_NAME ,
222
+ "Silently ignore unknown properties in the connection string/properties (true/false)" ,
223
+ DEFAULT_LENIENT ))));
216
224
217
225
private static final Set <ConnectionProperty > INTERNAL_PROPERTIES =
218
226
Collections .unmodifiableSet (
@@ -416,6 +424,7 @@ public static Builder newBuilder() {
416
424
}
417
425
418
426
private final String uri ;
427
+ private final String warnings ;
419
428
private final String credentialsUrl ;
420
429
private final String oauthToken ;
421
430
private final Credentials fixedCredentials ;
@@ -441,7 +450,7 @@ private ConnectionOptions(Builder builder) {
441
450
Matcher matcher = Builder .SPANNER_URI_PATTERN .matcher (builder .uri );
442
451
Preconditions .checkArgument (
443
452
matcher .find (), String .format ("Invalid connection URI specified: %s" , builder .uri ));
444
- checkValidProperties (builder .uri );
453
+ this . warnings = checkValidProperties (builder .uri );
445
454
446
455
this .uri = builder .uri ;
447
456
this .sessionPoolOptions = builder .sessionPoolOptions ;
@@ -574,6 +583,12 @@ static String parseOptimizerVersion(String uri) {
574
583
return value != null ? value : DEFAULT_OPTIMIZER_VERSION ;
575
584
}
576
585
586
+ @ VisibleForTesting
587
+ static boolean parseLenient (String uri ) {
588
+ String value = parseUriProperty (uri , LENIENT_PROPERTY_NAME );
589
+ return value != null ? Boolean .valueOf (value ) : DEFAULT_LENIENT ;
590
+ }
591
+
577
592
@ VisibleForTesting
578
593
static String parseUriProperty (String uri , String property ) {
579
594
Pattern pattern = Pattern .compile (String .format ("(?is)(?:;|\\ ?)%s=(.*?)(?:;|$)" , property ));
@@ -586,9 +601,10 @@ static String parseUriProperty(String uri, String property) {
586
601
587
602
/** Check that only valid properties have been specified. */
588
603
@ VisibleForTesting
589
- static void checkValidProperties (String uri ) {
604
+ static String checkValidProperties (String uri ) {
590
605
String invalidProperties = "" ;
591
606
List <String > properties = parseProperties (uri );
607
+ boolean lenient = parseLenient (uri );
592
608
for (String property : properties ) {
593
609
if (!INTERNAL_VALID_PROPERTIES .contains (ConnectionProperty .createEmptyProperty (property ))) {
594
610
if (invalidProperties .length () > 0 ) {
@@ -597,9 +613,17 @@ static void checkValidProperties(String uri) {
597
613
invalidProperties = invalidProperties + property ;
598
614
}
599
615
}
600
- Preconditions .checkArgument (
601
- invalidProperties .isEmpty (),
602
- "Invalid properties found in connection URI: " + invalidProperties .toString ());
616
+ if (lenient ) {
617
+ return String .format (
618
+ "Invalid properties found in connection URI: %s" , invalidProperties .toString ());
619
+ } else {
620
+ Preconditions .checkArgument (
621
+ invalidProperties .isEmpty (),
622
+ String .format (
623
+ "Invalid properties found in connection URI. Add lenient=true to the connection string to ignore unknown properties. Invalid properties: %s" ,
624
+ invalidProperties .toString ()));
625
+ return null ;
626
+ }
603
627
}
604
628
605
629
@ VisibleForTesting
@@ -706,6 +730,12 @@ public boolean isRetryAbortsInternally() {
706
730
return retryAbortsInternally ;
707
731
}
708
732
733
+ /** Any warnings that were generated while creating the {@link ConnectionOptions} instance. */
734
+ @ Nullable
735
+ public String getWarnings () {
736
+ return warnings ;
737
+ }
738
+
709
739
/** Use http instead of https. Only valid for (local) test servers. */
710
740
boolean isUsePlainText () {
711
741
return usePlainText ;
0 commit comments