@@ -1592,7 +1592,8 @@ public List<Session> batchCreateSessions(
15921592 requestBuilder .setSessionTemplate (sessionBuilder );
15931593 BatchCreateSessionsRequest request = requestBuilder .build ();
15941594 GrpcCallContext context =
1595- newCallContext (options , databaseName , request , SpannerGrpc .getBatchCreateSessionsMethod ());
1595+ newCallContext (
1596+ options , databaseName , request , SpannerGrpc .getBatchCreateSessionsMethod (), true );
15961597 return get (spannerStub .batchCreateSessionsCallable ().futureCall (request , context ))
15971598 .getSessionList ();
15981599 }
@@ -1616,7 +1617,7 @@ public Session createSession(
16161617 requestBuilder .setSession (sessionBuilder );
16171618 CreateSessionRequest request = requestBuilder .build ();
16181619 GrpcCallContext context =
1619- newCallContext (options , databaseName , request , SpannerGrpc .getCreateSessionMethod ());
1620+ newCallContext (options , databaseName , request , SpannerGrpc .getCreateSessionMethod (), true );
16201621 return get (spannerStub .createSessionCallable ().futureCall (request , context ));
16211622 }
16221623
@@ -1630,15 +1631,19 @@ public void deleteSession(String sessionName, @Nullable Map<Option, ?> options)
16301631 public ApiFuture <Empty > asyncDeleteSession (String sessionName , @ Nullable Map <Option , ?> options ) {
16311632 DeleteSessionRequest request = DeleteSessionRequest .newBuilder ().setName (sessionName ).build ();
16321633 GrpcCallContext context =
1633- newCallContext (options , sessionName , request , SpannerGrpc .getDeleteSessionMethod ());
1634+ newCallContext (options , sessionName , request , SpannerGrpc .getDeleteSessionMethod (), false );
16341635 return spannerStub .deleteSessionCallable ().futureCall (request , context );
16351636 }
16361637
16371638 @ Override
16381639 public StreamingCall read (
1639- ReadRequest request , ResultStreamConsumer consumer , @ Nullable Map <Option , ?> options ) {
1640+ ReadRequest request ,
1641+ ResultStreamConsumer consumer ,
1642+ @ Nullable Map <Option , ?> options ,
1643+ boolean routeToLeader ) {
16401644 GrpcCallContext context =
1641- newCallContext (options , request .getSession (), request , SpannerGrpc .getReadMethod ());
1645+ newCallContext (
1646+ options , request .getSession (), request , SpannerGrpc .getReadMethod (), routeToLeader );
16421647 SpannerResponseObserver responseObserver = new SpannerResponseObserver (consumer );
16431648 spannerStub .streamingReadCallable ().call (request , responseObserver , context );
16441649 final StreamController controller = responseObserver .getController ();
@@ -1658,13 +1663,14 @@ public void cancel(String message) {
16581663 }
16591664
16601665 @ Override
1661- public ResultSet executeQuery (ExecuteSqlRequest request , @ Nullable Map <Option , ?> options ) {
1662- return get (executeQueryAsync (request , options ));
1666+ public ResultSet executeQuery (
1667+ ExecuteSqlRequest request , @ Nullable Map <Option , ?> options , boolean routeToLeader ) {
1668+ return get (executeQueryAsync (request , options , routeToLeader ));
16631669 }
16641670
16651671 @ Override
16661672 public ApiFuture <ResultSet > executeQueryAsync (
1667- ExecuteSqlRequest request , @ Nullable Map <Option , ?> options ) {
1673+ ExecuteSqlRequest request , @ Nullable Map <Option , ?> options , boolean routeToLeader ) {
16681674 GrpcCallContext context =
16691675 newCallContext (options , request .getSession (), request , SpannerGrpc .getExecuteSqlMethod ());
16701676 return spannerStub .executeSqlCallable ().futureCall (request , context );
@@ -1674,7 +1680,8 @@ public ApiFuture<ResultSet> executeQueryAsync(
16741680 public ResultSet executePartitionedDml (
16751681 ExecuteSqlRequest request , @ Nullable Map <Option , ?> options ) {
16761682 GrpcCallContext context =
1677- newCallContext (options , request .getSession (), request , SpannerGrpc .getExecuteSqlMethod ());
1683+ newCallContext (
1684+ options , request .getSession (), request , SpannerGrpc .getExecuteSqlMethod (), true );
16781685 return get (partitionedDmlStub .executeSqlCallable ().futureCall (request , context ));
16791686 }
16801687
@@ -1688,18 +1695,29 @@ public ServerStream<PartialResultSet> executeStreamingPartitionedDml(
16881695 ExecuteSqlRequest request , Map <Option , ?> options , Duration timeout ) {
16891696 GrpcCallContext context =
16901697 newCallContext (
1691- options , request .getSession (), request , SpannerGrpc .getExecuteStreamingSqlMethod ());
1698+ options ,
1699+ request .getSession (),
1700+ request ,
1701+ SpannerGrpc .getExecuteStreamingSqlMethod (),
1702+ true );
16921703 // Override any timeout settings that might have been set on the call context.
16931704 context = context .withTimeout (timeout ).withStreamWaitTimeout (timeout );
16941705 return partitionedDmlStub .executeStreamingSqlCallable ().call (request , context );
16951706 }
16961707
16971708 @ Override
16981709 public StreamingCall executeQuery (
1699- ExecuteSqlRequest request , ResultStreamConsumer consumer , @ Nullable Map <Option , ?> options ) {
1710+ ExecuteSqlRequest request ,
1711+ ResultStreamConsumer consumer ,
1712+ @ Nullable Map <Option , ?> options ,
1713+ boolean routeToLeader ) {
17001714 GrpcCallContext context =
17011715 newCallContext (
1702- options , request .getSession (), request , SpannerGrpc .getExecuteStreamingSqlMethod ());
1716+ options ,
1717+ request .getSession (),
1718+ request ,
1719+ SpannerGrpc .getExecuteStreamingSqlMethod (),
1720+ routeToLeader );
17031721 SpannerResponseObserver responseObserver = new SpannerResponseObserver (consumer );
17041722 spannerStub .executeStreamingSqlCallable ().call (request , responseObserver , context );
17051723 final StreamController controller = responseObserver .getController ();
@@ -1729,30 +1747,35 @@ public ApiFuture<ExecuteBatchDmlResponse> executeBatchDmlAsync(
17291747 ExecuteBatchDmlRequest request , @ Nullable Map <Option , ?> options ) {
17301748 GrpcCallContext context =
17311749 newCallContext (
1732- options , request .getSession (), request , SpannerGrpc .getExecuteBatchDmlMethod ());
1750+ options , request .getSession (), request , SpannerGrpc .getExecuteBatchDmlMethod (), true );
17331751 return spannerStub .executeBatchDmlCallable ().futureCall (request , context );
17341752 }
17351753
17361754 @ Override
17371755 public ApiFuture <Transaction > beginTransactionAsync (
1738- BeginTransactionRequest request , @ Nullable Map <Option , ?> options ) {
1756+ BeginTransactionRequest request , @ Nullable Map <Option , ?> options , boolean routeToLeader ) {
17391757 GrpcCallContext context =
17401758 newCallContext (
1741- options , request .getSession (), request , SpannerGrpc .getBeginTransactionMethod ());
1759+ options ,
1760+ request .getSession (),
1761+ request ,
1762+ SpannerGrpc .getBeginTransactionMethod (),
1763+ routeToLeader );
17421764 return spannerStub .beginTransactionCallable ().futureCall (request , context );
17431765 }
17441766
17451767 @ Override
17461768 public Transaction beginTransaction (
1747- BeginTransactionRequest request , @ Nullable Map <Option , ?> options ) throws SpannerException {
1748- return get (beginTransactionAsync (request , options ));
1769+ BeginTransactionRequest request , @ Nullable Map <Option , ?> options , boolean routeToLeader )
1770+ throws SpannerException {
1771+ return get (beginTransactionAsync (request , options , routeToLeader ));
17491772 }
17501773
17511774 @ Override
17521775 public ApiFuture <CommitResponse > commitAsync (
17531776 CommitRequest request , @ Nullable Map <Option , ?> options ) {
17541777 GrpcCallContext context =
1755- newCallContext (options , request .getSession (), request , SpannerGrpc .getCommitMethod ());
1778+ newCallContext (options , request .getSession (), request , SpannerGrpc .getCommitMethod (), true );
17561779 return spannerStub .commitCallable ().futureCall (request , context );
17571780 }
17581781
@@ -1765,7 +1788,8 @@ public CommitResponse commit(CommitRequest commitRequest, @Nullable Map<Option,
17651788 @ Override
17661789 public ApiFuture <Empty > rollbackAsync (RollbackRequest request , @ Nullable Map <Option , ?> options ) {
17671790 GrpcCallContext context =
1768- newCallContext (options , request .getSession (), request , SpannerGrpc .getRollbackMethod ());
1791+ newCallContext (
1792+ options , request .getSession (), request , SpannerGrpc .getRollbackMethod (), true );
17691793 return spannerStub .rollbackCallable ().futureCall (request , context );
17701794 }
17711795
@@ -1780,7 +1804,7 @@ public PartitionResponse partitionQuery(
17801804 PartitionQueryRequest request , @ Nullable Map <Option , ?> options ) throws SpannerException {
17811805 GrpcCallContext context =
17821806 newCallContext (
1783- options , request .getSession (), request , SpannerGrpc .getPartitionQueryMethod ());
1807+ options , request .getSession (), request , SpannerGrpc .getPartitionQueryMethod (), true );
17841808 return get (spannerStub .partitionQueryCallable ().futureCall (request , context ));
17851809 }
17861810
@@ -1789,7 +1813,7 @@ public PartitionResponse partitionRead(
17891813 PartitionReadRequest request , @ Nullable Map <Option , ?> options ) throws SpannerException {
17901814 GrpcCallContext context =
17911815 newCallContext (
1792- options , request .getSession (), request , SpannerGrpc .getPartitionReadMethod ());
1816+ options , request .getSession (), request , SpannerGrpc .getPartitionReadMethod (), true );
17931817 return get (spannerStub .partitionReadCallable ().futureCall (request , context ));
17941818 }
17951819
@@ -1898,6 +1922,16 @@ <ReqT, RespT> GrpcCallContext newCallContext(
18981922 String resource ,
18991923 ReqT request ,
19001924 MethodDescriptor <ReqT , RespT > method ) {
1925+ return newCallContext (options , resource , request , method , false );
1926+ }
1927+
1928+ @ VisibleForTesting
1929+ <ReqT , RespT > GrpcCallContext newCallContext (
1930+ @ Nullable Map <Option , ?> options ,
1931+ String resource ,
1932+ ReqT request ,
1933+ MethodDescriptor <ReqT , RespT > method ,
1934+ boolean routeToLeader ) {
19011935 GrpcCallContext context = GrpcCallContext .createDefault ();
19021936 if (options != null ) {
19031937 context = context .withChannelAffinity (Option .CHANNEL_HINT .getLong (options ).intValue ());
@@ -1907,6 +1941,9 @@ <ReqT, RespT> GrpcCallContext newCallContext(
19071941 context = context .withCallOptions (context .getCallOptions ().withCompression (compressorName ));
19081942 }
19091943 context = context .withExtraHeaders (metadataProvider .newExtraHeaders (resource , projectName ));
1944+ if (routeToLeader ) {
1945+ context = context .withExtraHeaders (metadataProvider .newRouteToLeaderHeader ());
1946+ }
19101947 if (callCredentialsProvider != null ) {
19111948 CallCredentials callCredentials = callCredentialsProvider .getCallCredentials ();
19121949 if (callCredentials != null ) {
0 commit comments