From 702147ee76b2a70e65eafd8856a484261a26b715 Mon Sep 17 00:00:00 2001
From: "release-please[bot]"
 <55107282+release-please[bot]@users.noreply.github.com>
Date: Thu, 30 Jun 2022 03:14:14 +0000
Subject: [PATCH 01/11] chore(main): release 6.25.8-SNAPSHOT (#1932)

:robot: I have created a release *beep* *boop*
---


### Updating meta-information for bleeding-edge SNAPSHOT release.

---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
---
 google-cloud-spanner-bom/pom.xml               | 18 +++++++++---------
 google-cloud-spanner/pom.xml                   |  4 ++--
 .../pom.xml                                    |  4 ++--
 .../pom.xml                                    |  4 ++--
 grpc-google-cloud-spanner-v1/pom.xml           |  4 ++--
 pom.xml                                        | 16 ++++++++--------
 .../pom.xml                                    |  4 ++--
 .../pom.xml                                    |  4 ++--
 proto-google-cloud-spanner-v1/pom.xml          |  4 ++--
 samples/snapshot/pom.xml                       |  2 +-
 versions.txt                                   | 14 +++++++-------
 11 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml
index bcbb89716db..d1973f706b7 100644
--- a/google-cloud-spanner-bom/pom.xml
+++ b/google-cloud-spanner-bom/pom.xml
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner-bom</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   <packaging>pom</packaging>
   <parent>
     <groupId>com.google.cloud</groupId>
@@ -53,43 +53,43 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner</artifactId>
         <type>test-jar</type>
-        <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
     </dependencies>
   </dependencyManagement>
diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml
index e19423ee42e..9e469d0961a 100644
--- a/google-cloud-spanner/pom.xml
+++ b/google-cloud-spanner/pom.xml
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   <packaging>jar</packaging>
   <name>Google Cloud Spanner</name>
   <url>https://github.com/googleapis/java-spanner</url>
@@ -11,7 +11,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <properties>
     <site.installationModule>google-cloud-spanner</site.installationModule>
diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml
index 3278b7f657b..586e45055a9 100644
--- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml
+++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
   <name>grpc-google-cloud-spanner-admin-database-v1</name>
   <description>GRPC library for grpc-google-cloud-spanner-admin-database-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml
index 6dc83cd26cf..635f2b33675 100644
--- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml
+++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
   <name>grpc-google-cloud-spanner-admin-instance-v1</name>
   <description>GRPC library for grpc-google-cloud-spanner-admin-instance-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml
index efe70734322..e3be92a9925 100644
--- a/grpc-google-cloud-spanner-v1/pom.xml
+++ b/grpc-google-cloud-spanner-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-spanner-v1</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
   <name>grpc-google-cloud-spanner-v1</name>
   <description>GRPC library for grpc-google-cloud-spanner-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/pom.xml b/pom.xml
index be63fd7ce48..fdaa4995fbc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner-parent</artifactId>
   <packaging>pom</packaging>
-  <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   <name>Google Cloud Spanner Parent</name>
   <url>https://github.com/googleapis/java-spanner</url>
   <description>
@@ -62,37 +62,37 @@
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner</artifactId>
-        <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
       </dependency>
 
       <dependency>
diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml
index 4e0eecaeb8a..9af1acd5e29 100644
--- a/proto-google-cloud-spanner-admin-database-v1/pom.xml
+++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
   <name>proto-google-cloud-spanner-admin-database-v1</name>
   <description>PROTO library for proto-google-cloud-spanner-admin-database-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml
index 50aa173a999..ace386ca693 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml
+++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
   <name>proto-google-cloud-spanner-admin-instance-v1</name>
   <description>PROTO library for proto-google-cloud-spanner-admin-instance-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml
index 5771d7a6001..f9d30b28869 100644
--- a/proto-google-cloud-spanner-v1/pom.xml
+++ b/proto-google-cloud-spanner-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-spanner-v1</artifactId>
-  <version>6.25.7</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
+  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
   <name>proto-google-cloud-spanner-v1</name>
   <description>PROTO library for proto-google-cloud-spanner-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.7</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index bd60ffb6a48..d588ed2611f 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -31,7 +31,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner</artifactId>
-      <version>6.25.7</version>
+      <version>6.25.8-SNAPSHOT</version>
     </dependency>
     <!-- {x-version-update-end} -->
     
diff --git a/versions.txt b/versions.txt
index 5746c0f515d..357a42c9284 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,10 +1,10 @@
 # Format:
 # module:released-version:current-version
 
-proto-google-cloud-spanner-admin-instance-v1:6.25.7:6.25.7
-proto-google-cloud-spanner-v1:6.25.7:6.25.7
-proto-google-cloud-spanner-admin-database-v1:6.25.7:6.25.7
-grpc-google-cloud-spanner-v1:6.25.7:6.25.7
-grpc-google-cloud-spanner-admin-instance-v1:6.25.7:6.25.7
-grpc-google-cloud-spanner-admin-database-v1:6.25.7:6.25.7
-google-cloud-spanner:6.25.7:6.25.7
+proto-google-cloud-spanner-admin-instance-v1:6.25.7:6.25.8-SNAPSHOT
+proto-google-cloud-spanner-v1:6.25.7:6.25.8-SNAPSHOT
+proto-google-cloud-spanner-admin-database-v1:6.25.7:6.25.8-SNAPSHOT
+grpc-google-cloud-spanner-v1:6.25.7:6.25.8-SNAPSHOT
+grpc-google-cloud-spanner-admin-instance-v1:6.25.7:6.25.8-SNAPSHOT
+grpc-google-cloud-spanner-admin-database-v1:6.25.7:6.25.8-SNAPSHOT
+google-cloud-spanner:6.25.7:6.25.8-SNAPSHOT

From 2813eb21c9f168e8dea149e40dac188933c7e2db Mon Sep 17 00:00:00 2001
From: WhiteSource Renovate <bot@renovateapp.com>
Date: Fri, 1 Jul 2022 23:12:27 +0200
Subject: [PATCH 02/11] deps: update dependency
 com.google.cloud:google-cloud-trace to v2.3.0 (#1934)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [com.google.cloud:google-cloud-trace](https://togithub.com/googleapis/java-core) | `2.2.0` -> `2.3.0` | [![age](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-trace/2.3.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-trace/2.3.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-trace/2.3.0/compatibility-slim/2.2.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.google.cloud:google-cloud-trace/2.3.0/confidence-slim/2.2.0)](https://docs.renovatebot.com/merge-confidence/) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. ⚠ **Warning**: custom changes will be lost.

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner).
---
 README.md                           | 4 ++--
 samples/install-without-bom/pom.xml | 2 +-
 samples/snapshot/pom.xml            | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index a5067eccd35..4a7495bf860 100644
--- a/README.md
+++ b/README.md
@@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-spanner'
 If you are using Gradle without BOM, add this to your dependencies
 
 ```Groovy
-implementation 'com.google.cloud:google-cloud-spanner:6.25.6'
+implementation 'com.google.cloud:google-cloud-spanner:6.25.7'
 ```
 
 If you are using SBT, add this to your dependencies
 
 ```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.25.6"
+libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.25.7"
 ```
 
 ## Authentication
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 6cdd35614dc..2631508f826 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -22,7 +22,7 @@
     <maven.compiler.source>1.8</maven.compiler.source>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <opencensus.version>0.31.1</opencensus.version>
-    <trace.version>2.2.0</trace.version>
+    <trace.version>2.3.0</trace.version>
     <cloudmonitoring.version>3.3.0</cloudmonitoring.version>
   </properties>
 
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index d588ed2611f..e81438c3394 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -22,7 +22,7 @@
     <maven.compiler.source>1.8</maven.compiler.source>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <opencensus.version>0.31.1</opencensus.version>
-    <trace.version>2.2.0</trace.version>
+    <trace.version>2.3.0</trace.version>
     <cloudmonitoring.version>3.3.0</cloudmonitoring.version>
   </properties>
 

From bddd20b73d7334d0101488764f897ea8b9b4f529 Mon Sep 17 00:00:00 2001
From: WhiteSource Renovate <bot@renovateapp.com>
Date: Mon, 4 Jul 2022 19:09:25 +0200
Subject: [PATCH 03/11] build(deps): update dependency
 org.apache.maven.plugins:maven-assembly-plugin to v3.4.0 (#1936)

---
 samples/snippets/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 6b229cfdc11..7f27e6f95c9 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -119,7 +119,7 @@
     <plugins>
       <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
-        <version>3.3.0</version>
+        <version>3.4.0</version>
         <configuration>
           <descriptors>
             <descriptor>assembly-descriptor.xml</descriptor>

From b685f477806a509c6fc166990894e82858070011 Mon Sep 17 00:00:00 2001
From: WhiteSource Renovate <bot@renovateapp.com>
Date: Mon, 4 Jul 2022 20:40:22 +0200
Subject: [PATCH 04/11] build(deps): update dependency
 org.apache.maven.plugins:maven-failsafe-plugin to v3.0.0-m7 (#1912)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [org.apache.maven.plugins:maven-failsafe-plugin](https://maven.apache.org/surefire/) | `3.0.0-M6` -> `3.0.0-M7` | [![age](https://badges.renovateapi.com/packages/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.0.0-M7/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.0.0-M7/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.0.0-M7/compatibility-slim/3.0.0-M6)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/org.apache.maven.plugins:maven-failsafe-plugin/3.0.0-M7/confidence-slim/3.0.0-M6)](https://docs.renovatebot.com/merge-confidence/) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/java-spanner).
---
 samples/install-without-bom/pom.xml | 2 +-
 samples/snapshot/pom.xml            | 2 +-
 samples/snippets/pom.xml            | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 2631508f826..10f3ea843ff 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -139,7 +139,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-failsafe-plugin</artifactId>
-        <version>3.0.0-M6</version>
+        <version>3.0.0-M7</version>
         <configuration>
           <systemPropertyVariables>
             <spanner.test.instance>spanner-testing-east1</spanner.test.instance>
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index e81438c3394..02704451ed8 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -138,7 +138,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-failsafe-plugin</artifactId>
-        <version>3.0.0-M6</version>
+        <version>3.0.0-M7</version>
         <configuration>
           <systemPropertyVariables>
             <spanner.test.instance>spanner-testing-east1</spanner.test.instance>
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 7f27e6f95c9..e20a95c6b30 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -143,7 +143,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-failsafe-plugin</artifactId>
-        <version>3.0.0-M6</version>
+        <version>3.0.0-M7</version>
         <configuration>
           <systemPropertyVariables>
             <spanner.test.instance>spanner-testing-east1</spanner.test.instance>

From c8a2184c51cc92ec35c759eff68e614fc78fb2e6 Mon Sep 17 00:00:00 2001
From: Gaurav Purohit <purohitgaurav0612@gmail.com>
Date: Tue, 5 Jul 2022 18:57:45 +0530
Subject: [PATCH 05/11] feat: Error Details Improvement (#1929)

feat: Error Details Improvement
---
 .../cloud/spanner/AbortedException.java       | 12 ++-
 ...minRequestsPerMinuteExceededException.java | 12 ++-
 .../spanner/DatabaseNotFoundException.java    | 13 ++-
 .../spanner/InstanceNotFoundException.java    | 12 ++-
 .../spanner/SessionNotFoundException.java     | 13 ++-
 .../cloud/spanner/SpannerException.java       | 84 ++++++++++++++++++-
 .../spanner/SpannerExceptionFactory.java      | 38 ++++++---
 7 files changed, 164 insertions(+), 20 deletions(-)

diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbortedException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbortedException.java
index b3fb0b05328..21b0bb2224a 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbortedException.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbortedException.java
@@ -16,6 +16,7 @@
 
 package com.google.cloud.spanner;
 
+import com.google.api.gax.rpc.ApiException;
 import javax.annotation.Nullable;
 
 /**
@@ -34,6 +35,15 @@ public class AbortedException extends SpannerException {
   /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
   AbortedException(
       DoNotConstructDirectly token, @Nullable String message, @Nullable Throwable cause) {
-    super(token, ErrorCode.ABORTED, IS_RETRYABLE, message, cause);
+    this(token, message, cause, null);
+  }
+
+  /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
+  AbortedException(
+      DoNotConstructDirectly token,
+      @Nullable String message,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
+    super(token, ErrorCode.ABORTED, IS_RETRYABLE, message, cause, apiException);
   }
 }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AdminRequestsPerMinuteExceededException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AdminRequestsPerMinuteExceededException.java
index 11870c94d00..72d8b0ab15d 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AdminRequestsPerMinuteExceededException.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AdminRequestsPerMinuteExceededException.java
@@ -16,6 +16,7 @@
 
 package com.google.cloud.spanner;
 
+import com.google.api.gax.rpc.ApiException;
 import javax.annotation.Nullable;
 
 /**
@@ -31,6 +32,15 @@ public class AdminRequestsPerMinuteExceededException extends SpannerException {
   /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
   AdminRequestsPerMinuteExceededException(
       DoNotConstructDirectly token, @Nullable String message, @Nullable Throwable cause) {
-    super(token, ErrorCode.RESOURCE_EXHAUSTED, true, message, cause);
+    this(token, message, cause, null);
+  }
+
+  /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
+  AdminRequestsPerMinuteExceededException(
+      DoNotConstructDirectly token,
+      @Nullable String message,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
+    super(token, ErrorCode.RESOURCE_EXHAUSTED, true, message, cause, apiException);
   }
 }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseNotFoundException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseNotFoundException.java
index aafd799103e..cc4a2e32f0b 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseNotFoundException.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseNotFoundException.java
@@ -16,6 +16,7 @@
 
 package com.google.cloud.spanner;
 
+import com.google.api.gax.rpc.ApiException;
 import com.google.cloud.spanner.SpannerException.ResourceNotFoundException;
 import com.google.rpc.ResourceInfo;
 import javax.annotation.Nullable;
@@ -34,6 +35,16 @@ public class DatabaseNotFoundException extends ResourceNotFoundException {
       @Nullable String message,
       ResourceInfo resourceInfo,
       @Nullable Throwable cause) {
-    super(token, message, resourceInfo, cause);
+    this(token, message, resourceInfo, cause, null);
+  }
+
+  /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
+  DatabaseNotFoundException(
+      DoNotConstructDirectly token,
+      @Nullable String message,
+      ResourceInfo resourceInfo,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
+    super(token, message, resourceInfo, cause, apiException);
   }
 }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceNotFoundException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceNotFoundException.java
index 6c179ca9b60..82c451f9475 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceNotFoundException.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceNotFoundException.java
@@ -16,6 +16,7 @@
 
 package com.google.cloud.spanner;
 
+import com.google.api.gax.rpc.ApiException;
 import com.google.cloud.spanner.SpannerException.ResourceNotFoundException;
 import com.google.rpc.ResourceInfo;
 import javax.annotation.Nullable;
@@ -34,6 +35,15 @@ public class InstanceNotFoundException extends ResourceNotFoundException {
       @Nullable String message,
       ResourceInfo resourceInfo,
       @Nullable Throwable cause) {
-    super(token, message, resourceInfo, cause);
+    this(token, message, resourceInfo, cause, null);
+  }
+  /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
+  InstanceNotFoundException(
+      DoNotConstructDirectly token,
+      @Nullable String message,
+      ResourceInfo resourceInfo,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
+    super(token, message, resourceInfo, cause, apiException);
   }
 }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionNotFoundException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionNotFoundException.java
index 4e3e08c5c21..f4a62b1954a 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionNotFoundException.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionNotFoundException.java
@@ -16,6 +16,7 @@
 
 package com.google.cloud.spanner;
 
+import com.google.api.gax.rpc.ApiException;
 import com.google.cloud.spanner.SpannerException.ResourceNotFoundException;
 import com.google.rpc.ResourceInfo;
 import javax.annotation.Nullable;
@@ -34,6 +35,16 @@ public class SessionNotFoundException extends ResourceNotFoundException {
       @Nullable String message,
       ResourceInfo resourceInfo,
       @Nullable Throwable cause) {
-    super(token, message, resourceInfo, cause);
+    this(token, message, resourceInfo, cause, null);
+  }
+
+  /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
+  SessionNotFoundException(
+      DoNotConstructDirectly token,
+      @Nullable String message,
+      ResourceInfo resourceInfo,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
+    super(token, message, resourceInfo, cause, apiException);
   }
 }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerException.java
index 8c3af71547e..58076570c20 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerException.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerException.java
@@ -16,6 +16,8 @@
 
 package com.google.cloud.spanner;
 
+import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ErrorDetails;
 import com.google.cloud.grpc.BaseGrpcServiceException;
 import com.google.common.base.Preconditions;
 import com.google.protobuf.util.Durations;
@@ -24,6 +26,7 @@
 import io.grpc.Metadata;
 import io.grpc.Status;
 import io.grpc.protobuf.ProtoUtils;
+import java.util.Map;
 import javax.annotation.Nullable;
 
 /** Base exception type for all exceptions produced by the Cloud Spanner service. */
@@ -36,8 +39,9 @@ public abstract static class ResourceNotFoundException extends SpannerException
         DoNotConstructDirectly token,
         @Nullable String message,
         ResourceInfo resourceInfo,
-        @Nullable Throwable cause) {
-      super(token, ErrorCode.NOT_FOUND, /* retryable */ false, message, cause);
+        @Nullable Throwable cause,
+        @Nullable ApiException apiException) {
+      super(token, ErrorCode.NOT_FOUND, /* retryable */ false, message, cause, apiException);
       this.resourceInfo = resourceInfo;
     }
 
@@ -51,6 +55,7 @@ public String getResourceName() {
       ProtoUtils.keyForProto(RetryInfo.getDefaultInstance());
 
   private final ErrorCode code;
+  private final ApiException apiException;
 
   /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
   SpannerException(
@@ -59,11 +64,23 @@ public String getResourceName() {
       boolean retryable,
       @Nullable String message,
       @Nullable Throwable cause) {
+    this(token, code, retryable, message, cause, null);
+  }
+
+  /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */
+  SpannerException(
+      DoNotConstructDirectly token,
+      ErrorCode code,
+      boolean retryable,
+      @Nullable String message,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
     super(message, cause, code.getCode(), retryable);
     if (token != DoNotConstructDirectly.ALLOWED) {
       throw new AssertionError("Do not construct directly: use SpannerExceptionFactory");
     }
     this.code = Preconditions.checkNotNull(code);
+    this.apiException = apiException;
   }
 
   /** Returns the error code associated with this exception. */
@@ -95,4 +112,67 @@ static long extractRetryDelay(Throwable cause) {
     }
     return -1L;
   }
+
+  /**
+   * Checks the underlying reason of the exception and if it's {@link ApiException} then return the
+   * reason otherwise null.
+   *
+   * @see <a
+   *     href="https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto#L117">Reason</a>
+   * @return the reason of an error.
+   */
+  public String getReason() {
+    if (this.apiException != null) {
+      return this.apiException.getReason();
+    }
+    return null;
+  }
+
+  /**
+   * Checks the underlying reason of the exception and if it's {@link ApiException} then return the
+   * specific domain otherwise null.
+   *
+   * @see <a
+   *     href="https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto#L125">Domain</a>
+   * @return the logical grouping to which the "reason" belongs.
+   */
+  public String getDomain() {
+    if (this.apiException != null) {
+      return this.apiException.getDomain();
+    }
+    return null;
+  }
+
+  /**
+   * Checks the underlying reason of the exception and if it's {@link ApiException} then return a
+   * map of key-value pairs otherwise null.
+   *
+   * @see <a
+   *     href="https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto#L135">Metadata</a>
+   * @return the map of additional structured details about an error.
+   */
+  public Map<String, String> getMetadata() {
+    if (this.apiException != null) {
+      return this.apiException.getMetadata();
+    }
+    return null;
+  }
+
+  /**
+   * Checks the underlying reason of the exception and if it's {@link ApiException} then return the
+   * ErrorDetails otherwise null.
+   *
+   * @see <a
+   *     href="https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto">Status</a>
+   * @see <a
+   *     href="https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto">Error
+   *     Details</a>
+   * @return An object containing getters for structured objects from error_details.proto.
+   */
+  public ErrorDetails getErrorDetails() {
+    if (this.apiException != null) {
+      return this.apiException.getErrorDetails();
+    }
+    return null;
+  }
 }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java
index da17680d6db..2c52192d214 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java
@@ -251,12 +251,15 @@ static StatusRuntimeException createAbortedExceptionWithRetryDelay(
   }
 
   static SpannerException newSpannerExceptionPreformatted(
-      ErrorCode code, @Nullable String message, @Nullable Throwable cause) {
+      ErrorCode code,
+      @Nullable String message,
+      @Nullable Throwable cause,
+      @Nullable ApiException apiException) {
     // This is the one place in the codebase that is allowed to call constructors directly.
     DoNotConstructDirectly token = DoNotConstructDirectly.ALLOWED;
     switch (code) {
       case ABORTED:
-        return new AbortedException(token, message, cause);
+        return new AbortedException(token, message, cause, apiException);
       case RESOURCE_EXHAUSTED:
         ErrorInfo info = extractErrorInfo(cause);
         if (info != null
@@ -265,26 +268,35 @@ static SpannerException newSpannerExceptionPreformatted(
             && AdminRequestsPerMinuteExceededException.ADMIN_REQUESTS_LIMIT_VALUE.equals(
                 info.getMetadataMap()
                     .get(AdminRequestsPerMinuteExceededException.ADMIN_REQUESTS_LIMIT_KEY))) {
-          return new AdminRequestsPerMinuteExceededException(token, message, cause);
+          return new AdminRequestsPerMinuteExceededException(token, message, cause, apiException);
         }
       case NOT_FOUND:
         ResourceInfo resourceInfo = extractResourceInfo(cause);
         if (resourceInfo != null) {
           switch (resourceInfo.getResourceType()) {
             case SESSION_RESOURCE_TYPE:
-              return new SessionNotFoundException(token, message, resourceInfo, cause);
+              return new SessionNotFoundException(
+                  token, message, resourceInfo, cause, apiException);
             case DATABASE_RESOURCE_TYPE:
-              return new DatabaseNotFoundException(token, message, resourceInfo, cause);
+              return new DatabaseNotFoundException(
+                  token, message, resourceInfo, cause, apiException);
             case INSTANCE_RESOURCE_TYPE:
-              return new InstanceNotFoundException(token, message, resourceInfo, cause);
+              return new InstanceNotFoundException(
+                  token, message, resourceInfo, cause, apiException);
           }
         }
         // Fall through to the default.
       default:
-        return new SpannerException(token, code, isRetryable(code, cause), message, cause);
+        return new SpannerException(
+            token, code, isRetryable(code, cause), message, cause, apiException);
     }
   }
 
+  static SpannerException newSpannerExceptionPreformatted(
+      ErrorCode code, @Nullable String message, @Nullable Throwable cause) {
+    return newSpannerExceptionPreformatted(code, message, cause, null);
+  }
+
   private static SpannerException fromApiException(ApiException exception) {
     Status.Code code;
     if (exception.getStatusCode() instanceof GrpcStatusCode) {
@@ -295,12 +307,12 @@ private static SpannerException fromApiException(ApiException exception) {
       code = Status.Code.UNKNOWN;
     }
     ErrorCode errorCode = ErrorCode.fromGrpcStatus(Status.fromCode(code));
-    if (exception.getCause() != null) {
-      return SpannerExceptionFactory.newSpannerException(
-          errorCode, exception.getMessage(), exception.getCause());
-    } else {
-      return SpannerExceptionFactory.newSpannerException(errorCode, exception.getMessage());
-    }
+
+    return SpannerExceptionFactory.newSpannerExceptionPreformatted(
+        errorCode,
+        formatMessage(errorCode, exception.getMessage()),
+        exception.getCause(),
+        exception);
   }
 
   private static boolean isRetryable(ErrorCode code, @Nullable Throwable cause) {

From c667653ec380dccbf205e7b419843da11cf4155a Mon Sep 17 00:00:00 2001
From: Astha Mohta <35952883+asthamohta@users.noreply.github.com>
Date: Wed, 6 Jul 2022 01:58:52 +0530
Subject: [PATCH 06/11] feat: changes to support data, timestamp and arrays in
 IT tests (#1840)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* changes to support data, timestamp and arrays

* changes to support data, timestamp and arrays

* linting

* changes as per review

* linting

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
---
 .../google/cloud/spanner/it/ITQueryTest.java  |  70 +++++--
 .../cloud/spanner/it/ITResultSetGetValue.java | 197 +++++++++++++++++-
 .../google/cloud/spanner/it/ITWriteTest.java  |  73 +++----
 3 files changed, 273 insertions(+), 67 deletions(-)

diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java
index f07bffc2d8f..a691fbf78b4 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 
 import com.google.cloud.ByteArray;
 import com.google.cloud.Date;
@@ -355,7 +356,6 @@ public void bindTimestampNull() {
 
   @Test
   public void bindDate() {
-    assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL);
     Date d = Date.parseDate("2016-09-18");
     Struct row = execute(Statement.newBuilder(selectValueQuery).bind("p1").to(d), Type.date());
     assertThat(row.isNull(0)).isFalse();
@@ -364,7 +364,6 @@ public void bindDate() {
 
   @Test
   public void bindDateNull() {
-    assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL);
     Struct row =
         execute(Statement.newBuilder(selectValueQuery).bind("p1").to((Date) null), Type.date());
     assertThat(row.isNull(0)).isTrue();
@@ -682,13 +681,12 @@ public void bindTimestampArrayNull() {
 
   @Test
   public void bindDateArray() {
-    assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL);
     Date d1 = Date.parseDate("2016-09-18");
     Date d2 = Date.parseDate("2016-09-19");
 
     Struct row =
         execute(
-            Statement.newBuilder("SELECT @v").bind("v").toDateArray(asList(d1, d2, null)),
+            Statement.newBuilder(selectValueQuery).bind("p1").toDateArray(asList(d1, d2, null)),
             Type.array(Type.date()));
     assertThat(row.isNull(0)).isFalse();
     assertThat(row.getDateList(0)).containsExactly(d1, d2, null).inOrder();
@@ -696,10 +694,9 @@ public void bindDateArray() {
 
   @Test
   public void bindDateArrayEmpty() {
-    assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL);
     Struct row =
         execute(
-            Statement.newBuilder("SELECT @v").bind("v").toDateArray(Collections.emptyList()),
+            Statement.newBuilder(selectValueQuery).bind("p1").toDateArray(Collections.emptyList()),
             Type.array(Type.date()));
     assertThat(row.isNull(0)).isFalse();
     assertThat(row.getDateList(0)).containsExactly();
@@ -707,18 +704,16 @@ public void bindDateArrayEmpty() {
 
   @Test
   public void bindDateArrayNull() {
-    assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL);
     Struct row =
         execute(
-            Statement.newBuilder("SELECT @v").bind("v").toDateArray(null), Type.array(Type.date()));
+            Statement.newBuilder(selectValueQuery).bind("p1").toDateArray(null),
+            Type.array(Type.date()));
     assertThat(row.isNull(0)).isTrue();
   }
 
   @Test
-  public void bindNumericArray() {
-    assumeFalse(
-        "array numeric binding is not supported on POSTGRESQL",
-        dialect.dialect == Dialect.POSTGRESQL);
+  public void bindNumericArrayGoogleStandardSQL() {
+    assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
     BigDecimal b1 = new BigDecimal("3.14");
     BigDecimal b2 = new BigDecimal("6.626");
@@ -732,10 +727,22 @@ public void bindNumericArray() {
   }
 
   @Test
-  public void bindNumericArrayEmpty() {
-    assumeFalse(
-        "array numeric binding is not supported on POSTGRESQL",
-        dialect.dialect == Dialect.POSTGRESQL);
+  public void bindNumericArrayPostgreSQL() {
+    assumeTrue(dialect.dialect == Dialect.POSTGRESQL);
+    assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
+    Struct row =
+        execute(
+            Statement.newBuilder(selectValueQuery)
+                .bind("p1")
+                .toPgNumericArray(asList("3.14", "6.626", null)),
+            Type.array(Type.pgNumeric()));
+    assertThat(row.isNull(0)).isFalse();
+    assertThat(row.getStringList(0)).containsExactly("3.14", "6.626", null).inOrder();
+  }
+
+  @Test
+  public void bindNumericArrayEmptyGoogleStandardSQL() {
+    assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
     Struct row =
         execute(
@@ -748,11 +755,22 @@ public void bindNumericArrayEmpty() {
   }
 
   @Test
-  public void bindNumericArrayNull() {
-    assumeFalse(
-        "array numeric binding is not supported on POSTGRESQL",
-        dialect.dialect == Dialect.POSTGRESQL);
+  public void bindNumericArrayEmptyPostgreSQL() {
+    assumeTrue(dialect.dialect == Dialect.POSTGRESQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
+    Struct row =
+        execute(
+            Statement.newBuilder(selectValueQuery)
+                .bind("p1")
+                .toPgNumericArray(Collections.emptyList()),
+            Type.array(Type.pgNumeric()));
+    assertThat(row.isNull(0)).isFalse();
+    assertThat(row.getStringList(0)).containsExactly();
+  }
+
+  @Test
+  public void bindNumericArrayNullGoogleStandardSQL() {
+    assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL);
     Struct row =
         execute(
             Statement.newBuilder(selectValueQuery).bind("p1").toNumericArray(null),
@@ -760,6 +778,16 @@ public void bindNumericArrayNull() {
     assertThat(row.isNull(0)).isTrue();
   }
 
+  @Test
+  public void bindNumericArrayNullPostgreSQL() {
+    assumeTrue(dialect.dialect == Dialect.POSTGRESQL);
+    Struct row =
+        execute(
+            Statement.newBuilder(selectValueQuery).bind("p1").toPgNumericArray(null),
+            Type.array(Type.pgNumeric()));
+    assertThat(row.isNull(0)).isTrue();
+  }
+
   @Test
   public void bindNumericArray_doesNotPreservePrecision() {
     assumeFalse(
@@ -771,7 +799,7 @@ public void bindNumericArray_doesNotPreservePrecision() {
 
     Struct row =
         execute(
-            Statement.newBuilder("SELECT @v").bind("v").toNumericArray(asList(b1, b2, null)),
+            Statement.newBuilder(selectValueQuery).bind("p1").toNumericArray(asList(b1, b2, null)),
             Type.array(Type.numeric()));
     assertThat(row.isNull(0)).isFalse();
     assertThat(row.getBigDecimalList(0))
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java
index e48b2f35fd0..68aeb2a0e99 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeFalse;
 
 import com.google.cloud.ByteArray;
 import com.google.cloud.Date;
@@ -128,7 +127,17 @@ public static void beforeClass()
                           + "float64 DOUBLE PRECISION,"
                           + "numeric NUMERIC,"
                           + "string VARCHAR,"
-                          + "bytes BYTEA"
+                          + "bytes BYTEA,"
+                          + "timestamp TIMESTAMPTZ,"
+                          + "date DATE,"
+                          + "boolArray BOOL[],"
+                          + "int64Array BIGINT[],"
+                          + "float64Array DOUBLE PRECISION[],"
+                          + "numericArray NUMERIC[],"
+                          + "stringArray VARCHAR[],"
+                          + "bytesArray BYTEA[],"
+                          + "dateArray DATE[],"
+                          + "timestampArray TIMESTAMPTZ[]"
                           + ")"));
       postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase);
     }
@@ -264,6 +273,32 @@ public void testReadNonNullValuesPostgreSQL() {
                 .to("stringValue")
                 .set("bytes")
                 .to(ByteArray.copyFrom("bytesValue"))
+                .set("date")
+                .to(Date.fromYearMonthDay(2021, 1, 2))
+                .set("timestamp")
+                .to(Timestamp.ofTimeSecondsAndNanos(1, 0))
+                .set("boolArray")
+                .toBoolArray(new boolean[] {false, true})
+                .set("int64Array")
+                .toInt64Array(new long[] {100L, 200L})
+                .set("float64Array")
+                .toFloat64Array(new double[] {1000D, 2000D})
+                .set("numericArray")
+                .toNumericArray(Arrays.asList(new BigDecimal("10000"), new BigDecimal("20000")))
+                .set("stringArray")
+                .toStringArray(Arrays.asList("string1", "string2"))
+                .set("bytesArray")
+                .toBytesArray(
+                    Arrays.asList(ByteArray.copyFrom("bytes1"), ByteArray.copyFrom("bytes2")))
+                .set("timestampArray")
+                .toTimestampArray(
+                    Arrays.asList(
+                        Timestamp.ofTimeSecondsAndNanos(10, 0),
+                        Timestamp.ofTimeSecondsAndNanos(20, 0)))
+                .set("dateArray")
+                .toDateArray(
+                    Arrays.asList(
+                        Date.fromYearMonthDay(2021, 2, 3), Date.fromYearMonthDay(2021, 3, 4)))
                 .build()));
 
     try (ResultSet resultSet =
@@ -278,6 +313,34 @@ public void testReadNonNullValuesPostgreSQL() {
       assertEquals(Value.pgNumeric("30"), resultSet.getValue("numeric"));
       assertEquals(Value.string("stringValue"), resultSet.getValue("string"));
       assertEquals(Value.bytes(ByteArray.copyFrom("bytesValue")), resultSet.getValue("bytes"));
+      assertEquals(
+          Value.timestamp(Timestamp.ofTimeSecondsAndNanos(1, 0)), resultSet.getValue("timestamp"));
+      assertEquals(Value.date(Date.fromYearMonthDay(2021, 1, 2)), resultSet.getValue("date"));
+      assertEquals(Value.boolArray(new boolean[] {false, true}), resultSet.getValue("boolarray"));
+      assertEquals(Value.int64Array(new long[] {100L, 200L}), resultSet.getValue("int64array"));
+      assertArrayEquals(
+          new double[] {1000D, 2000D},
+          Doubles.toArray(resultSet.getValue("float64array").getFloat64Array()),
+          1e-15);
+      assertEquals(
+          Value.pgNumericArray(Arrays.asList("10000", "20000")),
+          resultSet.getValue("numericarray"));
+      assertEquals(
+          Value.stringArray(Arrays.asList("string1", "string2")),
+          resultSet.getValue("stringarray"));
+      assertEquals(
+          Value.bytesArray(
+              Arrays.asList(ByteArray.copyFrom("bytes1"), ByteArray.copyFrom("bytes2"))),
+          resultSet.getValue("bytesarray"));
+      assertEquals(
+          Value.timestampArray(
+              Arrays.asList(
+                  Timestamp.ofTimeSecondsAndNanos(10, 0), Timestamp.ofTimeSecondsAndNanos(20, 0))),
+          resultSet.getValue("timestamparray"));
+      assertEquals(
+          Value.dateArray(
+              Arrays.asList(Date.fromYearMonthDay(2021, 2, 3), Date.fromYearMonthDay(2021, 3, 4))),
+          resultSet.getValue("datearray"));
     }
   }
 
@@ -367,12 +430,42 @@ public void testReadNullValuesPostgreSQL() {
       assertThrows(IllegalStateException.class, () -> resultSet.getValue("string").getString());
       assertTrue(resultSet.getValue("bytes").isNull());
       assertThrows(IllegalStateException.class, () -> resultSet.getValue("bytes").getBytes());
+      assertTrue(resultSet.getValue("timestamp").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("timestamp").getTimestamp());
+      assertTrue(resultSet.getValue("date").isNull());
+      assertThrows(IllegalStateException.class, () -> resultSet.getValue("date").getDate());
+      assertTrue(resultSet.getValue("boolarray").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("boolarray").getBoolArray());
+      assertTrue(resultSet.getValue("int64array").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("int64array").getInt64Array());
+      assertTrue(resultSet.getValue("float64array").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("float64array").getFloat64Array());
+      assertTrue(resultSet.getValue("numericarray").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("numericarray").getNumericArray());
+      assertTrue(resultSet.getValue("stringarray").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("stringarray").getStringArray());
+      assertTrue(resultSet.getValue("bytesarray").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("bytesarray").getBytesArray());
+      assertTrue(resultSet.getValue("timestamparray").isNull());
+      assertThrows(
+          IllegalStateException.class,
+          () -> resultSet.getValue("timestamparray").getTimestampArray());
+      assertTrue(resultSet.getValue("datearray").isNull());
+      assertThrows(
+          IllegalStateException.class, () -> resultSet.getValue("datearray").getDateArray());
     }
   }
 
   @Test
-  public void testReadNullValuesInArrays() {
-    assumeFalse("PostgreSQL does not yet support Arrays", dialect.dialect == Dialect.POSTGRESQL);
+  public void testReadNullValuesInArraysGoogleStandardSQL() {
+    Assume.assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL);
     databaseClient.write(
         Collections.singletonList(
             Mutation.newInsertBuilder(TABLE_NAME)
@@ -429,6 +522,59 @@ public void testReadNullValuesInArrays() {
     }
   }
 
+  @Test
+  public void testReadNullValuesInArraysPostgreSQL() {
+    Assume.assumeTrue(dialect.dialect == Dialect.POSTGRESQL);
+    databaseClient.write(
+        Collections.singletonList(
+            Mutation.newInsertBuilder(TABLE_NAME)
+                .set("Id")
+                .to(3L)
+                .set("boolArray")
+                .toBoolArray(Arrays.asList(true, null))
+                .set("int64Array")
+                .toInt64Array(Arrays.asList(null, 2L))
+                .set("float64Array")
+                .toFloat64Array(Arrays.asList(null, 10D))
+                .set("numericArray")
+                .toNumericArray(Arrays.asList(new BigDecimal("10000"), null))
+                .set("stringArray")
+                .toStringArray(Arrays.asList(null, "string2"))
+                .set("bytesArray")
+                .toBytesArray(Arrays.asList(ByteArray.copyFrom("bytes1"), null))
+                .set("timestampArray")
+                .toTimestampArray(Arrays.asList(null, Timestamp.ofTimeSecondsAndNanos(20, 0)))
+                .set("dateArray")
+                .toDateArray(Arrays.asList(Date.fromYearMonthDay(2021, 2, 3), null))
+                .build()));
+
+    try (ResultSet resultSet =
+        databaseClient
+            .singleUse()
+            .executeQuery(Statement.of("SELECT * FROM " + TABLE_NAME + " WHERE Id = 3"))) {
+      resultSet.next();
+
+      assertEquals(Value.int64(3L), resultSet.getValue("id"));
+      assertEquals(Value.boolArray(Arrays.asList(true, null)), resultSet.getValue("boolarray"));
+      assertEquals(Value.int64Array(Arrays.asList(null, 2L)), resultSet.getValue("int64array"));
+      assertNull(resultSet.getValue("float64array").getFloat64Array().get(0));
+      assertEquals(10D, resultSet.getValue("float64array").getFloat64Array().get(1), DELTA);
+      assertEquals(
+          Value.pgNumericArray(Arrays.asList("10000", null)), resultSet.getValue("numericarray"));
+      assertEquals(
+          Value.stringArray(Arrays.asList(null, "string2")), resultSet.getValue("stringarray"));
+      assertEquals(
+          Value.bytesArray(Arrays.asList(ByteArray.copyFrom("bytes1"), null)),
+          resultSet.getValue("bytesarray"));
+      assertEquals(
+          Value.timestampArray(Arrays.asList(null, Timestamp.ofTimeSecondsAndNanos(20, 0))),
+          resultSet.getValue("timestamparray"));
+      assertEquals(
+          Value.dateArray(Arrays.asList(Date.fromYearMonthDay(2021, 2, 3), null)),
+          resultSet.getValue("datearray"));
+    }
+  }
+
   @Test
   public void testReadNonFloat64LiteralsGoogleStandardSQL() {
     Assume.assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL);
@@ -570,7 +716,16 @@ public void testReadNonFloat64LiteralsPostgreSQL() {
                         + "1 AS int64,"
                         + "CAST('100' AS numeric) AS numeric,"
                         + "'stringValue' AS string,"
-                        + "CAST('bytesValue' AS BYTEA) AS bytes"))) {
+                        + "CAST('bytesValue' AS BYTEA) AS bytes,"
+                        + "CAST('1970-01-01T00:00:01 UTC' AS TIMESTAMPTZ) AS timestamp,"
+                        + "CAST('2021-02-03' AS DATE) AS date,"
+                        + "ARRAY[false, true] AS boolArray,"
+                        + "ARRAY[1, 2] AS int64Array,"
+                        + "ARRAY[CAST('100' AS NUMERIC), CAST('200' AS NUMERIC)] AS numericArray,"
+                        + "ARRAY['string1', 'string2'] AS stringArray,"
+                        + "ARRAY[CAST('bytes1' AS BYTEA), CAST('bytes2' AS BYTEA)] AS bytesArray,"
+                        + "ARRAY[CAST('1970-01-01T00:00:01 UTC' AS TIMESTAMPTZ), CAST('1970-01-01T00:00:02 UTC' AS TIMESTAMPTZ)] AS timestampArray,"
+                        + "ARRAY[CAST('2020-01-02' AS DATE), CAST('2021-02-03' AS DATE)] AS dateArray"))) {
       resultSet.next();
 
       assertEquals(Value.bool(true), resultSet.getValue("bool"));
@@ -578,6 +733,29 @@ public void testReadNonFloat64LiteralsPostgreSQL() {
       assertEquals(Value.pgNumeric("100"), resultSet.getValue("numeric"));
       assertEquals(Value.string("stringValue"), resultSet.getValue("string"));
       assertEquals(Value.bytes(ByteArray.copyFrom("bytesValue")), resultSet.getValue("bytes"));
+      assertEquals(
+          Value.timestamp(Timestamp.ofTimeSecondsAndNanos(1, 0)), resultSet.getValue("timestamp"));
+      assertEquals(Value.date(Date.fromYearMonthDay(2021, 2, 3)), resultSet.getValue("date"));
+      assertEquals(Value.boolArray(new boolean[] {false, true}), resultSet.getValue("boolarray"));
+      assertEquals(Value.int64Array(new long[] {1L, 2L}), resultSet.getValue("int64array"));
+      assertEquals(
+          Value.pgNumericArray(Arrays.asList("100", "200")), resultSet.getValue("numericarray"));
+      assertEquals(
+          Value.stringArray(Arrays.asList("string1", "string2")),
+          resultSet.getValue("stringarray"));
+      assertEquals(
+          Value.bytesArray(
+              Arrays.asList(ByteArray.copyFrom("bytes1"), ByteArray.copyFrom("bytes2"))),
+          resultSet.getValue("bytesarray"));
+      assertEquals(
+          Value.timestampArray(
+              Arrays.asList(
+                  Timestamp.ofTimeSecondsAndNanos(1, 0), Timestamp.ofTimeSecondsAndNanos(2, 0))),
+          resultSet.getValue("timestamparray"));
+      assertEquals(
+          Value.dateArray(
+              Arrays.asList(Date.fromYearMonthDay(2020, 1, 2), Date.fromYearMonthDay(2021, 2, 3))),
+          resultSet.getValue("datearray"));
     }
   }
 
@@ -615,9 +793,16 @@ public void testReadFloat64LiteralsGoogleStandardSQL() {
   public void testReadFloat64LiteralsPostgreSQL() {
     Assume.assumeTrue(dialect.dialect == Dialect.POSTGRESQL);
     try (ResultSet resultSet =
-        databaseClient.singleUse().executeQuery(Statement.of("SELECT 10.0 AS float64"))) {
+        databaseClient
+            .singleUse()
+            .executeQuery(
+                Statement.of("SELECT 10.0 AS float64, " + "ARRAY[20.0, 30.0] AS float64Array"))) {
       resultSet.next();
       assertEquals(10D, resultSet.getValue("float64").getFloat64(), DELTA);
+      assertArrayEquals(
+          new double[] {20D, 30D},
+          Doubles.toArray(resultSet.getValue("float64array").getFloat64Array()),
+          DELTA);
     }
   }
 }
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java
index d274cdb91f5..2428e75c994 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java
@@ -126,7 +126,17 @@ public static List<DialectTestParameter> data() {
           + "  Float64Value        DOUBLE PRECISION,"
           + "  StringValue         VARCHAR,"
           + "  BytesValue          BYTEA,"
-          + "  NumericValue        NUMERIC"
+          + "  TimestampValue      TIMESTAMPTZ,"
+          + "  DateValue           DATE,"
+          + "  NumericValue        NUMERIC,"
+          + "  BoolArrayValue      BOOL[],"
+          + "  Int64ArrayValue     BIGINT[],"
+          + "  Float64ArrayValue   DOUBLE PRECISION[],"
+          + "  StringArrayValue    VARCHAR[],"
+          + "  BytesArrayValue     BYTEA[],"
+          + "  TimestampArrayValue TIMESTAMPTZ[],"
+          + "  DateArrayValue      DATE[],"
+          + "  NumericArrayValue   NUMERIC[]"
           + ")";
 
   private static final String GOOGLE_STANDARD_SQL_SCHEMA_WITHOUT_NUMERIC_AND_JSON =
@@ -492,7 +502,6 @@ public void writeTimestamp() {
 
   @Test
   public void writeTimestampNull() {
-    assumeFalse("PostgreSQL does not yet support Timestamp", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("TimestampValue").to((Timestamp) null).build());
     Struct row = readLastRow("TimestampValue");
     assertThat(row.isNull(0)).isTrue();
@@ -500,7 +509,8 @@ public void writeTimestampNull() {
 
   @Test
   public void writeCommitTimestamp() {
-    assumeFalse("PostgreSQL does not yet support Timestamp", dialect.dialect == Dialect.POSTGRESQL);
+    assumeFalse(
+        "PostgreSQL does not yet support Commit Timestamp", dialect.dialect == Dialect.POSTGRESQL);
     Timestamp commitTimestamp =
         write(baseInsert().set("TimestampValue").to(Value.COMMIT_TIMESTAMP).build());
     Struct row = readLastRow("TimestampValue");
@@ -509,7 +519,6 @@ public void writeCommitTimestamp() {
 
   @Test
   public void writeDate() {
-    assumeFalse("PostgreSQL does not yet support Date", dialect.dialect == Dialect.POSTGRESQL);
     Date date = Date.parseDate("2016-09-15");
     write(baseInsert().set("DateValue").to(date).build());
     Struct row = readLastRow("DateValue");
@@ -519,7 +528,6 @@ public void writeDate() {
 
   @Test
   public void writeDateNull() {
-    assumeFalse("PostgreSQL does not yet support Date", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("DateValue").to((Date) null).build());
     Struct row = readLastRow("DateValue");
     assertThat(row.isNull(0)).isTrue();
@@ -548,7 +556,6 @@ public void writeNumericNull() {
 
   @Test
   public void writeBoolArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("BoolArrayValue").toBoolArray((boolean[]) null).build());
     Struct row = readLastRow("BoolArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -556,7 +563,6 @@ public void writeBoolArrayNull() {
 
   @Test
   public void writeBoolArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("BoolArrayValue").toBoolArray(new boolean[] {}).build());
     Struct row = readLastRow("BoolArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -565,7 +571,6 @@ public void writeBoolArrayEmpty() {
 
   @Test
   public void writeBoolArray() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("BoolArrayValue").toBoolArray(Arrays.asList(true, null, false)).build());
     Struct row = readLastRow("BoolArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -580,7 +585,6 @@ public void writeBoolArray() {
 
   @Test
   public void writeBoolArrayNoNulls() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("BoolArrayValue").toBoolArray(Arrays.asList(true, false)).build());
     Struct row = readLastRow("BoolArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -589,7 +593,6 @@ public void writeBoolArrayNoNulls() {
 
   @Test
   public void writeInt64ArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Int64ArrayValue").toInt64Array((long[]) null).build());
     Struct row = readLastRow("Int64ArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -597,7 +600,6 @@ public void writeInt64ArrayNull() {
 
   @Test
   public void writeInt64ArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Int64ArrayValue").toInt64Array(new long[] {}).build());
     Struct row = readLastRow("Int64ArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -606,7 +608,6 @@ public void writeInt64ArrayEmpty() {
 
   @Test
   public void writeInt64Array() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Int64ArrayValue").toInt64Array(Arrays.asList(1L, 2L, null)).build());
     Struct row = readLastRow("Int64ArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -621,7 +622,6 @@ public void writeInt64Array() {
 
   @Test
   public void writeInt64ArrayNoNulls() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Int64ArrayValue").toInt64Array(Arrays.asList(1L, 2L)).build());
     Struct row = readLastRow("Int64ArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -630,7 +630,6 @@ public void writeInt64ArrayNoNulls() {
 
   @Test
   public void writeFloat64ArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Float64ArrayValue").toFloat64Array((double[]) null).build());
     Struct row = readLastRow("Float64ArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -638,7 +637,6 @@ public void writeFloat64ArrayNull() {
 
   @Test
   public void writeFloat64ArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Float64ArrayValue").toFloat64Array(new double[] {}).build());
     Struct row = readLastRow("Float64ArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -647,7 +645,6 @@ public void writeFloat64ArrayEmpty() {
 
   @Test
   public void writeFloat64Array() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(
         baseInsert()
             .set("Float64ArrayValue")
@@ -666,7 +663,6 @@ public void writeFloat64Array() {
 
   @Test
   public void writeFloat64ArrayNoNulls() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("Float64ArrayValue").toFloat64Array(Arrays.asList(1.0, 2.0)).build());
     Struct row = readLastRow("Float64ArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -677,7 +673,6 @@ public void writeFloat64ArrayNoNulls() {
 
   @Test
   public void writeStringArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("StringArrayValue").toStringArray(null).build());
     Struct row = readLastRow("StringArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -685,7 +680,6 @@ public void writeStringArrayNull() {
 
   @Test
   public void writeStringArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("StringArrayValue").toStringArray(Collections.emptyList()).build());
     Struct row = readLastRow("StringArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -694,7 +688,6 @@ public void writeStringArrayEmpty() {
 
   @Test
   public void writeStringArray() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(
         baseInsert().set("StringArrayValue").toStringArray(Arrays.asList("a", null, "b")).build());
     Struct row = readLastRow("StringArrayValue");
@@ -753,7 +746,6 @@ public void writeJsonArrayNoNulls() {
 
   @Test
   public void writeBytesArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("BytesArrayValue").toBytesArray(null).build());
     Struct row = readLastRow("BytesArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -761,7 +753,6 @@ public void writeBytesArrayNull() {
 
   @Test
   public void writeBytesArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("BytesArrayValue").toBytesArray(Collections.emptyList()).build());
     Struct row = readLastRow("BytesArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -770,7 +761,6 @@ public void writeBytesArrayEmpty() {
 
   @Test
   public void writeBytesArray() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     List<ByteArray> data = Arrays.asList(ByteArray.copyFrom("a"), ByteArray.copyFrom("b"), null);
     write(baseInsert().set("BytesArrayValue").toBytesArray(data).build());
     Struct row = readLastRow("BytesArrayValue");
@@ -780,7 +770,6 @@ public void writeBytesArray() {
 
   @Test
   public void writeTimestampArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("TimestampArrayValue").toTimestampArray(null).build());
     Struct row = readLastRow("TimestampArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -788,7 +777,6 @@ public void writeTimestampArrayNull() {
 
   @Test
   public void writeTimestampArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(
         baseInsert().set("TimestampArrayValue").toTimestampArray(Collections.emptyList()).build());
     Struct row = readLastRow("TimestampArrayValue");
@@ -798,7 +786,6 @@ public void writeTimestampArrayEmpty() {
 
   @Test
   public void writeTimestampArray() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     Timestamp t1 = Timestamp.parseTimestamp("2016-09-18T00:00:00Z");
     Timestamp t2 = Timestamp.parseTimestamp("2016-09-19T00:00:00Z");
     write(
@@ -813,7 +800,6 @@ public void writeTimestampArray() {
 
   @Test
   public void writeDateArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("DateArrayValue").toDateArray(null).build());
     Struct row = readLastRow("DateArrayValue");
     assertThat(row.isNull(0)).isTrue();
@@ -821,7 +807,6 @@ public void writeDateArrayNull() {
 
   @Test
   public void writeDateArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     write(baseInsert().set("DateArrayValue").toDateArray(Collections.emptyList()).build());
     Struct row = readLastRow("DateArrayValue");
     assertThat(row.isNull(0)).isFalse();
@@ -830,7 +815,6 @@ public void writeDateArrayEmpty() {
 
   @Test
   public void writeDateArray() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     Date d1 = Date.parseDate("2016-09-18");
     Date d2 = Date.parseDate("2016-09-19");
     write(baseInsert().set("DateArrayValue").toDateArray(Arrays.asList(d1, null, d2)).build());
@@ -841,7 +825,6 @@ public void writeDateArray() {
 
   @Test
   public void writeNumericArrayNull() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
     write(baseInsert().set("NumericArrayValue").toNumericArray(null).build());
     Struct row = readLastRow("NumericArrayValue");
@@ -850,17 +833,19 @@ public void writeNumericArrayNull() {
 
   @Test
   public void writeNumericArrayEmpty() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
     write(baseInsert().set("NumericArrayValue").toNumericArray(ImmutableList.of()).build());
     Struct row = readLastRow("NumericArrayValue");
     assertThat(row.isNull(0)).isFalse();
-    assertThat(row.getBigDecimalList(0)).containsExactly();
+    if (dialect.dialect == Dialect.GOOGLE_STANDARD_SQL) {
+      assertThat(row.getBigDecimalList(0)).containsExactly();
+    } else {
+      assertThat(row.getStringList(0)).containsExactly();
+    }
   }
 
   @Test
   public void writeNumericArray() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
     write(
         baseInsert()
@@ -870,14 +855,16 @@ public void writeNumericArray() {
             .build());
     Struct row = readLastRow("NumericArrayValue");
     assertThat(row.isNull(0)).isFalse();
-    assertThat(row.getBigDecimalList(0))
-        .containsExactly(BigDecimal.valueOf(3141592, 6), BigDecimal.valueOf(6626, 3), null)
-        .inOrder();
+    if (dialect.dialect == Dialect.GOOGLE_STANDARD_SQL) {
+      assertThat(row.getBigDecimalList(0))
+          .containsExactly(BigDecimal.valueOf(3141592, 6), BigDecimal.valueOf(6626, 3), null);
+    } else {
+      assertThat(row.getStringList(0)).containsExactly("3.141592", "6.626", null).inOrder();
+    }
   }
 
   @Test
   public void writeNumericArrayNoNulls() {
-    assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL);
     assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator());
     write(
         baseInsert()
@@ -886,9 +873,15 @@ public void writeNumericArrayNoNulls() {
             .build());
     Struct row = readLastRow("NumericArrayValue");
     assertThat(row.isNull(0)).isFalse();
-    assertThat(row.getBigDecimalList(0))
-        .containsExactly(BigDecimal.valueOf(3141592, 6), BigDecimal.valueOf(6626, 3))
-        .inOrder();
+    if (dialect.dialect == Dialect.GOOGLE_STANDARD_SQL) {
+      assertThat(row.getBigDecimalList(0))
+          .containsExactly(BigDecimal.valueOf(3141592, 6), BigDecimal.valueOf(6626, 3));
+    } else {
+      assertThat(row.getStringList(0))
+          .containsExactly(
+              BigDecimal.valueOf(3141592, 6).toString(), BigDecimal.valueOf(6626, 3).toString())
+          .inOrder();
+    }
   }
 
   @Test

From 289bf7955a08827faa42f29e29813eb5ee61a2e8 Mon Sep 17 00:00:00 2001
From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com>
Date: Fri, 8 Jul 2022 20:00:31 +0000
Subject: [PATCH 07/11] chore: fix minor typos in README and pom templates
 (#1479) (#1941)

Source-Link: https://github.com/googleapis/synthtool/commit/18d4e9bb50d0dfb3291de18c51b96a2c835e2446
Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:f8374176dc59291f05dd3fec927a9da2cda687a9ef4de32e77f699a2be12ab45
---
 .github/.OwlBot.lock.yaml | 4 ++--
 README.md                 | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml
index a454a61e8dc..1b645c01291 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/.OwlBot.lock.yaml
@@ -13,5 +13,5 @@
 # limitations under the License.
 docker:
   image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest
-  digest: sha256:6d4e3a15c62cfdcb823d60e16da7521e7c6fc00eba07c8ff12e4de9924a57d28
-# created: 2022-06-29T23:17:33.110417661Z
+  digest: sha256:f8374176dc59291f05dd3fec927a9da2cda687a9ef4de32e77f699a2be12ab45
+# created: 2022-07-07T14:26:11.880812641Z
diff --git a/README.md b/README.md
index 4a7495bf860..f438c296463 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Java idiomatic client for [Cloud Spanner][product-docs].
 
 ## Quickstart
 
-If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file
+If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file:
 
 ```xml
 <dependencyManagement>
@@ -46,20 +46,20 @@ If you are using Maven without BOM, add this to your dependencies:
 
 ```
 
-If you are using Gradle 5.x or later, add this to your dependencies
+If you are using Gradle 5.x or later, add this to your dependencies:
 
 ```Groovy
 implementation platform('com.google.cloud:libraries-bom:25.4.0')
 
 implementation 'com.google.cloud:google-cloud-spanner'
 ```
-If you are using Gradle without BOM, add this to your dependencies
+If you are using Gradle without BOM, add this to your dependencies:
 
 ```Groovy
 implementation 'com.google.cloud:google-cloud-spanner:6.25.7'
 ```
 
-If you are using SBT, add this to your dependencies
+If you are using SBT, add this to your dependencies:
 
 ```Scala
 libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.25.7"

From 00b38178e851401e293aa457f7ba5ea593a7b7c5 Mon Sep 17 00:00:00 2001
From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com>
Date: Tue, 12 Jul 2022 10:57:52 +0530
Subject: [PATCH 08/11] feat: Adding two new fields for Instance create_time
 and update_time (#1908)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* feat: add Session creator role
docs: clarify transaction semantics

PiperOrigin-RevId: 452634948

Source-Link: https://github.com/googleapis/googleapis/commit/df51ec8e93d8de4b85eae18db945b846f58f2728

Source-Link: https://github.com/googleapis/googleapis-gen/commit/25426f6fd17c5229e17a1f37858cb6c1738f0cad
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMjU0MjZmNmZkMTdjNTIyOWUxN2ExZjM3ODU4Y2I2YzE3MzhmMGNhZCJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* chore: Integrate new gapic-generator-java and rules_gapic

PiperOrigin-RevId: 454027580

Source-Link: https://github.com/googleapis/googleapis/commit/1b222777baa702e7135610355706570ed2b56318

Source-Link: https://github.com/googleapis/googleapis-gen/commit/e04cea20d0d12eb5c3bdb360a9e72b654edcb638
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiZTA0Y2VhMjBkMGQxMmViNWMzYmRiMzYwYTllNzJiNjU0ZWRjYjYzOCJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* feat: Enable REST transport for most of Java and Go clients

PiperOrigin-RevId: 456641589

Source-Link: https://github.com/googleapis/googleapis/commit/8a251f5225b789b2383207ffd978f6aa3d77fcf7

Source-Link: https://github.com/googleapis/googleapis-gen/commit/4ca52a529cf01308d9714950edffbea3560cfbdb
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNGNhNTJhNTI5Y2YwMTMwOGQ5NzE0OTUwZWRmZmJlYTM1NjBjZmJkYiJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* deps: adding gax-httpjson

* fix: update gapic-generator-java with mock service generation fixes

PiperOrigin-RevId: 457524730

Source-Link: https://github.com/googleapis/googleapis/commit/917e7f21cb1dc062744c6694437cdd46219f28cb

Source-Link: https://github.com/googleapis/googleapis-gen/commit/2497f9a069d3f6b2d6810d5a4e239cda1e7e5a39
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMjQ5N2Y5YTA2OWQzZjZiMmQ2ODEwZDVhNGUyMzljZGExZTdlNWEzOSJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* feat: Adding two new fields for Instance create_time and update_time

PiperOrigin-RevId: 458877561

Source-Link: https://github.com/googleapis/googleapis/commit/207bf593dc2eed95581bb38bdf95b9e0648acd24

Source-Link: https://github.com/googleapis/googleapis-gen/commit/5ede6e4fbc14d76f9a6f48152a16d8141d8aff52
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNWVkZTZlNGZiYzE0ZDc2ZjlhNmY0ODE1MmExNmQ4MTQxZDhhZmY1MiJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Co-authored-by: Tomo Suzuki <suztomo@google.com>
---
 google-cloud-spanner/pom.xml                  |   16 +
 .../database/v1/DatabaseAdminClient.java      |   47 +-
 .../database/v1/DatabaseAdminSettings.java    |   23 +-
 .../database/v1/stub/DatabaseAdminStub.java   |    6 +-
 .../v1/stub/DatabaseAdminStubSettings.java    |   53 +-
 .../HttpJsonDatabaseAdminCallableFactory.java |  105 +
 .../v1/stub/HttpJsonDatabaseAdminStub.java    | 1270 ++++++++++
 .../instance/v1/InstanceAdminClient.java      |   69 +-
 .../instance/v1/InstanceAdminSettings.java    |   23 +-
 .../HttpJsonInstanceAdminCallableFactory.java |  105 +
 .../v1/stub/HttpJsonInstanceAdminStub.java    |  755 ++++++
 .../instance/v1/stub/InstanceAdminStub.java   |    6 +-
 .../v1/stub/InstanceAdminStubSettings.java    |   53 +-
 .../cloud/spanner/v1/SpannerClient.java       |   16 +-
 .../cloud/spanner/v1/SpannerSettings.java     |   23 +-
 .../stub/HttpJsonSpannerCallableFactory.java  |  105 +
 .../spanner/v1/stub/HttpJsonSpannerStub.java  |  939 +++++++
 .../spanner/v1/stub/SpannerStubSettings.java  |   52 +-
 .../v1/DatabaseAdminClientHttpJsonTest.java   | 2171 +++++++++++++++++
 .../v1/InstanceAdminClientHttpJsonTest.java   | 1061 ++++++++
 .../instance/v1/InstanceAdminClientTest.java  |   23 +-
 .../spanner/v1/SpannerClientHttpJsonTest.java | 1314 ++++++++++
 .../cloud/spanner/v1/SpannerClientTest.java   |    4 +
 .../admin/instance/v1/InstanceAdminGrpc.java  |    8 +-
 .../spanner/admin/instance/v1/Instance.java   |  682 +++++-
 .../admin/instance/v1/InstanceConfig.java     |   40 +-
 .../instance/v1/InstanceConfigOrBuilder.java  |   12 +-
 .../admin/instance/v1/InstanceOrBuilder.java  |  109 +-
 .../v1/SpannerInstanceAdminProto.java         |  212 +-
 .../instance/v1/spanner_instance_admin.proto  |   32 +-
 .../com/google/spanner/v1/ResultSetProto.java |   53 +-
 .../java/com/google/spanner/v1/Session.java   |  179 ++
 .../google/spanner/v1/SessionOrBuilder.java   |   25 +
 .../com/google/spanner/v1/SpannerProto.java   |  365 +--
 .../google/spanner/v1/TransactionOptions.java |  146 +-
 .../google/spanner/v1/commit_response.proto   |    2 +-
 .../main/proto/google/spanner/v1/keys.proto   |    2 +-
 .../proto/google/spanner/v1/mutation.proto    |    2 +-
 .../proto/google/spanner/v1/query_plan.proto  |    2 +-
 .../proto/google/spanner/v1/result_set.proto  |    3 +-
 .../proto/google/spanner/v1/spanner.proto     |    5 +-
 .../proto/google/spanner/v1/transaction.proto |   94 +-
 .../main/proto/google/spanner/v1/type.proto   |    2 +-
 43 files changed, 9686 insertions(+), 528 deletions(-)
 create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminCallableFactory.java
 create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminStub.java
 create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminCallableFactory.java
 create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminStub.java
 create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerCallableFactory.java
 create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerStub.java
 create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java
 create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientHttpJsonTest.java
 create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java

diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml
index 9e469d0961a..c9c66fca10d 100644
--- a/google-cloud-spanner/pom.xml
+++ b/google-cloud-spanner/pom.xml
@@ -271,6 +271,10 @@
       <groupId>com.google.api</groupId>
       <artifactId>gax-grpc</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.google.api</groupId>
+      <artifactId>gax-httpjson</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.threeten</groupId>
       <artifactId>threetenbp</artifactId>
@@ -308,12 +312,24 @@
     </dependency>
 
     <!-- Need testing utility classes for generated gRPC clients tests -->
+    <dependency>
+      <groupId>com.google.api</groupId>
+      <artifactId>gax</artifactId>
+      <classifier>testlib</classifier>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>com.google.api</groupId>
       <artifactId>gax-grpc</artifactId>
       <classifier>testlib</classifier>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.google.api</groupId>
+      <artifactId>gax-httpjson</artifactId>
+      <classifier>testlib</classifier>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>com.google.truth</groupId>
       <artifactId>truth</artifactId>
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java
index 961289f6eee..8bd55cc79df 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClient.java
@@ -18,7 +18,9 @@
 
 import com.google.api.core.ApiFuture;
 import com.google.api.core.ApiFutures;
+import com.google.api.core.BetaApi;
 import com.google.api.gax.core.BackgroundResource;
+import com.google.api.gax.httpjson.longrunning.OperationsClient;
 import com.google.api.gax.longrunning.OperationFuture;
 import com.google.api.gax.paging.AbstractFixedSizeCollection;
 import com.google.api.gax.paging.AbstractPage;
@@ -36,7 +38,6 @@
 import com.google.iam.v1.TestIamPermissionsRequest;
 import com.google.iam.v1.TestIamPermissionsResponse;
 import com.google.longrunning.Operation;
-import com.google.longrunning.OperationsClient;
 import com.google.protobuf.Empty;
 import com.google.protobuf.FieldMask;
 import com.google.protobuf.Timestamp;
@@ -143,13 +144,28 @@
  * DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(databaseAdminSettings);
  * }</pre>
  *
+ * <p>To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending and receiving requests over
+ * the wire:
+ *
+ * <pre>{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * DatabaseAdminSettings databaseAdminSettings =
+ *     DatabaseAdminSettings.newBuilder()
+ *         .setTransportChannelProvider(
+ *             DatabaseAdminSettings.defaultHttpJsonTransportProviderBuilder().build())
+ *         .build();
+ * DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create(databaseAdminSettings);
+ * }</pre>
+ *
  * <p>Please refer to the GitHub repository's samples for more quickstart code snippets.
  */
 @Generated("by gapic-generator-java")
 public class DatabaseAdminClient implements BackgroundResource {
   private final DatabaseAdminSettings settings;
   private final DatabaseAdminStub stub;
-  private final OperationsClient operationsClient;
+  private final OperationsClient httpJsonOperationsClient;
+  private final com.google.longrunning.OperationsClient operationsClient;
 
   /** Constructs an instance of DatabaseAdminClient with default settings. */
   public static final DatabaseAdminClient create() throws IOException {
@@ -181,13 +197,17 @@ public static final DatabaseAdminClient create(DatabaseAdminStub stub) {
   protected DatabaseAdminClient(DatabaseAdminSettings settings) throws IOException {
     this.settings = settings;
     this.stub = ((DatabaseAdminStubSettings) settings.getStubSettings()).createStub();
-    this.operationsClient = OperationsClient.create(this.stub.getOperationsStub());
+    this.operationsClient =
+        com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub());
+    this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub());
   }
 
   protected DatabaseAdminClient(DatabaseAdminStub stub) {
     this.settings = null;
     this.stub = stub;
-    this.operationsClient = OperationsClient.create(this.stub.getOperationsStub());
+    this.operationsClient =
+        com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub());
+    this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub());
   }
 
   public final DatabaseAdminSettings getSettings() {
@@ -202,10 +222,19 @@ public DatabaseAdminStub getStub() {
    * Returns the OperationsClient that can be used to query the status of a long-running operation
    * returned by another API method call.
    */
-  public final OperationsClient getOperationsClient() {
+  public final com.google.longrunning.OperationsClient getOperationsClient() {
     return operationsClient;
   }
 
+  /**
+   * Returns the OperationsClient that can be used to query the status of a long-running operation
+   * returned by another API method call.
+   */
+  @BetaApi
+  public final OperationsClient getHttpJsonOperationsClient() {
+    return httpJsonOperationsClient;
+  }
+
   // AUTO-GENERATED DOCUMENTATION AND METHOD.
   /**
    * Lists Cloud Spanner databases.
@@ -338,7 +367,7 @@ public final ListDatabasesPagedResponse listDatabases(ListDatabasesRequest reque
    *           .build();
    *   while (true) {
    *     ListDatabasesResponse response = databaseAdminClient.listDatabasesCallable().call(request);
-   *     for (Database element : response.getResponsesList()) {
+   *     for (Database element : response.getDatabasesList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
@@ -2395,7 +2424,7 @@ public final ListBackupsPagedResponse listBackups(ListBackupsRequest request) {
    *           .build();
    *   while (true) {
    *     ListBackupsResponse response = databaseAdminClient.listBackupsCallable().call(request);
-   *     for (Backup element : response.getResponsesList()) {
+   *     for (Backup element : response.getBackupsList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
@@ -2913,7 +2942,7 @@ public final ListDatabaseOperationsPagedResponse listDatabaseOperations(
    *   while (true) {
    *     ListDatabaseOperationsResponse response =
    *         databaseAdminClient.listDatabaseOperationsCallable().call(request);
-   *     for (Operation element : response.getResponsesList()) {
+   *     for (Operation element : response.getOperationsList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
@@ -3104,7 +3133,7 @@ public final ListBackupOperationsPagedResponse listBackupOperations(
    *   while (true) {
    *     ListBackupOperationsResponse response =
    *         databaseAdminClient.listBackupOperationsCallable().call(request);
-   *     for (Operation element : response.getResponsesList()) {
+   *     for (Operation element : response.getOperationsList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java
index d0f6aeb24ba..6e4811ed0b1 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java
@@ -26,6 +26,7 @@
 import com.google.api.gax.core.GoogleCredentialsProvider;
 import com.google.api.gax.core.InstantiatingExecutorProvider;
 import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
 import com.google.api.gax.rpc.ApiClientHeaderProvider;
 import com.google.api.gax.rpc.ClientContext;
 import com.google.api.gax.rpc.ClientSettings;
@@ -264,11 +265,18 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde
     return DatabaseAdminStubSettings.defaultCredentialsProviderBuilder();
   }
 
-  /** Returns a builder for the default ChannelProvider for this service. */
+  /** Returns a builder for the default gRPC ChannelProvider for this service. */
   public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() {
     return DatabaseAdminStubSettings.defaultGrpcTransportProviderBuilder();
   }
 
+  /** Returns a builder for the default REST ChannelProvider for this service. */
+  @BetaApi
+  public static InstantiatingHttpJsonChannelProvider.Builder
+      defaultHttpJsonTransportProviderBuilder() {
+    return DatabaseAdminStubSettings.defaultHttpJsonTransportProviderBuilder();
+  }
+
   public static TransportChannelProvider defaultTransportChannelProvider() {
     return DatabaseAdminStubSettings.defaultTransportChannelProvider();
   }
@@ -278,11 +286,17 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil
     return DatabaseAdminStubSettings.defaultApiClientHeaderProviderBuilder();
   }
 
-  /** Returns a new builder for this class. */
+  /** Returns a new gRPC builder for this class. */
   public static Builder newBuilder() {
     return Builder.createDefault();
   }
 
+  /** Returns a new REST builder for this class. */
+  @BetaApi
+  public static Builder newHttpJsonBuilder() {
+    return Builder.createHttpJsonDefault();
+  }
+
   /** Returns a new builder for this class. */
   public static Builder newBuilder(ClientContext clientContext) {
     return new Builder(clientContext);
@@ -320,6 +334,11 @@ private static Builder createDefault() {
       return new Builder(DatabaseAdminStubSettings.newBuilder());
     }
 
+    @BetaApi
+    private static Builder createHttpJsonDefault() {
+      return new Builder(DatabaseAdminStubSettings.newHttpJsonBuilder());
+    }
+
     public DatabaseAdminStubSettings.Builder getStubSettingsBuilder() {
       return ((DatabaseAdminStubSettings.Builder) getStubSettings());
     }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStub.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStub.java
index 6b9df8b0e50..fedc9d86e9f 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStub.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStub.java
@@ -71,7 +71,11 @@
 public abstract class DatabaseAdminStub implements BackgroundResource {
 
   public OperationsStub getOperationsStub() {
-    throw new UnsupportedOperationException("Not implemented: getOperationsStub()");
+    return null;
+  }
+
+  public com.google.api.gax.httpjson.longrunning.stub.OperationsStub getHttpJsonOperationsStub() {
+    return null;
   }
 
   public UnaryCallable<ListDatabasesRequest, ListDatabasesPagedResponse>
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java
index 3eaebd1eeda..cc76e2511b3 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java
@@ -31,6 +31,9 @@
 import com.google.api.gax.grpc.GrpcTransportChannel;
 import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
 import com.google.api.gax.grpc.ProtoOperationTransformers;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.HttpJsonTransportChannel;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
 import com.google.api.gax.longrunning.OperationSnapshot;
 import com.google.api.gax.longrunning.OperationTimedPollAlgorithm;
 import com.google.api.gax.retrying.RetrySettings;
@@ -547,6 +550,11 @@ public DatabaseAdminStub createStub() throws IOException {
         .equals(GrpcTransportChannel.getGrpcTransportName())) {
       return GrpcDatabaseAdminStub.create(this);
     }
+    if (getTransportChannelProvider()
+        .getTransportName()
+        .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) {
+      return HttpJsonDatabaseAdminStub.create(this);
+    }
     throw new UnsupportedOperationException(
         String.format(
             "Transport not supported: %s", getTransportChannelProvider().getTransportName()));
@@ -579,18 +587,25 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde
         .setUseJwtAccessWithScope(true);
   }
 
-  /** Returns a builder for the default ChannelProvider for this service. */
+  /** Returns a builder for the default gRPC ChannelProvider for this service. */
   public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() {
     return InstantiatingGrpcChannelProvider.newBuilder()
         .setMaxInboundMessageSize(Integer.MAX_VALUE);
   }
 
+  /** Returns a builder for the default REST ChannelProvider for this service. */
+  @BetaApi
+  public static InstantiatingHttpJsonChannelProvider.Builder
+      defaultHttpJsonTransportProviderBuilder() {
+    return InstantiatingHttpJsonChannelProvider.newBuilder();
+  }
+
   public static TransportChannelProvider defaultTransportChannelProvider() {
     return defaultGrpcTransportProviderBuilder().build();
   }
 
   @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
-  public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
+  public static ApiClientHeaderProvider.Builder defaultGrpcApiClientHeaderProviderBuilder() {
     return ApiClientHeaderProvider.newBuilder()
         .setGeneratedLibToken(
             "gapic", GaxProperties.getLibraryVersion(DatabaseAdminStubSettings.class))
@@ -598,11 +613,30 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil
             GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion());
   }
 
-  /** Returns a new builder for this class. */
+  @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
+  public static ApiClientHeaderProvider.Builder defaultHttpJsonApiClientHeaderProviderBuilder() {
+    return ApiClientHeaderProvider.newBuilder()
+        .setGeneratedLibToken(
+            "gapic", GaxProperties.getLibraryVersion(DatabaseAdminStubSettings.class))
+        .setTransportToken(
+            GaxHttpJsonProperties.getHttpJsonTokenName(),
+            GaxHttpJsonProperties.getHttpJsonVersion());
+  }
+
+  public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
+    return DatabaseAdminStubSettings.defaultGrpcApiClientHeaderProviderBuilder();
+  }
+
+  /** Returns a new gRPC builder for this class. */
   public static Builder newBuilder() {
     return Builder.createDefault();
   }
 
+  /** Returns a new REST builder for this class. */
+  public static Builder newHttpJsonBuilder() {
+    return Builder.createHttpJsonDefault();
+  }
+
   /** Returns a new builder for this class. */
   public static Builder newBuilder(ClientContext clientContext) {
     return new Builder(clientContext);
@@ -880,6 +914,19 @@ private static Builder createDefault() {
       return initDefaults(builder);
     }
 
+    private static Builder createHttpJsonDefault() {
+      Builder builder = new Builder(((ClientContext) null));
+
+      builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build());
+      builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build());
+      builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build());
+      builder.setEndpoint(getDefaultEndpoint());
+      builder.setMtlsEndpoint(getDefaultMtlsEndpoint());
+      builder.setSwitchToMtlsEndpointAllowed(true);
+
+      return initDefaults(builder);
+    }
+
     private static Builder initDefaults(Builder builder) {
       builder
           .listDatabasesSettings()
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminCallableFactory.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminCallableFactory.java
new file mode 100644
index 00000000000..e443d8f614b
--- /dev/null
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminCallableFactory.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.admin.database.v1.stub;
+
+import com.google.api.core.BetaApi;
+import com.google.api.gax.httpjson.HttpJsonCallSettings;
+import com.google.api.gax.httpjson.HttpJsonCallableFactory;
+import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable;
+import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
+import com.google.api.gax.httpjson.longrunning.stub.OperationsStub;
+import com.google.api.gax.rpc.BatchingCallSettings;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.OperationCallSettings;
+import com.google.api.gax.rpc.OperationCallable;
+import com.google.api.gax.rpc.PagedCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallable;
+import com.google.api.gax.rpc.UnaryCallSettings;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.longrunning.Operation;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * REST callable factory implementation for the DatabaseAdmin service API.
+ *
+ * <p>This class is for advanced usage.
+ */
+@Generated("by gapic-generator-java")
+@BetaApi
+public class HttpJsonDatabaseAdminCallableFactory
+    implements HttpJsonStubCallableFactory<Operation, OperationsStub> {
+
+  @Override
+  public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCallable(
+      HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+      UnaryCallSettings<RequestT, ResponseT> callSettings,
+      ClientContext clientContext) {
+    return HttpJsonCallableFactory.createUnaryCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @Override
+  public <RequestT, ResponseT, PagedListResponseT>
+      UnaryCallable<RequestT, PagedListResponseT> createPagedCallable(
+          HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+          PagedCallSettings<RequestT, ResponseT, PagedListResponseT> callSettings,
+          ClientContext clientContext) {
+    return HttpJsonCallableFactory.createPagedCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @Override
+  public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createBatchingCallable(
+      HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+      BatchingCallSettings<RequestT, ResponseT> callSettings,
+      ClientContext clientContext) {
+    return HttpJsonCallableFactory.createBatchingCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @BetaApi(
+      "The surface for long-running operations is not stable yet and may change in the future.")
+  @Override
+  public <RequestT, ResponseT, MetadataT>
+      OperationCallable<RequestT, ResponseT, MetadataT> createOperationCallable(
+          HttpJsonCallSettings<RequestT, Operation> httpJsonCallSettings,
+          OperationCallSettings<RequestT, ResponseT, MetadataT> callSettings,
+          ClientContext clientContext,
+          OperationsStub operationsStub) {
+    UnaryCallable<RequestT, Operation> innerCallable =
+        HttpJsonCallableFactory.createBaseUnaryCallable(
+            httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext);
+    HttpJsonOperationSnapshotCallable<RequestT, Operation> initialCallable =
+        new HttpJsonOperationSnapshotCallable<RequestT, Operation>(
+            innerCallable,
+            httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory());
+    return HttpJsonCallableFactory.createOperationCallable(
+        callSettings, clientContext, operationsStub.longRunningClient(), initialCallable);
+  }
+
+  @Override
+  public <RequestT, ResponseT>
+      ServerStreamingCallable<RequestT, ResponseT> createServerStreamingCallable(
+          HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+          ServerStreamingCallSettings<RequestT, ResponseT> callSettings,
+          ClientContext clientContext) {
+    return HttpJsonCallableFactory.createServerStreamingCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminStub.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminStub.java
new file mode 100644
index 00000000000..505676eab73
--- /dev/null
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/HttpJsonDatabaseAdminStub.java
@@ -0,0 +1,1270 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.admin.database.v1.stub;
+
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListBackupOperationsPagedResponse;
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListBackupsPagedResponse;
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabaseOperationsPagedResponse;
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabasesPagedResponse;
+
+import com.google.api.core.BetaApi;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.core.BackgroundResource;
+import com.google.api.gax.core.BackgroundResourceAggregation;
+import com.google.api.gax.httpjson.ApiMethodDescriptor;
+import com.google.api.gax.httpjson.HttpJsonCallSettings;
+import com.google.api.gax.httpjson.HttpJsonOperationSnapshot;
+import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
+import com.google.api.gax.httpjson.ProtoMessageRequestFormatter;
+import com.google.api.gax.httpjson.ProtoMessageResponseParser;
+import com.google.api.gax.httpjson.ProtoRestSerializer;
+import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.OperationCallable;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.iam.v1.GetIamPolicyRequest;
+import com.google.iam.v1.Policy;
+import com.google.iam.v1.SetIamPolicyRequest;
+import com.google.iam.v1.TestIamPermissionsRequest;
+import com.google.iam.v1.TestIamPermissionsResponse;
+import com.google.longrunning.Operation;
+import com.google.protobuf.Empty;
+import com.google.protobuf.TypeRegistry;
+import com.google.spanner.admin.database.v1.Backup;
+import com.google.spanner.admin.database.v1.CopyBackupMetadata;
+import com.google.spanner.admin.database.v1.CopyBackupRequest;
+import com.google.spanner.admin.database.v1.CreateBackupMetadata;
+import com.google.spanner.admin.database.v1.CreateBackupRequest;
+import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
+import com.google.spanner.admin.database.v1.CreateDatabaseRequest;
+import com.google.spanner.admin.database.v1.Database;
+import com.google.spanner.admin.database.v1.DeleteBackupRequest;
+import com.google.spanner.admin.database.v1.DropDatabaseRequest;
+import com.google.spanner.admin.database.v1.GetBackupRequest;
+import com.google.spanner.admin.database.v1.GetDatabaseDdlRequest;
+import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse;
+import com.google.spanner.admin.database.v1.GetDatabaseRequest;
+import com.google.spanner.admin.database.v1.ListBackupOperationsRequest;
+import com.google.spanner.admin.database.v1.ListBackupOperationsResponse;
+import com.google.spanner.admin.database.v1.ListBackupsRequest;
+import com.google.spanner.admin.database.v1.ListBackupsResponse;
+import com.google.spanner.admin.database.v1.ListDatabaseOperationsRequest;
+import com.google.spanner.admin.database.v1.ListDatabaseOperationsResponse;
+import com.google.spanner.admin.database.v1.ListDatabasesRequest;
+import com.google.spanner.admin.database.v1.ListDatabasesResponse;
+import com.google.spanner.admin.database.v1.RestoreDatabaseMetadata;
+import com.google.spanner.admin.database.v1.RestoreDatabaseRequest;
+import com.google.spanner.admin.database.v1.UpdateBackupRequest;
+import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata;
+import com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * REST stub implementation for the DatabaseAdmin service API.
+ *
+ * <p>This class is for advanced usage and reflects the underlying API directly.
+ */
+@Generated("by gapic-generator-java")
+@BetaApi
+public class HttpJsonDatabaseAdminStub extends DatabaseAdminStub {
+  private static final TypeRegistry typeRegistry =
+      TypeRegistry.newBuilder()
+          .add(CreateDatabaseMetadata.getDescriptor())
+          .add(Empty.getDescriptor())
+          .add(CreateBackupMetadata.getDescriptor())
+          .add(RestoreDatabaseMetadata.getDescriptor())
+          .add(Database.getDescriptor())
+          .add(Backup.getDescriptor())
+          .add(CopyBackupMetadata.getDescriptor())
+          .add(UpdateDatabaseDdlMetadata.getDescriptor())
+          .build();
+
+  private static final ApiMethodDescriptor<ListDatabasesRequest, ListDatabasesResponse>
+      listDatabasesMethodDescriptor =
+          ApiMethodDescriptor.<ListDatabasesRequest, ListDatabasesResponse>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/ListDatabases")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListDatabasesRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/databases",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListDatabasesRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListDatabasesRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListDatabasesResponse>newBuilder()
+                      .setDefaultInstance(ListDatabasesResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<CreateDatabaseRequest, Operation>
+      createDatabaseMethodDescriptor =
+          ApiMethodDescriptor.<CreateDatabaseRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/CreateDatabase")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<CreateDatabaseRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/databases",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearParent().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (CreateDatabaseRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<GetDatabaseRequest, Database>
+      getDatabaseMethodDescriptor =
+          ApiMethodDescriptor.<GetDatabaseRequest, Database>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/GetDatabase")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<GetDatabaseRequest>newBuilder()
+                      .setPath(
+                          "/v1/{name=projects/*/instances/*/databases/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<GetDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "name", request.getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<GetDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Database>newBuilder()
+                      .setDefaultInstance(Database.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<UpdateDatabaseDdlRequest, Operation>
+      updateDatabaseDdlMethodDescriptor =
+          ApiMethodDescriptor.<UpdateDatabaseDdlRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/UpdateDatabaseDdl")
+              .setHttpMethod("PATCH")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<UpdateDatabaseDdlRequest>newBuilder()
+                      .setPath(
+                          "/v1/{database=projects/*/instances/*/databases/*}/ddl",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<UpdateDatabaseDdlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "database", request.getDatabase());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<UpdateDatabaseDdlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearDatabase().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (UpdateDatabaseDdlRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<DropDatabaseRequest, Empty>
+      dropDatabaseMethodDescriptor =
+          ApiMethodDescriptor.<DropDatabaseRequest, Empty>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/DropDatabase")
+              .setHttpMethod("DELETE")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<DropDatabaseRequest>newBuilder()
+                      .setPath(
+                          "/v1/{database=projects/*/instances/*/databases/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<DropDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "database", request.getDatabase());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<DropDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Empty>newBuilder()
+                      .setDefaultInstance(Empty.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<GetDatabaseDdlRequest, GetDatabaseDdlResponse>
+      getDatabaseDdlMethodDescriptor =
+          ApiMethodDescriptor.<GetDatabaseDdlRequest, GetDatabaseDdlResponse>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/GetDatabaseDdl")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<GetDatabaseDdlRequest>newBuilder()
+                      .setPath(
+                          "/v1/{database=projects/*/instances/*/databases/*}/ddl",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<GetDatabaseDdlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "database", request.getDatabase());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<GetDatabaseDdlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<GetDatabaseDdlResponse>newBuilder()
+                      .setDefaultInstance(GetDatabaseDdlResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<SetIamPolicyRequest, Policy>
+      setIamPolicyMethodDescriptor =
+          ApiMethodDescriptor.<SetIamPolicyRequest, Policy>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/SetIamPolicy")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<SetIamPolicyRequest>newBuilder()
+                      .setPath(
+                          "/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<SetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "resource", request.getResource());
+                            return fields;
+                          })
+                      .setAdditionalPaths(
+                          "/v1/{resource=projects/*/instances/*/backups/*}:setIamPolicy")
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<SetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearResource().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Policy>newBuilder()
+                      .setDefaultInstance(Policy.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<GetIamPolicyRequest, Policy>
+      getIamPolicyMethodDescriptor =
+          ApiMethodDescriptor.<GetIamPolicyRequest, Policy>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/GetIamPolicy")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<GetIamPolicyRequest>newBuilder()
+                      .setPath(
+                          "/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<GetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "resource", request.getResource());
+                            return fields;
+                          })
+                      .setAdditionalPaths(
+                          "/v1/{resource=projects/*/instances/*/backups/*}:getIamPolicy")
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<GetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearResource().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Policy>newBuilder()
+                      .setDefaultInstance(Policy.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<TestIamPermissionsRequest, TestIamPermissionsResponse>
+      testIamPermissionsMethodDescriptor =
+          ApiMethodDescriptor.<TestIamPermissionsRequest, TestIamPermissionsResponse>newBuilder()
+              .setFullMethodName(
+                  "google.spanner.admin.database.v1.DatabaseAdmin/TestIamPermissions")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<TestIamPermissionsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{resource=projects/*/instances/*/databases/*}:testIamPermissions",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<TestIamPermissionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "resource", request.getResource());
+                            return fields;
+                          })
+                      .setAdditionalPaths(
+                          "/v1/{resource=projects/*/instances/*/backups/*}:testIamPermissions")
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<TestIamPermissionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearResource().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<TestIamPermissionsResponse>newBuilder()
+                      .setDefaultInstance(TestIamPermissionsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<CreateBackupRequest, Operation>
+      createBackupMethodDescriptor =
+          ApiMethodDescriptor.<CreateBackupRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/CreateBackup")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<CreateBackupRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/backups",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "backupId", request.getBackupId());
+                            serializer.putQueryParam(
+                                fields, "encryptionConfig", request.getEncryptionConfig());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create().toBody("backup", request.getBackup()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (CreateBackupRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<CopyBackupRequest, Operation>
+      copyBackupMethodDescriptor =
+          ApiMethodDescriptor.<CopyBackupRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/CopyBackup")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<CopyBackupRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/backups:copy",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<CopyBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<CopyBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearParent().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (CopyBackupRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<GetBackupRequest, Backup> getBackupMethodDescriptor =
+      ApiMethodDescriptor.<GetBackupRequest, Backup>newBuilder()
+          .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/GetBackup")
+          .setHttpMethod("GET")
+          .setType(ApiMethodDescriptor.MethodType.UNARY)
+          .setRequestFormatter(
+              ProtoMessageRequestFormatter.<GetBackupRequest>newBuilder()
+                  .setPath(
+                      "/v1/{name=projects/*/instances/*/backups/*}",
+                      request -> {
+                        Map<String, String> fields = new HashMap<>();
+                        ProtoRestSerializer<GetBackupRequest> serializer =
+                            ProtoRestSerializer.create();
+                        serializer.putPathParam(fields, "name", request.getName());
+                        return fields;
+                      })
+                  .setQueryParamsExtractor(
+                      request -> {
+                        Map<String, List<String>> fields = new HashMap<>();
+                        ProtoRestSerializer<GetBackupRequest> serializer =
+                            ProtoRestSerializer.create();
+                        return fields;
+                      })
+                  .setRequestBodyExtractor(request -> null)
+                  .build())
+          .setResponseParser(
+              ProtoMessageResponseParser.<Backup>newBuilder()
+                  .setDefaultInstance(Backup.getDefaultInstance())
+                  .setDefaultTypeRegistry(typeRegistry)
+                  .build())
+          .build();
+
+  private static final ApiMethodDescriptor<UpdateBackupRequest, Backup>
+      updateBackupMethodDescriptor =
+          ApiMethodDescriptor.<UpdateBackupRequest, Backup>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/UpdateBackup")
+              .setHttpMethod("PATCH")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<UpdateBackupRequest>newBuilder()
+                      .setPath(
+                          "/v1/{backup.name=projects/*/instances/*/backups/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<UpdateBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(
+                                fields, "backup.name", request.getBackup().getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<UpdateBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "updateMask", request.getUpdateMask());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create().toBody("backup", request.getBackup()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Backup>newBuilder()
+                      .setDefaultInstance(Backup.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<DeleteBackupRequest, Empty>
+      deleteBackupMethodDescriptor =
+          ApiMethodDescriptor.<DeleteBackupRequest, Empty>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/DeleteBackup")
+              .setHttpMethod("DELETE")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<DeleteBackupRequest>newBuilder()
+                      .setPath(
+                          "/v1/{name=projects/*/instances/*/backups/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<DeleteBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "name", request.getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<DeleteBackupRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Empty>newBuilder()
+                      .setDefaultInstance(Empty.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<ListBackupsRequest, ListBackupsResponse>
+      listBackupsMethodDescriptor =
+          ApiMethodDescriptor.<ListBackupsRequest, ListBackupsResponse>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/ListBackups")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListBackupsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/backups",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListBackupsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListBackupsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "filter", request.getFilter());
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListBackupsResponse>newBuilder()
+                      .setDefaultInstance(ListBackupsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<RestoreDatabaseRequest, Operation>
+      restoreDatabaseMethodDescriptor =
+          ApiMethodDescriptor.<RestoreDatabaseRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.database.v1.DatabaseAdmin/RestoreDatabase")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<RestoreDatabaseRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/databases:restore",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<RestoreDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<RestoreDatabaseRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearParent().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (RestoreDatabaseRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<
+          ListDatabaseOperationsRequest, ListDatabaseOperationsResponse>
+      listDatabaseOperationsMethodDescriptor =
+          ApiMethodDescriptor
+              .<ListDatabaseOperationsRequest, ListDatabaseOperationsResponse>newBuilder()
+              .setFullMethodName(
+                  "google.spanner.admin.database.v1.DatabaseAdmin/ListDatabaseOperations")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListDatabaseOperationsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/databaseOperations",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListDatabaseOperationsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListDatabaseOperationsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "filter", request.getFilter());
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListDatabaseOperationsResponse>newBuilder()
+                      .setDefaultInstance(ListDatabaseOperationsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<
+          ListBackupOperationsRequest, ListBackupOperationsResponse>
+      listBackupOperationsMethodDescriptor =
+          ApiMethodDescriptor
+              .<ListBackupOperationsRequest, ListBackupOperationsResponse>newBuilder()
+              .setFullMethodName(
+                  "google.spanner.admin.database.v1.DatabaseAdmin/ListBackupOperations")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListBackupOperationsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*/instances/*}/backupOperations",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListBackupOperationsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListBackupOperationsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "filter", request.getFilter());
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListBackupOperationsResponse>newBuilder()
+                      .setDefaultInstance(ListBackupOperationsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private final UnaryCallable<ListDatabasesRequest, ListDatabasesResponse> listDatabasesCallable;
+  private final UnaryCallable<ListDatabasesRequest, ListDatabasesPagedResponse>
+      listDatabasesPagedCallable;
+  private final UnaryCallable<CreateDatabaseRequest, Operation> createDatabaseCallable;
+  private final OperationCallable<CreateDatabaseRequest, Database, CreateDatabaseMetadata>
+      createDatabaseOperationCallable;
+  private final UnaryCallable<GetDatabaseRequest, Database> getDatabaseCallable;
+  private final UnaryCallable<UpdateDatabaseDdlRequest, Operation> updateDatabaseDdlCallable;
+  private final OperationCallable<UpdateDatabaseDdlRequest, Empty, UpdateDatabaseDdlMetadata>
+      updateDatabaseDdlOperationCallable;
+  private final UnaryCallable<DropDatabaseRequest, Empty> dropDatabaseCallable;
+  private final UnaryCallable<GetDatabaseDdlRequest, GetDatabaseDdlResponse> getDatabaseDdlCallable;
+  private final UnaryCallable<SetIamPolicyRequest, Policy> setIamPolicyCallable;
+  private final UnaryCallable<GetIamPolicyRequest, Policy> getIamPolicyCallable;
+  private final UnaryCallable<TestIamPermissionsRequest, TestIamPermissionsResponse>
+      testIamPermissionsCallable;
+  private final UnaryCallable<CreateBackupRequest, Operation> createBackupCallable;
+  private final OperationCallable<CreateBackupRequest, Backup, CreateBackupMetadata>
+      createBackupOperationCallable;
+  private final UnaryCallable<CopyBackupRequest, Operation> copyBackupCallable;
+  private final OperationCallable<CopyBackupRequest, Backup, CopyBackupMetadata>
+      copyBackupOperationCallable;
+  private final UnaryCallable<GetBackupRequest, Backup> getBackupCallable;
+  private final UnaryCallable<UpdateBackupRequest, Backup> updateBackupCallable;
+  private final UnaryCallable<DeleteBackupRequest, Empty> deleteBackupCallable;
+  private final UnaryCallable<ListBackupsRequest, ListBackupsResponse> listBackupsCallable;
+  private final UnaryCallable<ListBackupsRequest, ListBackupsPagedResponse>
+      listBackupsPagedCallable;
+  private final UnaryCallable<RestoreDatabaseRequest, Operation> restoreDatabaseCallable;
+  private final OperationCallable<RestoreDatabaseRequest, Database, RestoreDatabaseMetadata>
+      restoreDatabaseOperationCallable;
+  private final UnaryCallable<ListDatabaseOperationsRequest, ListDatabaseOperationsResponse>
+      listDatabaseOperationsCallable;
+  private final UnaryCallable<ListDatabaseOperationsRequest, ListDatabaseOperationsPagedResponse>
+      listDatabaseOperationsPagedCallable;
+  private final UnaryCallable<ListBackupOperationsRequest, ListBackupOperationsResponse>
+      listBackupOperationsCallable;
+  private final UnaryCallable<ListBackupOperationsRequest, ListBackupOperationsPagedResponse>
+      listBackupOperationsPagedCallable;
+
+  private final BackgroundResource backgroundResources;
+  private final HttpJsonOperationsStub httpJsonOperationsStub;
+  private final HttpJsonStubCallableFactory callableFactory;
+
+  public static final HttpJsonDatabaseAdminStub create(DatabaseAdminStubSettings settings)
+      throws IOException {
+    return new HttpJsonDatabaseAdminStub(settings, ClientContext.create(settings));
+  }
+
+  public static final HttpJsonDatabaseAdminStub create(ClientContext clientContext)
+      throws IOException {
+    return new HttpJsonDatabaseAdminStub(
+        DatabaseAdminStubSettings.newHttpJsonBuilder().build(), clientContext);
+  }
+
+  public static final HttpJsonDatabaseAdminStub create(
+      ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException {
+    return new HttpJsonDatabaseAdminStub(
+        DatabaseAdminStubSettings.newHttpJsonBuilder().build(), clientContext, callableFactory);
+  }
+
+  /**
+   * Constructs an instance of HttpJsonDatabaseAdminStub, using the given settings. This is
+   * protected so that it is easy to make a subclass, but otherwise, the static factory methods
+   * should be preferred.
+   */
+  protected HttpJsonDatabaseAdminStub(
+      DatabaseAdminStubSettings settings, ClientContext clientContext) throws IOException {
+    this(settings, clientContext, new HttpJsonDatabaseAdminCallableFactory());
+  }
+
+  /**
+   * Constructs an instance of HttpJsonDatabaseAdminStub, using the given settings. This is
+   * protected so that it is easy to make a subclass, but otherwise, the static factory methods
+   * should be preferred.
+   */
+  protected HttpJsonDatabaseAdminStub(
+      DatabaseAdminStubSettings settings,
+      ClientContext clientContext,
+      HttpJsonStubCallableFactory callableFactory)
+      throws IOException {
+    this.callableFactory = callableFactory;
+    this.httpJsonOperationsStub =
+        HttpJsonOperationsStub.create(clientContext, callableFactory, typeRegistry);
+
+    HttpJsonCallSettings<ListDatabasesRequest, ListDatabasesResponse>
+        listDatabasesTransportSettings =
+            HttpJsonCallSettings.<ListDatabasesRequest, ListDatabasesResponse>newBuilder()
+                .setMethodDescriptor(listDatabasesMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<CreateDatabaseRequest, Operation> createDatabaseTransportSettings =
+        HttpJsonCallSettings.<CreateDatabaseRequest, Operation>newBuilder()
+            .setMethodDescriptor(createDatabaseMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<GetDatabaseRequest, Database> getDatabaseTransportSettings =
+        HttpJsonCallSettings.<GetDatabaseRequest, Database>newBuilder()
+            .setMethodDescriptor(getDatabaseMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<UpdateDatabaseDdlRequest, Operation> updateDatabaseDdlTransportSettings =
+        HttpJsonCallSettings.<UpdateDatabaseDdlRequest, Operation>newBuilder()
+            .setMethodDescriptor(updateDatabaseDdlMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<DropDatabaseRequest, Empty> dropDatabaseTransportSettings =
+        HttpJsonCallSettings.<DropDatabaseRequest, Empty>newBuilder()
+            .setMethodDescriptor(dropDatabaseMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<GetDatabaseDdlRequest, GetDatabaseDdlResponse>
+        getDatabaseDdlTransportSettings =
+            HttpJsonCallSettings.<GetDatabaseDdlRequest, GetDatabaseDdlResponse>newBuilder()
+                .setMethodDescriptor(getDatabaseDdlMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<SetIamPolicyRequest, Policy> setIamPolicyTransportSettings =
+        HttpJsonCallSettings.<SetIamPolicyRequest, Policy>newBuilder()
+            .setMethodDescriptor(setIamPolicyMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<GetIamPolicyRequest, Policy> getIamPolicyTransportSettings =
+        HttpJsonCallSettings.<GetIamPolicyRequest, Policy>newBuilder()
+            .setMethodDescriptor(getIamPolicyMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<TestIamPermissionsRequest, TestIamPermissionsResponse>
+        testIamPermissionsTransportSettings =
+            HttpJsonCallSettings.<TestIamPermissionsRequest, TestIamPermissionsResponse>newBuilder()
+                .setMethodDescriptor(testIamPermissionsMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<CreateBackupRequest, Operation> createBackupTransportSettings =
+        HttpJsonCallSettings.<CreateBackupRequest, Operation>newBuilder()
+            .setMethodDescriptor(createBackupMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<CopyBackupRequest, Operation> copyBackupTransportSettings =
+        HttpJsonCallSettings.<CopyBackupRequest, Operation>newBuilder()
+            .setMethodDescriptor(copyBackupMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<GetBackupRequest, Backup> getBackupTransportSettings =
+        HttpJsonCallSettings.<GetBackupRequest, Backup>newBuilder()
+            .setMethodDescriptor(getBackupMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<UpdateBackupRequest, Backup> updateBackupTransportSettings =
+        HttpJsonCallSettings.<UpdateBackupRequest, Backup>newBuilder()
+            .setMethodDescriptor(updateBackupMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<DeleteBackupRequest, Empty> deleteBackupTransportSettings =
+        HttpJsonCallSettings.<DeleteBackupRequest, Empty>newBuilder()
+            .setMethodDescriptor(deleteBackupMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ListBackupsRequest, ListBackupsResponse> listBackupsTransportSettings =
+        HttpJsonCallSettings.<ListBackupsRequest, ListBackupsResponse>newBuilder()
+            .setMethodDescriptor(listBackupsMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<RestoreDatabaseRequest, Operation> restoreDatabaseTransportSettings =
+        HttpJsonCallSettings.<RestoreDatabaseRequest, Operation>newBuilder()
+            .setMethodDescriptor(restoreDatabaseMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ListDatabaseOperationsRequest, ListDatabaseOperationsResponse>
+        listDatabaseOperationsTransportSettings =
+            HttpJsonCallSettings
+                .<ListDatabaseOperationsRequest, ListDatabaseOperationsResponse>newBuilder()
+                .setMethodDescriptor(listDatabaseOperationsMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<ListBackupOperationsRequest, ListBackupOperationsResponse>
+        listBackupOperationsTransportSettings =
+            HttpJsonCallSettings
+                .<ListBackupOperationsRequest, ListBackupOperationsResponse>newBuilder()
+                .setMethodDescriptor(listBackupOperationsMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+
+    this.listDatabasesCallable =
+        callableFactory.createUnaryCallable(
+            listDatabasesTransportSettings, settings.listDatabasesSettings(), clientContext);
+    this.listDatabasesPagedCallable =
+        callableFactory.createPagedCallable(
+            listDatabasesTransportSettings, settings.listDatabasesSettings(), clientContext);
+    this.createDatabaseCallable =
+        callableFactory.createUnaryCallable(
+            createDatabaseTransportSettings, settings.createDatabaseSettings(), clientContext);
+    this.createDatabaseOperationCallable =
+        callableFactory.createOperationCallable(
+            createDatabaseTransportSettings,
+            settings.createDatabaseOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.getDatabaseCallable =
+        callableFactory.createUnaryCallable(
+            getDatabaseTransportSettings, settings.getDatabaseSettings(), clientContext);
+    this.updateDatabaseDdlCallable =
+        callableFactory.createUnaryCallable(
+            updateDatabaseDdlTransportSettings,
+            settings.updateDatabaseDdlSettings(),
+            clientContext);
+    this.updateDatabaseDdlOperationCallable =
+        callableFactory.createOperationCallable(
+            updateDatabaseDdlTransportSettings,
+            settings.updateDatabaseDdlOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.dropDatabaseCallable =
+        callableFactory.createUnaryCallable(
+            dropDatabaseTransportSettings, settings.dropDatabaseSettings(), clientContext);
+    this.getDatabaseDdlCallable =
+        callableFactory.createUnaryCallable(
+            getDatabaseDdlTransportSettings, settings.getDatabaseDdlSettings(), clientContext);
+    this.setIamPolicyCallable =
+        callableFactory.createUnaryCallable(
+            setIamPolicyTransportSettings, settings.setIamPolicySettings(), clientContext);
+    this.getIamPolicyCallable =
+        callableFactory.createUnaryCallable(
+            getIamPolicyTransportSettings, settings.getIamPolicySettings(), clientContext);
+    this.testIamPermissionsCallable =
+        callableFactory.createUnaryCallable(
+            testIamPermissionsTransportSettings,
+            settings.testIamPermissionsSettings(),
+            clientContext);
+    this.createBackupCallable =
+        callableFactory.createUnaryCallable(
+            createBackupTransportSettings, settings.createBackupSettings(), clientContext);
+    this.createBackupOperationCallable =
+        callableFactory.createOperationCallable(
+            createBackupTransportSettings,
+            settings.createBackupOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.copyBackupCallable =
+        callableFactory.createUnaryCallable(
+            copyBackupTransportSettings, settings.copyBackupSettings(), clientContext);
+    this.copyBackupOperationCallable =
+        callableFactory.createOperationCallable(
+            copyBackupTransportSettings,
+            settings.copyBackupOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.getBackupCallable =
+        callableFactory.createUnaryCallable(
+            getBackupTransportSettings, settings.getBackupSettings(), clientContext);
+    this.updateBackupCallable =
+        callableFactory.createUnaryCallable(
+            updateBackupTransportSettings, settings.updateBackupSettings(), clientContext);
+    this.deleteBackupCallable =
+        callableFactory.createUnaryCallable(
+            deleteBackupTransportSettings, settings.deleteBackupSettings(), clientContext);
+    this.listBackupsCallable =
+        callableFactory.createUnaryCallable(
+            listBackupsTransportSettings, settings.listBackupsSettings(), clientContext);
+    this.listBackupsPagedCallable =
+        callableFactory.createPagedCallable(
+            listBackupsTransportSettings, settings.listBackupsSettings(), clientContext);
+    this.restoreDatabaseCallable =
+        callableFactory.createUnaryCallable(
+            restoreDatabaseTransportSettings, settings.restoreDatabaseSettings(), clientContext);
+    this.restoreDatabaseOperationCallable =
+        callableFactory.createOperationCallable(
+            restoreDatabaseTransportSettings,
+            settings.restoreDatabaseOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.listDatabaseOperationsCallable =
+        callableFactory.createUnaryCallable(
+            listDatabaseOperationsTransportSettings,
+            settings.listDatabaseOperationsSettings(),
+            clientContext);
+    this.listDatabaseOperationsPagedCallable =
+        callableFactory.createPagedCallable(
+            listDatabaseOperationsTransportSettings,
+            settings.listDatabaseOperationsSettings(),
+            clientContext);
+    this.listBackupOperationsCallable =
+        callableFactory.createUnaryCallable(
+            listBackupOperationsTransportSettings,
+            settings.listBackupOperationsSettings(),
+            clientContext);
+    this.listBackupOperationsPagedCallable =
+        callableFactory.createPagedCallable(
+            listBackupOperationsTransportSettings,
+            settings.listBackupOperationsSettings(),
+            clientContext);
+
+    this.backgroundResources =
+        new BackgroundResourceAggregation(clientContext.getBackgroundResources());
+  }
+
+  @InternalApi
+  public static List<ApiMethodDescriptor> getMethodDescriptors() {
+    List<ApiMethodDescriptor> methodDescriptors = new ArrayList<>();
+    methodDescriptors.add(listDatabasesMethodDescriptor);
+    methodDescriptors.add(createDatabaseMethodDescriptor);
+    methodDescriptors.add(getDatabaseMethodDescriptor);
+    methodDescriptors.add(updateDatabaseDdlMethodDescriptor);
+    methodDescriptors.add(dropDatabaseMethodDescriptor);
+    methodDescriptors.add(getDatabaseDdlMethodDescriptor);
+    methodDescriptors.add(setIamPolicyMethodDescriptor);
+    methodDescriptors.add(getIamPolicyMethodDescriptor);
+    methodDescriptors.add(testIamPermissionsMethodDescriptor);
+    methodDescriptors.add(createBackupMethodDescriptor);
+    methodDescriptors.add(copyBackupMethodDescriptor);
+    methodDescriptors.add(getBackupMethodDescriptor);
+    methodDescriptors.add(updateBackupMethodDescriptor);
+    methodDescriptors.add(deleteBackupMethodDescriptor);
+    methodDescriptors.add(listBackupsMethodDescriptor);
+    methodDescriptors.add(restoreDatabaseMethodDescriptor);
+    methodDescriptors.add(listDatabaseOperationsMethodDescriptor);
+    methodDescriptors.add(listBackupOperationsMethodDescriptor);
+    return methodDescriptors;
+  }
+
+  public HttpJsonOperationsStub getHttpJsonOperationsStub() {
+    return httpJsonOperationsStub;
+  }
+
+  @Override
+  public UnaryCallable<ListDatabasesRequest, ListDatabasesResponse> listDatabasesCallable() {
+    return listDatabasesCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListDatabasesRequest, ListDatabasesPagedResponse>
+      listDatabasesPagedCallable() {
+    return listDatabasesPagedCallable;
+  }
+
+  @Override
+  public UnaryCallable<CreateDatabaseRequest, Operation> createDatabaseCallable() {
+    return createDatabaseCallable;
+  }
+
+  @Override
+  public OperationCallable<CreateDatabaseRequest, Database, CreateDatabaseMetadata>
+      createDatabaseOperationCallable() {
+    return createDatabaseOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetDatabaseRequest, Database> getDatabaseCallable() {
+    return getDatabaseCallable;
+  }
+
+  @Override
+  public UnaryCallable<UpdateDatabaseDdlRequest, Operation> updateDatabaseDdlCallable() {
+    return updateDatabaseDdlCallable;
+  }
+
+  @Override
+  public OperationCallable<UpdateDatabaseDdlRequest, Empty, UpdateDatabaseDdlMetadata>
+      updateDatabaseDdlOperationCallable() {
+    return updateDatabaseDdlOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<DropDatabaseRequest, Empty> dropDatabaseCallable() {
+    return dropDatabaseCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetDatabaseDdlRequest, GetDatabaseDdlResponse> getDatabaseDdlCallable() {
+    return getDatabaseDdlCallable;
+  }
+
+  @Override
+  public UnaryCallable<SetIamPolicyRequest, Policy> setIamPolicyCallable() {
+    return setIamPolicyCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetIamPolicyRequest, Policy> getIamPolicyCallable() {
+    return getIamPolicyCallable;
+  }
+
+  @Override
+  public UnaryCallable<TestIamPermissionsRequest, TestIamPermissionsResponse>
+      testIamPermissionsCallable() {
+    return testIamPermissionsCallable;
+  }
+
+  @Override
+  public UnaryCallable<CreateBackupRequest, Operation> createBackupCallable() {
+    return createBackupCallable;
+  }
+
+  @Override
+  public OperationCallable<CreateBackupRequest, Backup, CreateBackupMetadata>
+      createBackupOperationCallable() {
+    return createBackupOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<CopyBackupRequest, Operation> copyBackupCallable() {
+    return copyBackupCallable;
+  }
+
+  @Override
+  public OperationCallable<CopyBackupRequest, Backup, CopyBackupMetadata>
+      copyBackupOperationCallable() {
+    return copyBackupOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetBackupRequest, Backup> getBackupCallable() {
+    return getBackupCallable;
+  }
+
+  @Override
+  public UnaryCallable<UpdateBackupRequest, Backup> updateBackupCallable() {
+    return updateBackupCallable;
+  }
+
+  @Override
+  public UnaryCallable<DeleteBackupRequest, Empty> deleteBackupCallable() {
+    return deleteBackupCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListBackupsRequest, ListBackupsResponse> listBackupsCallable() {
+    return listBackupsCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListBackupsRequest, ListBackupsPagedResponse> listBackupsPagedCallable() {
+    return listBackupsPagedCallable;
+  }
+
+  @Override
+  public UnaryCallable<RestoreDatabaseRequest, Operation> restoreDatabaseCallable() {
+    return restoreDatabaseCallable;
+  }
+
+  @Override
+  public OperationCallable<RestoreDatabaseRequest, Database, RestoreDatabaseMetadata>
+      restoreDatabaseOperationCallable() {
+    return restoreDatabaseOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListDatabaseOperationsRequest, ListDatabaseOperationsResponse>
+      listDatabaseOperationsCallable() {
+    return listDatabaseOperationsCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListDatabaseOperationsRequest, ListDatabaseOperationsPagedResponse>
+      listDatabaseOperationsPagedCallable() {
+    return listDatabaseOperationsPagedCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListBackupOperationsRequest, ListBackupOperationsResponse>
+      listBackupOperationsCallable() {
+    return listBackupOperationsCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListBackupOperationsRequest, ListBackupOperationsPagedResponse>
+      listBackupOperationsPagedCallable() {
+    return listBackupOperationsPagedCallable;
+  }
+
+  @Override
+  public final void close() {
+    try {
+      backgroundResources.close();
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IllegalStateException("Failed to close resource", e);
+    }
+  }
+
+  @Override
+  public void shutdown() {
+    backgroundResources.shutdown();
+  }
+
+  @Override
+  public boolean isShutdown() {
+    return backgroundResources.isShutdown();
+  }
+
+  @Override
+  public boolean isTerminated() {
+    return backgroundResources.isTerminated();
+  }
+
+  @Override
+  public void shutdownNow() {
+    backgroundResources.shutdownNow();
+  }
+
+  @Override
+  public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException {
+    return backgroundResources.awaitTermination(duration, unit);
+  }
+}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java
index aa9a61bb1de..e6f016b3db5 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClient.java
@@ -18,7 +18,9 @@
 
 import com.google.api.core.ApiFuture;
 import com.google.api.core.ApiFutures;
+import com.google.api.core.BetaApi;
 import com.google.api.gax.core.BackgroundResource;
+import com.google.api.gax.httpjson.longrunning.OperationsClient;
 import com.google.api.gax.longrunning.OperationFuture;
 import com.google.api.gax.paging.AbstractFixedSizeCollection;
 import com.google.api.gax.paging.AbstractPage;
@@ -36,7 +38,6 @@
 import com.google.iam.v1.TestIamPermissionsRequest;
 import com.google.iam.v1.TestIamPermissionsResponse;
 import com.google.longrunning.Operation;
-import com.google.longrunning.OperationsClient;
 import com.google.protobuf.Empty;
 import com.google.protobuf.FieldMask;
 import com.google.spanner.admin.instance.v1.CreateInstanceMetadata;
@@ -140,13 +141,28 @@
  * InstanceAdminClient instanceAdminClient = InstanceAdminClient.create(instanceAdminSettings);
  * }</pre>
  *
+ * <p>To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending and receiving requests over
+ * the wire:
+ *
+ * <pre>{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * InstanceAdminSettings instanceAdminSettings =
+ *     InstanceAdminSettings.newBuilder()
+ *         .setTransportChannelProvider(
+ *             InstanceAdminSettings.defaultHttpJsonTransportProviderBuilder().build())
+ *         .build();
+ * InstanceAdminClient instanceAdminClient = InstanceAdminClient.create(instanceAdminSettings);
+ * }</pre>
+ *
  * <p>Please refer to the GitHub repository's samples for more quickstart code snippets.
  */
 @Generated("by gapic-generator-java")
 public class InstanceAdminClient implements BackgroundResource {
   private final InstanceAdminSettings settings;
   private final InstanceAdminStub stub;
-  private final OperationsClient operationsClient;
+  private final OperationsClient httpJsonOperationsClient;
+  private final com.google.longrunning.OperationsClient operationsClient;
 
   /** Constructs an instance of InstanceAdminClient with default settings. */
   public static final InstanceAdminClient create() throws IOException {
@@ -178,13 +194,17 @@ public static final InstanceAdminClient create(InstanceAdminStub stub) {
   protected InstanceAdminClient(InstanceAdminSettings settings) throws IOException {
     this.settings = settings;
     this.stub = ((InstanceAdminStubSettings) settings.getStubSettings()).createStub();
-    this.operationsClient = OperationsClient.create(this.stub.getOperationsStub());
+    this.operationsClient =
+        com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub());
+    this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub());
   }
 
   protected InstanceAdminClient(InstanceAdminStub stub) {
     this.settings = null;
     this.stub = stub;
-    this.operationsClient = OperationsClient.create(this.stub.getOperationsStub());
+    this.operationsClient =
+        com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub());
+    this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub());
   }
 
   public final InstanceAdminSettings getSettings() {
@@ -199,10 +219,19 @@ public InstanceAdminStub getStub() {
    * Returns the OperationsClient that can be used to query the status of a long-running operation
    * returned by another API method call.
    */
-  public final OperationsClient getOperationsClient() {
+  public final com.google.longrunning.OperationsClient getOperationsClient() {
     return operationsClient;
   }
 
+  /**
+   * Returns the OperationsClient that can be used to query the status of a long-running operation
+   * returned by another API method call.
+   */
+  @BetaApi
+  public final OperationsClient getHttpJsonOperationsClient() {
+    return httpJsonOperationsClient;
+  }
+
   // AUTO-GENERATED DOCUMENTATION AND METHOD.
   /**
    * Lists the supported instance configurations for a given project.
@@ -338,7 +367,7 @@ public final ListInstanceConfigsPagedResponse listInstanceConfigs(
    *   while (true) {
    *     ListInstanceConfigsResponse response =
    *         instanceAdminClient.listInstanceConfigsCallable().call(request);
-   *     for (InstanceConfig element : response.getResponsesList()) {
+   *     for (InstanceConfig element : response.getInstanceConfigsList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
@@ -592,7 +621,7 @@ public final ListInstancesPagedResponse listInstances(ListInstancesRequest reque
    *           .build();
    *   while (true) {
    *     ListInstancesResponse response = instanceAdminClient.listInstancesCallable().call(request);
-   *     for (Instance element : response.getResponsesList()) {
+   *     for (Instance element : response.getInstancesList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
@@ -1039,7 +1068,7 @@ public final UnaryCallable<CreateInstanceRequest, Operation> createInstanceCalla
    * [response][google.longrunning.Operation.response] field type is
    * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
    *
-   * <p>Authorization requires `spanner.instances.update` permission on resource
+   * <p>Authorization requires `spanner.instances.update` permission on the resource
    * [name][google.spanner.admin.instance.v1.Instance.name].
    *
    * <p>Sample code:
@@ -1105,7 +1134,7 @@ public final OperationFuture<Instance, UpdateInstanceMetadata> updateInstanceAsy
    * [response][google.longrunning.Operation.response] field type is
    * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
    *
-   * <p>Authorization requires `spanner.instances.update` permission on resource
+   * <p>Authorization requires `spanner.instances.update` permission on the resource
    * [name][google.spanner.admin.instance.v1.Instance.name].
    *
    * <p>Sample code:
@@ -1164,7 +1193,7 @@ public final OperationFuture<Instance, UpdateInstanceMetadata> updateInstanceAsy
    * [response][google.longrunning.Operation.response] field type is
    * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
    *
-   * <p>Authorization requires `spanner.instances.update` permission on resource
+   * <p>Authorization requires `spanner.instances.update` permission on the resource
    * [name][google.spanner.admin.instance.v1.Instance.name].
    *
    * <p>Sample code:
@@ -1223,7 +1252,7 @@ public final OperationFuture<Instance, UpdateInstanceMetadata> updateInstanceAsy
    * [response][google.longrunning.Operation.response] field type is
    * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
    *
-   * <p>Authorization requires `spanner.instances.update` permission on resource
+   * <p>Authorization requires `spanner.instances.update` permission on the resource
    * [name][google.spanner.admin.instance.v1.Instance.name].
    *
    * <p>Sample code:
@@ -1395,7 +1424,7 @@ public final UnaryCallable<DeleteInstanceRequest, Empty> deleteInstanceCallable(
    * // This snippet has been automatically generated for illustrative purposes only.
    * // It may require modifications to work in your environment.
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
-   *   ResourceName resource = ProjectName.of("[PROJECT]");
+   *   ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
    *   Policy policy = Policy.newBuilder().build();
    *   Policy response = instanceAdminClient.setIamPolicy(resource, policy);
    * }
@@ -1464,7 +1493,7 @@ public final Policy setIamPolicy(String resource, Policy policy) {
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
    *   SetIamPolicyRequest request =
    *       SetIamPolicyRequest.newBuilder()
-   *           .setResource(ProjectName.of("[PROJECT]").toString())
+   *           .setResource(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
    *           .setPolicy(Policy.newBuilder().build())
    *           .setUpdateMask(FieldMask.newBuilder().build())
    *           .build();
@@ -1494,7 +1523,7 @@ public final Policy setIamPolicy(SetIamPolicyRequest request) {
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
    *   SetIamPolicyRequest request =
    *       SetIamPolicyRequest.newBuilder()
-   *           .setResource(ProjectName.of("[PROJECT]").toString())
+   *           .setResource(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
    *           .setPolicy(Policy.newBuilder().build())
    *           .setUpdateMask(FieldMask.newBuilder().build())
    *           .build();
@@ -1522,7 +1551,7 @@ public final UnaryCallable<SetIamPolicyRequest, Policy> setIamPolicyCallable() {
    * // This snippet has been automatically generated for illustrative purposes only.
    * // It may require modifications to work in your environment.
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
-   *   ResourceName resource = ProjectName.of("[PROJECT]");
+   *   ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
    *   Policy response = instanceAdminClient.getIamPolicy(resource);
    * }
    * }</pre>
@@ -1583,7 +1612,7 @@ public final Policy getIamPolicy(String resource) {
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
    *   GetIamPolicyRequest request =
    *       GetIamPolicyRequest.newBuilder()
-   *           .setResource(ProjectName.of("[PROJECT]").toString())
+   *           .setResource(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
    *           .setOptions(GetPolicyOptions.newBuilder().build())
    *           .build();
    *   Policy response = instanceAdminClient.getIamPolicy(request);
@@ -1613,7 +1642,7 @@ public final Policy getIamPolicy(GetIamPolicyRequest request) {
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
    *   GetIamPolicyRequest request =
    *       GetIamPolicyRequest.newBuilder()
-   *           .setResource(ProjectName.of("[PROJECT]").toString())
+   *           .setResource(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
    *           .setOptions(GetPolicyOptions.newBuilder().build())
    *           .build();
    *   ApiFuture<Policy> future = instanceAdminClient.getIamPolicyCallable().futureCall(request);
@@ -1640,7 +1669,7 @@ public final UnaryCallable<GetIamPolicyRequest, Policy> getIamPolicyCallable() {
    * // This snippet has been automatically generated for illustrative purposes only.
    * // It may require modifications to work in your environment.
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
-   *   ResourceName resource = ProjectName.of("[PROJECT]");
+   *   ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
    *   List<String> permissions = new ArrayList<>();
    *   TestIamPermissionsResponse response =
    *       instanceAdminClient.testIamPermissions(resource, permissions);
@@ -1718,7 +1747,7 @@ public final TestIamPermissionsResponse testIamPermissions(
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
    *   TestIamPermissionsRequest request =
    *       TestIamPermissionsRequest.newBuilder()
-   *           .setResource(ProjectName.of("[PROJECT]").toString())
+   *           .setResource(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
    *           .addAllPermissions(new ArrayList<String>())
    *           .build();
    *   TestIamPermissionsResponse response = instanceAdminClient.testIamPermissions(request);
@@ -1748,7 +1777,7 @@ public final TestIamPermissionsResponse testIamPermissions(TestIamPermissionsReq
    * try (InstanceAdminClient instanceAdminClient = InstanceAdminClient.create()) {
    *   TestIamPermissionsRequest request =
    *       TestIamPermissionsRequest.newBuilder()
-   *           .setResource(ProjectName.of("[PROJECT]").toString())
+   *           .setResource(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
    *           .addAllPermissions(new ArrayList<String>())
    *           .build();
    *   ApiFuture<TestIamPermissionsResponse> future =
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminSettings.java
index dc2c2b81efe..36339665f01 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminSettings.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminSettings.java
@@ -24,6 +24,7 @@
 import com.google.api.gax.core.GoogleCredentialsProvider;
 import com.google.api.gax.core.InstantiatingExecutorProvider;
 import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
 import com.google.api.gax.rpc.ApiClientHeaderProvider;
 import com.google.api.gax.rpc.ClientContext;
 import com.google.api.gax.rpc.ClientSettings;
@@ -183,11 +184,18 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde
     return InstanceAdminStubSettings.defaultCredentialsProviderBuilder();
   }
 
-  /** Returns a builder for the default ChannelProvider for this service. */
+  /** Returns a builder for the default gRPC ChannelProvider for this service. */
   public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() {
     return InstanceAdminStubSettings.defaultGrpcTransportProviderBuilder();
   }
 
+  /** Returns a builder for the default REST ChannelProvider for this service. */
+  @BetaApi
+  public static InstantiatingHttpJsonChannelProvider.Builder
+      defaultHttpJsonTransportProviderBuilder() {
+    return InstanceAdminStubSettings.defaultHttpJsonTransportProviderBuilder();
+  }
+
   public static TransportChannelProvider defaultTransportChannelProvider() {
     return InstanceAdminStubSettings.defaultTransportChannelProvider();
   }
@@ -197,11 +205,17 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil
     return InstanceAdminStubSettings.defaultApiClientHeaderProviderBuilder();
   }
 
-  /** Returns a new builder for this class. */
+  /** Returns a new gRPC builder for this class. */
   public static Builder newBuilder() {
     return Builder.createDefault();
   }
 
+  /** Returns a new REST builder for this class. */
+  @BetaApi
+  public static Builder newHttpJsonBuilder() {
+    return Builder.createHttpJsonDefault();
+  }
+
   /** Returns a new builder for this class. */
   public static Builder newBuilder(ClientContext clientContext) {
     return new Builder(clientContext);
@@ -239,6 +253,11 @@ private static Builder createDefault() {
       return new Builder(InstanceAdminStubSettings.newBuilder());
     }
 
+    @BetaApi
+    private static Builder createHttpJsonDefault() {
+      return new Builder(InstanceAdminStubSettings.newHttpJsonBuilder());
+    }
+
     public InstanceAdminStubSettings.Builder getStubSettingsBuilder() {
       return ((InstanceAdminStubSettings.Builder) getStubSettings());
     }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminCallableFactory.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminCallableFactory.java
new file mode 100644
index 00000000000..73ca894a437
--- /dev/null
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminCallableFactory.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.admin.instance.v1.stub;
+
+import com.google.api.core.BetaApi;
+import com.google.api.gax.httpjson.HttpJsonCallSettings;
+import com.google.api.gax.httpjson.HttpJsonCallableFactory;
+import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable;
+import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
+import com.google.api.gax.httpjson.longrunning.stub.OperationsStub;
+import com.google.api.gax.rpc.BatchingCallSettings;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.OperationCallSettings;
+import com.google.api.gax.rpc.OperationCallable;
+import com.google.api.gax.rpc.PagedCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallable;
+import com.google.api.gax.rpc.UnaryCallSettings;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.longrunning.Operation;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * REST callable factory implementation for the InstanceAdmin service API.
+ *
+ * <p>This class is for advanced usage.
+ */
+@Generated("by gapic-generator-java")
+@BetaApi
+public class HttpJsonInstanceAdminCallableFactory
+    implements HttpJsonStubCallableFactory<Operation, OperationsStub> {
+
+  @Override
+  public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCallable(
+      HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+      UnaryCallSettings<RequestT, ResponseT> callSettings,
+      ClientContext clientContext) {
+    return HttpJsonCallableFactory.createUnaryCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @Override
+  public <RequestT, ResponseT, PagedListResponseT>
+      UnaryCallable<RequestT, PagedListResponseT> createPagedCallable(
+          HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+          PagedCallSettings<RequestT, ResponseT, PagedListResponseT> callSettings,
+          ClientContext clientContext) {
+    return HttpJsonCallableFactory.createPagedCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @Override
+  public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createBatchingCallable(
+      HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+      BatchingCallSettings<RequestT, ResponseT> callSettings,
+      ClientContext clientContext) {
+    return HttpJsonCallableFactory.createBatchingCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @BetaApi(
+      "The surface for long-running operations is not stable yet and may change in the future.")
+  @Override
+  public <RequestT, ResponseT, MetadataT>
+      OperationCallable<RequestT, ResponseT, MetadataT> createOperationCallable(
+          HttpJsonCallSettings<RequestT, Operation> httpJsonCallSettings,
+          OperationCallSettings<RequestT, ResponseT, MetadataT> callSettings,
+          ClientContext clientContext,
+          OperationsStub operationsStub) {
+    UnaryCallable<RequestT, Operation> innerCallable =
+        HttpJsonCallableFactory.createBaseUnaryCallable(
+            httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext);
+    HttpJsonOperationSnapshotCallable<RequestT, Operation> initialCallable =
+        new HttpJsonOperationSnapshotCallable<RequestT, Operation>(
+            innerCallable,
+            httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory());
+    return HttpJsonCallableFactory.createOperationCallable(
+        callSettings, clientContext, operationsStub.longRunningClient(), initialCallable);
+  }
+
+  @Override
+  public <RequestT, ResponseT>
+      ServerStreamingCallable<RequestT, ResponseT> createServerStreamingCallable(
+          HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+          ServerStreamingCallSettings<RequestT, ResponseT> callSettings,
+          ClientContext clientContext) {
+    return HttpJsonCallableFactory.createServerStreamingCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminStub.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminStub.java
new file mode 100644
index 00000000000..27fc3b60e59
--- /dev/null
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/HttpJsonInstanceAdminStub.java
@@ -0,0 +1,755 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.admin.instance.v1.stub;
+
+import static com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient.ListInstanceConfigsPagedResponse;
+import static com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient.ListInstancesPagedResponse;
+
+import com.google.api.core.BetaApi;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.core.BackgroundResource;
+import com.google.api.gax.core.BackgroundResourceAggregation;
+import com.google.api.gax.httpjson.ApiMethodDescriptor;
+import com.google.api.gax.httpjson.HttpJsonCallSettings;
+import com.google.api.gax.httpjson.HttpJsonOperationSnapshot;
+import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
+import com.google.api.gax.httpjson.ProtoMessageRequestFormatter;
+import com.google.api.gax.httpjson.ProtoMessageResponseParser;
+import com.google.api.gax.httpjson.ProtoRestSerializer;
+import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.OperationCallable;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.iam.v1.GetIamPolicyRequest;
+import com.google.iam.v1.Policy;
+import com.google.iam.v1.SetIamPolicyRequest;
+import com.google.iam.v1.TestIamPermissionsRequest;
+import com.google.iam.v1.TestIamPermissionsResponse;
+import com.google.longrunning.Operation;
+import com.google.protobuf.Empty;
+import com.google.protobuf.TypeRegistry;
+import com.google.spanner.admin.instance.v1.CreateInstanceMetadata;
+import com.google.spanner.admin.instance.v1.CreateInstanceRequest;
+import com.google.spanner.admin.instance.v1.DeleteInstanceRequest;
+import com.google.spanner.admin.instance.v1.GetInstanceConfigRequest;
+import com.google.spanner.admin.instance.v1.GetInstanceRequest;
+import com.google.spanner.admin.instance.v1.Instance;
+import com.google.spanner.admin.instance.v1.InstanceConfig;
+import com.google.spanner.admin.instance.v1.ListInstanceConfigsRequest;
+import com.google.spanner.admin.instance.v1.ListInstanceConfigsResponse;
+import com.google.spanner.admin.instance.v1.ListInstancesRequest;
+import com.google.spanner.admin.instance.v1.ListInstancesResponse;
+import com.google.spanner.admin.instance.v1.UpdateInstanceMetadata;
+import com.google.spanner.admin.instance.v1.UpdateInstanceRequest;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * REST stub implementation for the InstanceAdmin service API.
+ *
+ * <p>This class is for advanced usage and reflects the underlying API directly.
+ */
+@Generated("by gapic-generator-java")
+@BetaApi
+public class HttpJsonInstanceAdminStub extends InstanceAdminStub {
+  private static final TypeRegistry typeRegistry =
+      TypeRegistry.newBuilder()
+          .add(Instance.getDescriptor())
+          .add(UpdateInstanceMetadata.getDescriptor())
+          .add(CreateInstanceMetadata.getDescriptor())
+          .build();
+
+  private static final ApiMethodDescriptor<ListInstanceConfigsRequest, ListInstanceConfigsResponse>
+      listInstanceConfigsMethodDescriptor =
+          ApiMethodDescriptor.<ListInstanceConfigsRequest, ListInstanceConfigsResponse>newBuilder()
+              .setFullMethodName(
+                  "google.spanner.admin.instance.v1.InstanceAdmin/ListInstanceConfigs")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListInstanceConfigsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*}/instanceConfigs",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListInstanceConfigsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListInstanceConfigsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListInstanceConfigsResponse>newBuilder()
+                      .setDefaultInstance(ListInstanceConfigsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<GetInstanceConfigRequest, InstanceConfig>
+      getInstanceConfigMethodDescriptor =
+          ApiMethodDescriptor.<GetInstanceConfigRequest, InstanceConfig>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/GetInstanceConfig")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<GetInstanceConfigRequest>newBuilder()
+                      .setPath(
+                          "/v1/{name=projects/*/instanceConfigs/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<GetInstanceConfigRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "name", request.getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<GetInstanceConfigRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<InstanceConfig>newBuilder()
+                      .setDefaultInstance(InstanceConfig.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<ListInstancesRequest, ListInstancesResponse>
+      listInstancesMethodDescriptor =
+          ApiMethodDescriptor.<ListInstancesRequest, ListInstancesResponse>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/ListInstances")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListInstancesRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*}/instances",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListInstancesRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListInstancesRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "filter", request.getFilter());
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListInstancesResponse>newBuilder()
+                      .setDefaultInstance(ListInstancesResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<GetInstanceRequest, Instance>
+      getInstanceMethodDescriptor =
+          ApiMethodDescriptor.<GetInstanceRequest, Instance>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/GetInstance")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<GetInstanceRequest>newBuilder()
+                      .setPath(
+                          "/v1/{name=projects/*/instances/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<GetInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "name", request.getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<GetInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "fieldMask", request.getFieldMask());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Instance>newBuilder()
+                      .setDefaultInstance(Instance.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<CreateInstanceRequest, Operation>
+      createInstanceMethodDescriptor =
+          ApiMethodDescriptor.<CreateInstanceRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/CreateInstance")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<CreateInstanceRequest>newBuilder()
+                      .setPath(
+                          "/v1/{parent=projects/*}/instances",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "parent", request.getParent());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearParent().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (CreateInstanceRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<UpdateInstanceRequest, Operation>
+      updateInstanceMethodDescriptor =
+          ApiMethodDescriptor.<UpdateInstanceRequest, Operation>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/UpdateInstance")
+              .setHttpMethod("PATCH")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<UpdateInstanceRequest>newBuilder()
+                      .setPath(
+                          "/v1/{instance.name=projects/*/instances/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<UpdateInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(
+                                fields, "instance.name", request.getInstance().getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<UpdateInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create().toBody("*", request.toBuilder().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Operation>newBuilder()
+                      .setDefaultInstance(Operation.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .setOperationSnapshotFactory(
+                  (UpdateInstanceRequest request, Operation response) ->
+                      HttpJsonOperationSnapshot.create(response))
+              .build();
+
+  private static final ApiMethodDescriptor<DeleteInstanceRequest, Empty>
+      deleteInstanceMethodDescriptor =
+          ApiMethodDescriptor.<DeleteInstanceRequest, Empty>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/DeleteInstance")
+              .setHttpMethod("DELETE")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<DeleteInstanceRequest>newBuilder()
+                      .setPath(
+                          "/v1/{name=projects/*/instances/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<DeleteInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "name", request.getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<DeleteInstanceRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Empty>newBuilder()
+                      .setDefaultInstance(Empty.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<SetIamPolicyRequest, Policy>
+      setIamPolicyMethodDescriptor =
+          ApiMethodDescriptor.<SetIamPolicyRequest, Policy>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/SetIamPolicy")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<SetIamPolicyRequest>newBuilder()
+                      .setPath(
+                          "/v1/{resource=projects/*/instances/*}:setIamPolicy",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<SetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "resource", request.getResource());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<SetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearResource().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Policy>newBuilder()
+                      .setDefaultInstance(Policy.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<GetIamPolicyRequest, Policy>
+      getIamPolicyMethodDescriptor =
+          ApiMethodDescriptor.<GetIamPolicyRequest, Policy>newBuilder()
+              .setFullMethodName("google.spanner.admin.instance.v1.InstanceAdmin/GetIamPolicy")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<GetIamPolicyRequest>newBuilder()
+                      .setPath(
+                          "/v1/{resource=projects/*/instances/*}:getIamPolicy",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<GetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "resource", request.getResource());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<GetIamPolicyRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearResource().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Policy>newBuilder()
+                      .setDefaultInstance(Policy.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<TestIamPermissionsRequest, TestIamPermissionsResponse>
+      testIamPermissionsMethodDescriptor =
+          ApiMethodDescriptor.<TestIamPermissionsRequest, TestIamPermissionsResponse>newBuilder()
+              .setFullMethodName(
+                  "google.spanner.admin.instance.v1.InstanceAdmin/TestIamPermissions")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<TestIamPermissionsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{resource=projects/*/instances/*}:testIamPermissions",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<TestIamPermissionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "resource", request.getResource());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<TestIamPermissionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearResource().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<TestIamPermissionsResponse>newBuilder()
+                      .setDefaultInstance(TestIamPermissionsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private final UnaryCallable<ListInstanceConfigsRequest, ListInstanceConfigsResponse>
+      listInstanceConfigsCallable;
+  private final UnaryCallable<ListInstanceConfigsRequest, ListInstanceConfigsPagedResponse>
+      listInstanceConfigsPagedCallable;
+  private final UnaryCallable<GetInstanceConfigRequest, InstanceConfig> getInstanceConfigCallable;
+  private final UnaryCallable<ListInstancesRequest, ListInstancesResponse> listInstancesCallable;
+  private final UnaryCallable<ListInstancesRequest, ListInstancesPagedResponse>
+      listInstancesPagedCallable;
+  private final UnaryCallable<GetInstanceRequest, Instance> getInstanceCallable;
+  private final UnaryCallable<CreateInstanceRequest, Operation> createInstanceCallable;
+  private final OperationCallable<CreateInstanceRequest, Instance, CreateInstanceMetadata>
+      createInstanceOperationCallable;
+  private final UnaryCallable<UpdateInstanceRequest, Operation> updateInstanceCallable;
+  private final OperationCallable<UpdateInstanceRequest, Instance, UpdateInstanceMetadata>
+      updateInstanceOperationCallable;
+  private final UnaryCallable<DeleteInstanceRequest, Empty> deleteInstanceCallable;
+  private final UnaryCallable<SetIamPolicyRequest, Policy> setIamPolicyCallable;
+  private final UnaryCallable<GetIamPolicyRequest, Policy> getIamPolicyCallable;
+  private final UnaryCallable<TestIamPermissionsRequest, TestIamPermissionsResponse>
+      testIamPermissionsCallable;
+
+  private final BackgroundResource backgroundResources;
+  private final HttpJsonOperationsStub httpJsonOperationsStub;
+  private final HttpJsonStubCallableFactory callableFactory;
+
+  public static final HttpJsonInstanceAdminStub create(InstanceAdminStubSettings settings)
+      throws IOException {
+    return new HttpJsonInstanceAdminStub(settings, ClientContext.create(settings));
+  }
+
+  public static final HttpJsonInstanceAdminStub create(ClientContext clientContext)
+      throws IOException {
+    return new HttpJsonInstanceAdminStub(
+        InstanceAdminStubSettings.newHttpJsonBuilder().build(), clientContext);
+  }
+
+  public static final HttpJsonInstanceAdminStub create(
+      ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException {
+    return new HttpJsonInstanceAdminStub(
+        InstanceAdminStubSettings.newHttpJsonBuilder().build(), clientContext, callableFactory);
+  }
+
+  /**
+   * Constructs an instance of HttpJsonInstanceAdminStub, using the given settings. This is
+   * protected so that it is easy to make a subclass, but otherwise, the static factory methods
+   * should be preferred.
+   */
+  protected HttpJsonInstanceAdminStub(
+      InstanceAdminStubSettings settings, ClientContext clientContext) throws IOException {
+    this(settings, clientContext, new HttpJsonInstanceAdminCallableFactory());
+  }
+
+  /**
+   * Constructs an instance of HttpJsonInstanceAdminStub, using the given settings. This is
+   * protected so that it is easy to make a subclass, but otherwise, the static factory methods
+   * should be preferred.
+   */
+  protected HttpJsonInstanceAdminStub(
+      InstanceAdminStubSettings settings,
+      ClientContext clientContext,
+      HttpJsonStubCallableFactory callableFactory)
+      throws IOException {
+    this.callableFactory = callableFactory;
+    this.httpJsonOperationsStub =
+        HttpJsonOperationsStub.create(clientContext, callableFactory, typeRegistry);
+
+    HttpJsonCallSettings<ListInstanceConfigsRequest, ListInstanceConfigsResponse>
+        listInstanceConfigsTransportSettings =
+            HttpJsonCallSettings
+                .<ListInstanceConfigsRequest, ListInstanceConfigsResponse>newBuilder()
+                .setMethodDescriptor(listInstanceConfigsMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<GetInstanceConfigRequest, InstanceConfig>
+        getInstanceConfigTransportSettings =
+            HttpJsonCallSettings.<GetInstanceConfigRequest, InstanceConfig>newBuilder()
+                .setMethodDescriptor(getInstanceConfigMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<ListInstancesRequest, ListInstancesResponse>
+        listInstancesTransportSettings =
+            HttpJsonCallSettings.<ListInstancesRequest, ListInstancesResponse>newBuilder()
+                .setMethodDescriptor(listInstancesMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<GetInstanceRequest, Instance> getInstanceTransportSettings =
+        HttpJsonCallSettings.<GetInstanceRequest, Instance>newBuilder()
+            .setMethodDescriptor(getInstanceMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<CreateInstanceRequest, Operation> createInstanceTransportSettings =
+        HttpJsonCallSettings.<CreateInstanceRequest, Operation>newBuilder()
+            .setMethodDescriptor(createInstanceMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<UpdateInstanceRequest, Operation> updateInstanceTransportSettings =
+        HttpJsonCallSettings.<UpdateInstanceRequest, Operation>newBuilder()
+            .setMethodDescriptor(updateInstanceMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<DeleteInstanceRequest, Empty> deleteInstanceTransportSettings =
+        HttpJsonCallSettings.<DeleteInstanceRequest, Empty>newBuilder()
+            .setMethodDescriptor(deleteInstanceMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<SetIamPolicyRequest, Policy> setIamPolicyTransportSettings =
+        HttpJsonCallSettings.<SetIamPolicyRequest, Policy>newBuilder()
+            .setMethodDescriptor(setIamPolicyMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<GetIamPolicyRequest, Policy> getIamPolicyTransportSettings =
+        HttpJsonCallSettings.<GetIamPolicyRequest, Policy>newBuilder()
+            .setMethodDescriptor(getIamPolicyMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<TestIamPermissionsRequest, TestIamPermissionsResponse>
+        testIamPermissionsTransportSettings =
+            HttpJsonCallSettings.<TestIamPermissionsRequest, TestIamPermissionsResponse>newBuilder()
+                .setMethodDescriptor(testIamPermissionsMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+
+    this.listInstanceConfigsCallable =
+        callableFactory.createUnaryCallable(
+            listInstanceConfigsTransportSettings,
+            settings.listInstanceConfigsSettings(),
+            clientContext);
+    this.listInstanceConfigsPagedCallable =
+        callableFactory.createPagedCallable(
+            listInstanceConfigsTransportSettings,
+            settings.listInstanceConfigsSettings(),
+            clientContext);
+    this.getInstanceConfigCallable =
+        callableFactory.createUnaryCallable(
+            getInstanceConfigTransportSettings,
+            settings.getInstanceConfigSettings(),
+            clientContext);
+    this.listInstancesCallable =
+        callableFactory.createUnaryCallable(
+            listInstancesTransportSettings, settings.listInstancesSettings(), clientContext);
+    this.listInstancesPagedCallable =
+        callableFactory.createPagedCallable(
+            listInstancesTransportSettings, settings.listInstancesSettings(), clientContext);
+    this.getInstanceCallable =
+        callableFactory.createUnaryCallable(
+            getInstanceTransportSettings, settings.getInstanceSettings(), clientContext);
+    this.createInstanceCallable =
+        callableFactory.createUnaryCallable(
+            createInstanceTransportSettings, settings.createInstanceSettings(), clientContext);
+    this.createInstanceOperationCallable =
+        callableFactory.createOperationCallable(
+            createInstanceTransportSettings,
+            settings.createInstanceOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.updateInstanceCallable =
+        callableFactory.createUnaryCallable(
+            updateInstanceTransportSettings, settings.updateInstanceSettings(), clientContext);
+    this.updateInstanceOperationCallable =
+        callableFactory.createOperationCallable(
+            updateInstanceTransportSettings,
+            settings.updateInstanceOperationSettings(),
+            clientContext,
+            httpJsonOperationsStub);
+    this.deleteInstanceCallable =
+        callableFactory.createUnaryCallable(
+            deleteInstanceTransportSettings, settings.deleteInstanceSettings(), clientContext);
+    this.setIamPolicyCallable =
+        callableFactory.createUnaryCallable(
+            setIamPolicyTransportSettings, settings.setIamPolicySettings(), clientContext);
+    this.getIamPolicyCallable =
+        callableFactory.createUnaryCallable(
+            getIamPolicyTransportSettings, settings.getIamPolicySettings(), clientContext);
+    this.testIamPermissionsCallable =
+        callableFactory.createUnaryCallable(
+            testIamPermissionsTransportSettings,
+            settings.testIamPermissionsSettings(),
+            clientContext);
+
+    this.backgroundResources =
+        new BackgroundResourceAggregation(clientContext.getBackgroundResources());
+  }
+
+  @InternalApi
+  public static List<ApiMethodDescriptor> getMethodDescriptors() {
+    List<ApiMethodDescriptor> methodDescriptors = new ArrayList<>();
+    methodDescriptors.add(listInstanceConfigsMethodDescriptor);
+    methodDescriptors.add(getInstanceConfigMethodDescriptor);
+    methodDescriptors.add(listInstancesMethodDescriptor);
+    methodDescriptors.add(getInstanceMethodDescriptor);
+    methodDescriptors.add(createInstanceMethodDescriptor);
+    methodDescriptors.add(updateInstanceMethodDescriptor);
+    methodDescriptors.add(deleteInstanceMethodDescriptor);
+    methodDescriptors.add(setIamPolicyMethodDescriptor);
+    methodDescriptors.add(getIamPolicyMethodDescriptor);
+    methodDescriptors.add(testIamPermissionsMethodDescriptor);
+    return methodDescriptors;
+  }
+
+  public HttpJsonOperationsStub getHttpJsonOperationsStub() {
+    return httpJsonOperationsStub;
+  }
+
+  @Override
+  public UnaryCallable<ListInstanceConfigsRequest, ListInstanceConfigsResponse>
+      listInstanceConfigsCallable() {
+    return listInstanceConfigsCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListInstanceConfigsRequest, ListInstanceConfigsPagedResponse>
+      listInstanceConfigsPagedCallable() {
+    return listInstanceConfigsPagedCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetInstanceConfigRequest, InstanceConfig> getInstanceConfigCallable() {
+    return getInstanceConfigCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListInstancesRequest, ListInstancesResponse> listInstancesCallable() {
+    return listInstancesCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListInstancesRequest, ListInstancesPagedResponse>
+      listInstancesPagedCallable() {
+    return listInstancesPagedCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetInstanceRequest, Instance> getInstanceCallable() {
+    return getInstanceCallable;
+  }
+
+  @Override
+  public UnaryCallable<CreateInstanceRequest, Operation> createInstanceCallable() {
+    return createInstanceCallable;
+  }
+
+  @Override
+  public OperationCallable<CreateInstanceRequest, Instance, CreateInstanceMetadata>
+      createInstanceOperationCallable() {
+    return createInstanceOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<UpdateInstanceRequest, Operation> updateInstanceCallable() {
+    return updateInstanceCallable;
+  }
+
+  @Override
+  public OperationCallable<UpdateInstanceRequest, Instance, UpdateInstanceMetadata>
+      updateInstanceOperationCallable() {
+    return updateInstanceOperationCallable;
+  }
+
+  @Override
+  public UnaryCallable<DeleteInstanceRequest, Empty> deleteInstanceCallable() {
+    return deleteInstanceCallable;
+  }
+
+  @Override
+  public UnaryCallable<SetIamPolicyRequest, Policy> setIamPolicyCallable() {
+    return setIamPolicyCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetIamPolicyRequest, Policy> getIamPolicyCallable() {
+    return getIamPolicyCallable;
+  }
+
+  @Override
+  public UnaryCallable<TestIamPermissionsRequest, TestIamPermissionsResponse>
+      testIamPermissionsCallable() {
+    return testIamPermissionsCallable;
+  }
+
+  @Override
+  public final void close() {
+    try {
+      backgroundResources.close();
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IllegalStateException("Failed to close resource", e);
+    }
+  }
+
+  @Override
+  public void shutdown() {
+    backgroundResources.shutdown();
+  }
+
+  @Override
+  public boolean isShutdown() {
+    return backgroundResources.isShutdown();
+  }
+
+  @Override
+  public boolean isTerminated() {
+    return backgroundResources.isTerminated();
+  }
+
+  @Override
+  public void shutdownNow() {
+    backgroundResources.shutdownNow();
+  }
+
+  @Override
+  public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException {
+    return backgroundResources.awaitTermination(duration, unit);
+  }
+}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStub.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStub.java
index dbc187aee61..296f006d587 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStub.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStub.java
@@ -55,7 +55,11 @@
 public abstract class InstanceAdminStub implements BackgroundResource {
 
   public OperationsStub getOperationsStub() {
-    throw new UnsupportedOperationException("Not implemented: getOperationsStub()");
+    return null;
+  }
+
+  public com.google.api.gax.httpjson.longrunning.stub.OperationsStub getHttpJsonOperationsStub() {
+    return null;
   }
 
   public UnaryCallable<ListInstanceConfigsRequest, ListInstanceConfigsPagedResponse>
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java
index 4fa9ec0431a..fb1926bccab 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/instance/v1/stub/InstanceAdminStubSettings.java
@@ -29,6 +29,9 @@
 import com.google.api.gax.grpc.GrpcTransportChannel;
 import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
 import com.google.api.gax.grpc.ProtoOperationTransformers;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.HttpJsonTransportChannel;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
 import com.google.api.gax.longrunning.OperationSnapshot;
 import com.google.api.gax.longrunning.OperationTimedPollAlgorithm;
 import com.google.api.gax.retrying.RetrySettings;
@@ -324,6 +327,11 @@ public InstanceAdminStub createStub() throws IOException {
         .equals(GrpcTransportChannel.getGrpcTransportName())) {
       return GrpcInstanceAdminStub.create(this);
     }
+    if (getTransportChannelProvider()
+        .getTransportName()
+        .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) {
+      return HttpJsonInstanceAdminStub.create(this);
+    }
     throw new UnsupportedOperationException(
         String.format(
             "Transport not supported: %s", getTransportChannelProvider().getTransportName()));
@@ -356,18 +364,25 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde
         .setUseJwtAccessWithScope(true);
   }
 
-  /** Returns a builder for the default ChannelProvider for this service. */
+  /** Returns a builder for the default gRPC ChannelProvider for this service. */
   public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() {
     return InstantiatingGrpcChannelProvider.newBuilder()
         .setMaxInboundMessageSize(Integer.MAX_VALUE);
   }
 
+  /** Returns a builder for the default REST ChannelProvider for this service. */
+  @BetaApi
+  public static InstantiatingHttpJsonChannelProvider.Builder
+      defaultHttpJsonTransportProviderBuilder() {
+    return InstantiatingHttpJsonChannelProvider.newBuilder();
+  }
+
   public static TransportChannelProvider defaultTransportChannelProvider() {
     return defaultGrpcTransportProviderBuilder().build();
   }
 
   @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
-  public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
+  public static ApiClientHeaderProvider.Builder defaultGrpcApiClientHeaderProviderBuilder() {
     return ApiClientHeaderProvider.newBuilder()
         .setGeneratedLibToken(
             "gapic", GaxProperties.getLibraryVersion(InstanceAdminStubSettings.class))
@@ -375,11 +390,30 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil
             GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion());
   }
 
-  /** Returns a new builder for this class. */
+  @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
+  public static ApiClientHeaderProvider.Builder defaultHttpJsonApiClientHeaderProviderBuilder() {
+    return ApiClientHeaderProvider.newBuilder()
+        .setGeneratedLibToken(
+            "gapic", GaxProperties.getLibraryVersion(InstanceAdminStubSettings.class))
+        .setTransportToken(
+            GaxHttpJsonProperties.getHttpJsonTokenName(),
+            GaxHttpJsonProperties.getHttpJsonVersion());
+  }
+
+  public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
+    return InstanceAdminStubSettings.defaultGrpcApiClientHeaderProviderBuilder();
+  }
+
+  /** Returns a new gRPC builder for this class. */
   public static Builder newBuilder() {
     return Builder.createDefault();
   }
 
+  /** Returns a new REST builder for this class. */
+  public static Builder newHttpJsonBuilder() {
+    return Builder.createHttpJsonDefault();
+  }
+
   /** Returns a new builder for this class. */
   public static Builder newBuilder(ClientContext clientContext) {
     return new Builder(clientContext);
@@ -584,6 +618,19 @@ private static Builder createDefault() {
       return initDefaults(builder);
     }
 
+    private static Builder createHttpJsonDefault() {
+      Builder builder = new Builder(((ClientContext) null));
+
+      builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build());
+      builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build());
+      builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build());
+      builder.setEndpoint(getDefaultEndpoint());
+      builder.setMtlsEndpoint(getDefaultMtlsEndpoint());
+      builder.setSwitchToMtlsEndpointAllowed(true);
+
+      return initDefaults(builder);
+    }
+
     private static Builder initDefaults(Builder builder) {
       builder
           .listInstanceConfigsSettings()
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java
index c6e1d01c389..76bc2690983 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java
@@ -127,6 +127,20 @@
  * SpannerClient spannerClient = SpannerClient.create(spannerSettings);
  * }</pre>
  *
+ * <p>To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending and receiving requests over
+ * the wire:
+ *
+ * <pre>{@code
+ * // This snippet has been automatically generated for illustrative purposes only.
+ * // It may require modifications to work in your environment.
+ * SpannerSettings spannerSettings =
+ *     SpannerSettings.newBuilder()
+ *         .setTransportChannelProvider(
+ *             SpannerSettings.defaultHttpJsonTransportProviderBuilder().build())
+ *         .build();
+ * SpannerClient spannerClient = SpannerClient.create(spannerSettings);
+ * }</pre>
+ *
  * <p>Please refer to the GitHub repository's samples for more quickstart code snippets.
  */
 @Generated("by gapic-generator-java")
@@ -701,7 +715,7 @@ public final ListSessionsPagedResponse listSessions(ListSessionsRequest request)
    *           .build();
    *   while (true) {
    *     ListSessionsResponse response = spannerClient.listSessionsCallable().call(request);
-   *     for (Session element : response.getResponsesList()) {
+   *     for (Session element : response.getSessionsList()) {
    *       // doThingsWith(element);
    *     }
    *     String nextPageToken = response.getNextPageToken();
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerSettings.java
index 6541b6528ce..5abf4e1c53f 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerSettings.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerSettings.java
@@ -23,6 +23,7 @@
 import com.google.api.gax.core.GoogleCredentialsProvider;
 import com.google.api.gax.core.InstantiatingExecutorProvider;
 import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
 import com.google.api.gax.rpc.ApiClientHeaderProvider;
 import com.google.api.gax.rpc.ClientContext;
 import com.google.api.gax.rpc.ClientSettings;
@@ -197,11 +198,18 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde
     return SpannerStubSettings.defaultCredentialsProviderBuilder();
   }
 
-  /** Returns a builder for the default ChannelProvider for this service. */
+  /** Returns a builder for the default gRPC ChannelProvider for this service. */
   public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() {
     return SpannerStubSettings.defaultGrpcTransportProviderBuilder();
   }
 
+  /** Returns a builder for the default REST ChannelProvider for this service. */
+  @BetaApi
+  public static InstantiatingHttpJsonChannelProvider.Builder
+      defaultHttpJsonTransportProviderBuilder() {
+    return SpannerStubSettings.defaultHttpJsonTransportProviderBuilder();
+  }
+
   public static TransportChannelProvider defaultTransportChannelProvider() {
     return SpannerStubSettings.defaultTransportChannelProvider();
   }
@@ -211,11 +219,17 @@ public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuil
     return SpannerStubSettings.defaultApiClientHeaderProviderBuilder();
   }
 
-  /** Returns a new builder for this class. */
+  /** Returns a new gRPC builder for this class. */
   public static Builder newBuilder() {
     return Builder.createDefault();
   }
 
+  /** Returns a new REST builder for this class. */
+  @BetaApi
+  public static Builder newHttpJsonBuilder() {
+    return Builder.createHttpJsonDefault();
+  }
+
   /** Returns a new builder for this class. */
   public static Builder newBuilder(ClientContext clientContext) {
     return new Builder(clientContext);
@@ -253,6 +267,11 @@ private static Builder createDefault() {
       return new Builder(SpannerStubSettings.newBuilder());
     }
 
+    @BetaApi
+    private static Builder createHttpJsonDefault() {
+      return new Builder(SpannerStubSettings.newHttpJsonBuilder());
+    }
+
     public SpannerStubSettings.Builder getStubSettingsBuilder() {
       return ((SpannerStubSettings.Builder) getStubSettings());
     }
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerCallableFactory.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerCallableFactory.java
new file mode 100644
index 00000000000..97dfaf2dab9
--- /dev/null
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerCallableFactory.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.v1.stub;
+
+import com.google.api.core.BetaApi;
+import com.google.api.gax.httpjson.HttpJsonCallSettings;
+import com.google.api.gax.httpjson.HttpJsonCallableFactory;
+import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable;
+import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
+import com.google.api.gax.httpjson.longrunning.stub.OperationsStub;
+import com.google.api.gax.rpc.BatchingCallSettings;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.OperationCallSettings;
+import com.google.api.gax.rpc.OperationCallable;
+import com.google.api.gax.rpc.PagedCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallSettings;
+import com.google.api.gax.rpc.ServerStreamingCallable;
+import com.google.api.gax.rpc.UnaryCallSettings;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.longrunning.Operation;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * REST callable factory implementation for the Spanner service API.
+ *
+ * <p>This class is for advanced usage.
+ */
+@Generated("by gapic-generator-java")
+@BetaApi
+public class HttpJsonSpannerCallableFactory
+    implements HttpJsonStubCallableFactory<Operation, OperationsStub> {
+
+  @Override
+  public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCallable(
+      HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+      UnaryCallSettings<RequestT, ResponseT> callSettings,
+      ClientContext clientContext) {
+    return HttpJsonCallableFactory.createUnaryCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @Override
+  public <RequestT, ResponseT, PagedListResponseT>
+      UnaryCallable<RequestT, PagedListResponseT> createPagedCallable(
+          HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+          PagedCallSettings<RequestT, ResponseT, PagedListResponseT> callSettings,
+          ClientContext clientContext) {
+    return HttpJsonCallableFactory.createPagedCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @Override
+  public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createBatchingCallable(
+      HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+      BatchingCallSettings<RequestT, ResponseT> callSettings,
+      ClientContext clientContext) {
+    return HttpJsonCallableFactory.createBatchingCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+
+  @BetaApi(
+      "The surface for long-running operations is not stable yet and may change in the future.")
+  @Override
+  public <RequestT, ResponseT, MetadataT>
+      OperationCallable<RequestT, ResponseT, MetadataT> createOperationCallable(
+          HttpJsonCallSettings<RequestT, Operation> httpJsonCallSettings,
+          OperationCallSettings<RequestT, ResponseT, MetadataT> callSettings,
+          ClientContext clientContext,
+          OperationsStub operationsStub) {
+    UnaryCallable<RequestT, Operation> innerCallable =
+        HttpJsonCallableFactory.createBaseUnaryCallable(
+            httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext);
+    HttpJsonOperationSnapshotCallable<RequestT, Operation> initialCallable =
+        new HttpJsonOperationSnapshotCallable<RequestT, Operation>(
+            innerCallable,
+            httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory());
+    return HttpJsonCallableFactory.createOperationCallable(
+        callSettings, clientContext, operationsStub.longRunningClient(), initialCallable);
+  }
+
+  @Override
+  public <RequestT, ResponseT>
+      ServerStreamingCallable<RequestT, ResponseT> createServerStreamingCallable(
+          HttpJsonCallSettings<RequestT, ResponseT> httpJsonCallSettings,
+          ServerStreamingCallSettings<RequestT, ResponseT> callSettings,
+          ClientContext clientContext) {
+    return HttpJsonCallableFactory.createServerStreamingCallable(
+        httpJsonCallSettings, callSettings, clientContext);
+  }
+}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerStub.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerStub.java
new file mode 100644
index 00000000000..8a07ec7a041
--- /dev/null
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/HttpJsonSpannerStub.java
@@ -0,0 +1,939 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.v1.stub;
+
+import static com.google.cloud.spanner.v1.SpannerClient.ListSessionsPagedResponse;
+
+import com.google.api.core.BetaApi;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.core.BackgroundResource;
+import com.google.api.gax.core.BackgroundResourceAggregation;
+import com.google.api.gax.httpjson.ApiMethodDescriptor;
+import com.google.api.gax.httpjson.HttpJsonCallSettings;
+import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
+import com.google.api.gax.httpjson.ProtoMessageRequestFormatter;
+import com.google.api.gax.httpjson.ProtoMessageResponseParser;
+import com.google.api.gax.httpjson.ProtoRestSerializer;
+import com.google.api.gax.rpc.ClientContext;
+import com.google.api.gax.rpc.ServerStreamingCallable;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.protobuf.Empty;
+import com.google.protobuf.TypeRegistry;
+import com.google.spanner.v1.BatchCreateSessionsRequest;
+import com.google.spanner.v1.BatchCreateSessionsResponse;
+import com.google.spanner.v1.BeginTransactionRequest;
+import com.google.spanner.v1.CommitRequest;
+import com.google.spanner.v1.CommitResponse;
+import com.google.spanner.v1.CreateSessionRequest;
+import com.google.spanner.v1.DeleteSessionRequest;
+import com.google.spanner.v1.ExecuteBatchDmlRequest;
+import com.google.spanner.v1.ExecuteBatchDmlResponse;
+import com.google.spanner.v1.ExecuteSqlRequest;
+import com.google.spanner.v1.GetSessionRequest;
+import com.google.spanner.v1.ListSessionsRequest;
+import com.google.spanner.v1.ListSessionsResponse;
+import com.google.spanner.v1.PartialResultSet;
+import com.google.spanner.v1.PartitionQueryRequest;
+import com.google.spanner.v1.PartitionReadRequest;
+import com.google.spanner.v1.PartitionResponse;
+import com.google.spanner.v1.ReadRequest;
+import com.google.spanner.v1.ResultSet;
+import com.google.spanner.v1.RollbackRequest;
+import com.google.spanner.v1.Session;
+import com.google.spanner.v1.Transaction;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * REST stub implementation for the Spanner service API.
+ *
+ * <p>This class is for advanced usage and reflects the underlying API directly.
+ */
+@Generated("by gapic-generator-java")
+@BetaApi
+public class HttpJsonSpannerStub extends SpannerStub {
+  private static final TypeRegistry typeRegistry = TypeRegistry.newBuilder().build();
+
+  private static final ApiMethodDescriptor<CreateSessionRequest, Session>
+      createSessionMethodDescriptor =
+          ApiMethodDescriptor.<CreateSessionRequest, Session>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/CreateSession")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<CreateSessionRequest>newBuilder()
+                      .setPath(
+                          "/v1/{database=projects/*/instances/*/databases/*}/sessions",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateSessionRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "database", request.getDatabase());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<CreateSessionRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearDatabase().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Session>newBuilder()
+                      .setDefaultInstance(Session.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<BatchCreateSessionsRequest, BatchCreateSessionsResponse>
+      batchCreateSessionsMethodDescriptor =
+          ApiMethodDescriptor.<BatchCreateSessionsRequest, BatchCreateSessionsResponse>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/BatchCreateSessions")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<BatchCreateSessionsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{database=projects/*/instances/*/databases/*}/sessions:batchCreate",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<BatchCreateSessionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "database", request.getDatabase());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<BatchCreateSessionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearDatabase().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<BatchCreateSessionsResponse>newBuilder()
+                      .setDefaultInstance(BatchCreateSessionsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<GetSessionRequest, Session> getSessionMethodDescriptor =
+      ApiMethodDescriptor.<GetSessionRequest, Session>newBuilder()
+          .setFullMethodName("google.spanner.v1.Spanner/GetSession")
+          .setHttpMethod("GET")
+          .setType(ApiMethodDescriptor.MethodType.UNARY)
+          .setRequestFormatter(
+              ProtoMessageRequestFormatter.<GetSessionRequest>newBuilder()
+                  .setPath(
+                      "/v1/{name=projects/*/instances/*/databases/*/sessions/*}",
+                      request -> {
+                        Map<String, String> fields = new HashMap<>();
+                        ProtoRestSerializer<GetSessionRequest> serializer =
+                            ProtoRestSerializer.create();
+                        serializer.putPathParam(fields, "name", request.getName());
+                        return fields;
+                      })
+                  .setQueryParamsExtractor(
+                      request -> {
+                        Map<String, List<String>> fields = new HashMap<>();
+                        ProtoRestSerializer<GetSessionRequest> serializer =
+                            ProtoRestSerializer.create();
+                        return fields;
+                      })
+                  .setRequestBodyExtractor(request -> null)
+                  .build())
+          .setResponseParser(
+              ProtoMessageResponseParser.<Session>newBuilder()
+                  .setDefaultInstance(Session.getDefaultInstance())
+                  .setDefaultTypeRegistry(typeRegistry)
+                  .build())
+          .build();
+
+  private static final ApiMethodDescriptor<ListSessionsRequest, ListSessionsResponse>
+      listSessionsMethodDescriptor =
+          ApiMethodDescriptor.<ListSessionsRequest, ListSessionsResponse>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/ListSessions")
+              .setHttpMethod("GET")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ListSessionsRequest>newBuilder()
+                      .setPath(
+                          "/v1/{database=projects/*/instances/*/databases/*}/sessions",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ListSessionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "database", request.getDatabase());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ListSessionsRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putQueryParam(fields, "filter", request.getFilter());
+                            serializer.putQueryParam(fields, "pageSize", request.getPageSize());
+                            serializer.putQueryParam(fields, "pageToken", request.getPageToken());
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ListSessionsResponse>newBuilder()
+                      .setDefaultInstance(ListSessionsResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<DeleteSessionRequest, Empty>
+      deleteSessionMethodDescriptor =
+          ApiMethodDescriptor.<DeleteSessionRequest, Empty>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/DeleteSession")
+              .setHttpMethod("DELETE")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<DeleteSessionRequest>newBuilder()
+                      .setPath(
+                          "/v1/{name=projects/*/instances/*/databases/*/sessions/*}",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<DeleteSessionRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "name", request.getName());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<DeleteSessionRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(request -> null)
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Empty>newBuilder()
+                      .setDefaultInstance(Empty.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<ExecuteSqlRequest, ResultSet>
+      executeSqlMethodDescriptor =
+          ApiMethodDescriptor.<ExecuteSqlRequest, ResultSet>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/ExecuteSql")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ExecuteSqlRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeSql",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ExecuteSqlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ExecuteSqlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ResultSet>newBuilder()
+                      .setDefaultInstance(ResultSet.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<ExecuteSqlRequest, PartialResultSet>
+      executeStreamingSqlMethodDescriptor =
+          ApiMethodDescriptor.<ExecuteSqlRequest, PartialResultSet>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/ExecuteStreamingSql")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.SERVER_STREAMING)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ExecuteSqlRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeStreamingSql",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ExecuteSqlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ExecuteSqlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<PartialResultSet>newBuilder()
+                      .setDefaultInstance(PartialResultSet.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<ExecuteBatchDmlRequest, ExecuteBatchDmlResponse>
+      executeBatchDmlMethodDescriptor =
+          ApiMethodDescriptor.<ExecuteBatchDmlRequest, ExecuteBatchDmlResponse>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/ExecuteBatchDml")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ExecuteBatchDmlRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeBatchDml",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ExecuteBatchDmlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ExecuteBatchDmlRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<ExecuteBatchDmlResponse>newBuilder()
+                      .setDefaultInstance(ExecuteBatchDmlResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<ReadRequest, ResultSet> readMethodDescriptor =
+      ApiMethodDescriptor.<ReadRequest, ResultSet>newBuilder()
+          .setFullMethodName("google.spanner.v1.Spanner/Read")
+          .setHttpMethod("POST")
+          .setType(ApiMethodDescriptor.MethodType.UNARY)
+          .setRequestFormatter(
+              ProtoMessageRequestFormatter.<ReadRequest>newBuilder()
+                  .setPath(
+                      "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:read",
+                      request -> {
+                        Map<String, String> fields = new HashMap<>();
+                        ProtoRestSerializer<ReadRequest> serializer = ProtoRestSerializer.create();
+                        serializer.putPathParam(fields, "session", request.getSession());
+                        return fields;
+                      })
+                  .setQueryParamsExtractor(
+                      request -> {
+                        Map<String, List<String>> fields = new HashMap<>();
+                        ProtoRestSerializer<ReadRequest> serializer = ProtoRestSerializer.create();
+                        return fields;
+                      })
+                  .setRequestBodyExtractor(
+                      request ->
+                          ProtoRestSerializer.create()
+                              .toBody("*", request.toBuilder().clearSession().build()))
+                  .build())
+          .setResponseParser(
+              ProtoMessageResponseParser.<ResultSet>newBuilder()
+                  .setDefaultInstance(ResultSet.getDefaultInstance())
+                  .setDefaultTypeRegistry(typeRegistry)
+                  .build())
+          .build();
+
+  private static final ApiMethodDescriptor<ReadRequest, PartialResultSet>
+      streamingReadMethodDescriptor =
+          ApiMethodDescriptor.<ReadRequest, PartialResultSet>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/StreamingRead")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.SERVER_STREAMING)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<ReadRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:streamingRead",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<ReadRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<ReadRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<PartialResultSet>newBuilder()
+                      .setDefaultInstance(PartialResultSet.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<BeginTransactionRequest, Transaction>
+      beginTransactionMethodDescriptor =
+          ApiMethodDescriptor.<BeginTransactionRequest, Transaction>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/BeginTransaction")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<BeginTransactionRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:beginTransaction",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<BeginTransactionRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<BeginTransactionRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<Transaction>newBuilder()
+                      .setDefaultInstance(Transaction.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<CommitRequest, CommitResponse> commitMethodDescriptor =
+      ApiMethodDescriptor.<CommitRequest, CommitResponse>newBuilder()
+          .setFullMethodName("google.spanner.v1.Spanner/Commit")
+          .setHttpMethod("POST")
+          .setType(ApiMethodDescriptor.MethodType.UNARY)
+          .setRequestFormatter(
+              ProtoMessageRequestFormatter.<CommitRequest>newBuilder()
+                  .setPath(
+                      "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:commit",
+                      request -> {
+                        Map<String, String> fields = new HashMap<>();
+                        ProtoRestSerializer<CommitRequest> serializer =
+                            ProtoRestSerializer.create();
+                        serializer.putPathParam(fields, "session", request.getSession());
+                        return fields;
+                      })
+                  .setQueryParamsExtractor(
+                      request -> {
+                        Map<String, List<String>> fields = new HashMap<>();
+                        ProtoRestSerializer<CommitRequest> serializer =
+                            ProtoRestSerializer.create();
+                        return fields;
+                      })
+                  .setRequestBodyExtractor(
+                      request ->
+                          ProtoRestSerializer.create()
+                              .toBody("*", request.toBuilder().clearSession().build()))
+                  .build())
+          .setResponseParser(
+              ProtoMessageResponseParser.<CommitResponse>newBuilder()
+                  .setDefaultInstance(CommitResponse.getDefaultInstance())
+                  .setDefaultTypeRegistry(typeRegistry)
+                  .build())
+          .build();
+
+  private static final ApiMethodDescriptor<RollbackRequest, Empty> rollbackMethodDescriptor =
+      ApiMethodDescriptor.<RollbackRequest, Empty>newBuilder()
+          .setFullMethodName("google.spanner.v1.Spanner/Rollback")
+          .setHttpMethod("POST")
+          .setType(ApiMethodDescriptor.MethodType.UNARY)
+          .setRequestFormatter(
+              ProtoMessageRequestFormatter.<RollbackRequest>newBuilder()
+                  .setPath(
+                      "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:rollback",
+                      request -> {
+                        Map<String, String> fields = new HashMap<>();
+                        ProtoRestSerializer<RollbackRequest> serializer =
+                            ProtoRestSerializer.create();
+                        serializer.putPathParam(fields, "session", request.getSession());
+                        return fields;
+                      })
+                  .setQueryParamsExtractor(
+                      request -> {
+                        Map<String, List<String>> fields = new HashMap<>();
+                        ProtoRestSerializer<RollbackRequest> serializer =
+                            ProtoRestSerializer.create();
+                        return fields;
+                      })
+                  .setRequestBodyExtractor(
+                      request ->
+                          ProtoRestSerializer.create()
+                              .toBody("*", request.toBuilder().clearSession().build()))
+                  .build())
+          .setResponseParser(
+              ProtoMessageResponseParser.<Empty>newBuilder()
+                  .setDefaultInstance(Empty.getDefaultInstance())
+                  .setDefaultTypeRegistry(typeRegistry)
+                  .build())
+          .build();
+
+  private static final ApiMethodDescriptor<PartitionQueryRequest, PartitionResponse>
+      partitionQueryMethodDescriptor =
+          ApiMethodDescriptor.<PartitionQueryRequest, PartitionResponse>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/PartitionQuery")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<PartitionQueryRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:partitionQuery",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<PartitionQueryRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<PartitionQueryRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<PartitionResponse>newBuilder()
+                      .setDefaultInstance(PartitionResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private static final ApiMethodDescriptor<PartitionReadRequest, PartitionResponse>
+      partitionReadMethodDescriptor =
+          ApiMethodDescriptor.<PartitionReadRequest, PartitionResponse>newBuilder()
+              .setFullMethodName("google.spanner.v1.Spanner/PartitionRead")
+              .setHttpMethod("POST")
+              .setType(ApiMethodDescriptor.MethodType.UNARY)
+              .setRequestFormatter(
+                  ProtoMessageRequestFormatter.<PartitionReadRequest>newBuilder()
+                      .setPath(
+                          "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:partitionRead",
+                          request -> {
+                            Map<String, String> fields = new HashMap<>();
+                            ProtoRestSerializer<PartitionReadRequest> serializer =
+                                ProtoRestSerializer.create();
+                            serializer.putPathParam(fields, "session", request.getSession());
+                            return fields;
+                          })
+                      .setQueryParamsExtractor(
+                          request -> {
+                            Map<String, List<String>> fields = new HashMap<>();
+                            ProtoRestSerializer<PartitionReadRequest> serializer =
+                                ProtoRestSerializer.create();
+                            return fields;
+                          })
+                      .setRequestBodyExtractor(
+                          request ->
+                              ProtoRestSerializer.create()
+                                  .toBody("*", request.toBuilder().clearSession().build()))
+                      .build())
+              .setResponseParser(
+                  ProtoMessageResponseParser.<PartitionResponse>newBuilder()
+                      .setDefaultInstance(PartitionResponse.getDefaultInstance())
+                      .setDefaultTypeRegistry(typeRegistry)
+                      .build())
+              .build();
+
+  private final UnaryCallable<CreateSessionRequest, Session> createSessionCallable;
+  private final UnaryCallable<BatchCreateSessionsRequest, BatchCreateSessionsResponse>
+      batchCreateSessionsCallable;
+  private final UnaryCallable<GetSessionRequest, Session> getSessionCallable;
+  private final UnaryCallable<ListSessionsRequest, ListSessionsResponse> listSessionsCallable;
+  private final UnaryCallable<ListSessionsRequest, ListSessionsPagedResponse>
+      listSessionsPagedCallable;
+  private final UnaryCallable<DeleteSessionRequest, Empty> deleteSessionCallable;
+  private final UnaryCallable<ExecuteSqlRequest, ResultSet> executeSqlCallable;
+  private final ServerStreamingCallable<ExecuteSqlRequest, PartialResultSet>
+      executeStreamingSqlCallable;
+  private final UnaryCallable<ExecuteBatchDmlRequest, ExecuteBatchDmlResponse>
+      executeBatchDmlCallable;
+  private final UnaryCallable<ReadRequest, ResultSet> readCallable;
+  private final ServerStreamingCallable<ReadRequest, PartialResultSet> streamingReadCallable;
+  private final UnaryCallable<BeginTransactionRequest, Transaction> beginTransactionCallable;
+  private final UnaryCallable<CommitRequest, CommitResponse> commitCallable;
+  private final UnaryCallable<RollbackRequest, Empty> rollbackCallable;
+  private final UnaryCallable<PartitionQueryRequest, PartitionResponse> partitionQueryCallable;
+  private final UnaryCallable<PartitionReadRequest, PartitionResponse> partitionReadCallable;
+
+  private final BackgroundResource backgroundResources;
+  private final HttpJsonStubCallableFactory callableFactory;
+
+  public static final HttpJsonSpannerStub create(SpannerStubSettings settings) throws IOException {
+    return new HttpJsonSpannerStub(settings, ClientContext.create(settings));
+  }
+
+  public static final HttpJsonSpannerStub create(ClientContext clientContext) throws IOException {
+    return new HttpJsonSpannerStub(SpannerStubSettings.newHttpJsonBuilder().build(), clientContext);
+  }
+
+  public static final HttpJsonSpannerStub create(
+      ClientContext clientContext, HttpJsonStubCallableFactory callableFactory) throws IOException {
+    return new HttpJsonSpannerStub(
+        SpannerStubSettings.newHttpJsonBuilder().build(), clientContext, callableFactory);
+  }
+
+  /**
+   * Constructs an instance of HttpJsonSpannerStub, using the given settings. This is protected so
+   * that it is easy to make a subclass, but otherwise, the static factory methods should be
+   * preferred.
+   */
+  protected HttpJsonSpannerStub(SpannerStubSettings settings, ClientContext clientContext)
+      throws IOException {
+    this(settings, clientContext, new HttpJsonSpannerCallableFactory());
+  }
+
+  /**
+   * Constructs an instance of HttpJsonSpannerStub, using the given settings. This is protected so
+   * that it is easy to make a subclass, but otherwise, the static factory methods should be
+   * preferred.
+   */
+  protected HttpJsonSpannerStub(
+      SpannerStubSettings settings,
+      ClientContext clientContext,
+      HttpJsonStubCallableFactory callableFactory)
+      throws IOException {
+    this.callableFactory = callableFactory;
+
+    HttpJsonCallSettings<CreateSessionRequest, Session> createSessionTransportSettings =
+        HttpJsonCallSettings.<CreateSessionRequest, Session>newBuilder()
+            .setMethodDescriptor(createSessionMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<BatchCreateSessionsRequest, BatchCreateSessionsResponse>
+        batchCreateSessionsTransportSettings =
+            HttpJsonCallSettings
+                .<BatchCreateSessionsRequest, BatchCreateSessionsResponse>newBuilder()
+                .setMethodDescriptor(batchCreateSessionsMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<GetSessionRequest, Session> getSessionTransportSettings =
+        HttpJsonCallSettings.<GetSessionRequest, Session>newBuilder()
+            .setMethodDescriptor(getSessionMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ListSessionsRequest, ListSessionsResponse> listSessionsTransportSettings =
+        HttpJsonCallSettings.<ListSessionsRequest, ListSessionsResponse>newBuilder()
+            .setMethodDescriptor(listSessionsMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<DeleteSessionRequest, Empty> deleteSessionTransportSettings =
+        HttpJsonCallSettings.<DeleteSessionRequest, Empty>newBuilder()
+            .setMethodDescriptor(deleteSessionMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ExecuteSqlRequest, ResultSet> executeSqlTransportSettings =
+        HttpJsonCallSettings.<ExecuteSqlRequest, ResultSet>newBuilder()
+            .setMethodDescriptor(executeSqlMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ExecuteSqlRequest, PartialResultSet> executeStreamingSqlTransportSettings =
+        HttpJsonCallSettings.<ExecuteSqlRequest, PartialResultSet>newBuilder()
+            .setMethodDescriptor(executeStreamingSqlMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ExecuteBatchDmlRequest, ExecuteBatchDmlResponse>
+        executeBatchDmlTransportSettings =
+            HttpJsonCallSettings.<ExecuteBatchDmlRequest, ExecuteBatchDmlResponse>newBuilder()
+                .setMethodDescriptor(executeBatchDmlMethodDescriptor)
+                .setTypeRegistry(typeRegistry)
+                .build();
+    HttpJsonCallSettings<ReadRequest, ResultSet> readTransportSettings =
+        HttpJsonCallSettings.<ReadRequest, ResultSet>newBuilder()
+            .setMethodDescriptor(readMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<ReadRequest, PartialResultSet> streamingReadTransportSettings =
+        HttpJsonCallSettings.<ReadRequest, PartialResultSet>newBuilder()
+            .setMethodDescriptor(streamingReadMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<BeginTransactionRequest, Transaction> beginTransactionTransportSettings =
+        HttpJsonCallSettings.<BeginTransactionRequest, Transaction>newBuilder()
+            .setMethodDescriptor(beginTransactionMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<CommitRequest, CommitResponse> commitTransportSettings =
+        HttpJsonCallSettings.<CommitRequest, CommitResponse>newBuilder()
+            .setMethodDescriptor(commitMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<RollbackRequest, Empty> rollbackTransportSettings =
+        HttpJsonCallSettings.<RollbackRequest, Empty>newBuilder()
+            .setMethodDescriptor(rollbackMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<PartitionQueryRequest, PartitionResponse> partitionQueryTransportSettings =
+        HttpJsonCallSettings.<PartitionQueryRequest, PartitionResponse>newBuilder()
+            .setMethodDescriptor(partitionQueryMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+    HttpJsonCallSettings<PartitionReadRequest, PartitionResponse> partitionReadTransportSettings =
+        HttpJsonCallSettings.<PartitionReadRequest, PartitionResponse>newBuilder()
+            .setMethodDescriptor(partitionReadMethodDescriptor)
+            .setTypeRegistry(typeRegistry)
+            .build();
+
+    this.createSessionCallable =
+        callableFactory.createUnaryCallable(
+            createSessionTransportSettings, settings.createSessionSettings(), clientContext);
+    this.batchCreateSessionsCallable =
+        callableFactory.createUnaryCallable(
+            batchCreateSessionsTransportSettings,
+            settings.batchCreateSessionsSettings(),
+            clientContext);
+    this.getSessionCallable =
+        callableFactory.createUnaryCallable(
+            getSessionTransportSettings, settings.getSessionSettings(), clientContext);
+    this.listSessionsCallable =
+        callableFactory.createUnaryCallable(
+            listSessionsTransportSettings, settings.listSessionsSettings(), clientContext);
+    this.listSessionsPagedCallable =
+        callableFactory.createPagedCallable(
+            listSessionsTransportSettings, settings.listSessionsSettings(), clientContext);
+    this.deleteSessionCallable =
+        callableFactory.createUnaryCallable(
+            deleteSessionTransportSettings, settings.deleteSessionSettings(), clientContext);
+    this.executeSqlCallable =
+        callableFactory.createUnaryCallable(
+            executeSqlTransportSettings, settings.executeSqlSettings(), clientContext);
+    this.executeStreamingSqlCallable =
+        callableFactory.createServerStreamingCallable(
+            executeStreamingSqlTransportSettings,
+            settings.executeStreamingSqlSettings(),
+            clientContext);
+    this.executeBatchDmlCallable =
+        callableFactory.createUnaryCallable(
+            executeBatchDmlTransportSettings, settings.executeBatchDmlSettings(), clientContext);
+    this.readCallable =
+        callableFactory.createUnaryCallable(
+            readTransportSettings, settings.readSettings(), clientContext);
+    this.streamingReadCallable =
+        callableFactory.createServerStreamingCallable(
+            streamingReadTransportSettings, settings.streamingReadSettings(), clientContext);
+    this.beginTransactionCallable =
+        callableFactory.createUnaryCallable(
+            beginTransactionTransportSettings, settings.beginTransactionSettings(), clientContext);
+    this.commitCallable =
+        callableFactory.createUnaryCallable(
+            commitTransportSettings, settings.commitSettings(), clientContext);
+    this.rollbackCallable =
+        callableFactory.createUnaryCallable(
+            rollbackTransportSettings, settings.rollbackSettings(), clientContext);
+    this.partitionQueryCallable =
+        callableFactory.createUnaryCallable(
+            partitionQueryTransportSettings, settings.partitionQuerySettings(), clientContext);
+    this.partitionReadCallable =
+        callableFactory.createUnaryCallable(
+            partitionReadTransportSettings, settings.partitionReadSettings(), clientContext);
+
+    this.backgroundResources =
+        new BackgroundResourceAggregation(clientContext.getBackgroundResources());
+  }
+
+  @InternalApi
+  public static List<ApiMethodDescriptor> getMethodDescriptors() {
+    List<ApiMethodDescriptor> methodDescriptors = new ArrayList<>();
+    methodDescriptors.add(createSessionMethodDescriptor);
+    methodDescriptors.add(batchCreateSessionsMethodDescriptor);
+    methodDescriptors.add(getSessionMethodDescriptor);
+    methodDescriptors.add(listSessionsMethodDescriptor);
+    methodDescriptors.add(deleteSessionMethodDescriptor);
+    methodDescriptors.add(executeSqlMethodDescriptor);
+    methodDescriptors.add(executeStreamingSqlMethodDescriptor);
+    methodDescriptors.add(executeBatchDmlMethodDescriptor);
+    methodDescriptors.add(readMethodDescriptor);
+    methodDescriptors.add(streamingReadMethodDescriptor);
+    methodDescriptors.add(beginTransactionMethodDescriptor);
+    methodDescriptors.add(commitMethodDescriptor);
+    methodDescriptors.add(rollbackMethodDescriptor);
+    methodDescriptors.add(partitionQueryMethodDescriptor);
+    methodDescriptors.add(partitionReadMethodDescriptor);
+    return methodDescriptors;
+  }
+
+  @Override
+  public UnaryCallable<CreateSessionRequest, Session> createSessionCallable() {
+    return createSessionCallable;
+  }
+
+  @Override
+  public UnaryCallable<BatchCreateSessionsRequest, BatchCreateSessionsResponse>
+      batchCreateSessionsCallable() {
+    return batchCreateSessionsCallable;
+  }
+
+  @Override
+  public UnaryCallable<GetSessionRequest, Session> getSessionCallable() {
+    return getSessionCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListSessionsRequest, ListSessionsResponse> listSessionsCallable() {
+    return listSessionsCallable;
+  }
+
+  @Override
+  public UnaryCallable<ListSessionsRequest, ListSessionsPagedResponse> listSessionsPagedCallable() {
+    return listSessionsPagedCallable;
+  }
+
+  @Override
+  public UnaryCallable<DeleteSessionRequest, Empty> deleteSessionCallable() {
+    return deleteSessionCallable;
+  }
+
+  @Override
+  public UnaryCallable<ExecuteSqlRequest, ResultSet> executeSqlCallable() {
+    return executeSqlCallable;
+  }
+
+  @Override
+  public ServerStreamingCallable<ExecuteSqlRequest, PartialResultSet>
+      executeStreamingSqlCallable() {
+    return executeStreamingSqlCallable;
+  }
+
+  @Override
+  public UnaryCallable<ExecuteBatchDmlRequest, ExecuteBatchDmlResponse> executeBatchDmlCallable() {
+    return executeBatchDmlCallable;
+  }
+
+  @Override
+  public UnaryCallable<ReadRequest, ResultSet> readCallable() {
+    return readCallable;
+  }
+
+  @Override
+  public ServerStreamingCallable<ReadRequest, PartialResultSet> streamingReadCallable() {
+    return streamingReadCallable;
+  }
+
+  @Override
+  public UnaryCallable<BeginTransactionRequest, Transaction> beginTransactionCallable() {
+    return beginTransactionCallable;
+  }
+
+  @Override
+  public UnaryCallable<CommitRequest, CommitResponse> commitCallable() {
+    return commitCallable;
+  }
+
+  @Override
+  public UnaryCallable<RollbackRequest, Empty> rollbackCallable() {
+    return rollbackCallable;
+  }
+
+  @Override
+  public UnaryCallable<PartitionQueryRequest, PartitionResponse> partitionQueryCallable() {
+    return partitionQueryCallable;
+  }
+
+  @Override
+  public UnaryCallable<PartitionReadRequest, PartitionResponse> partitionReadCallable() {
+    return partitionReadCallable;
+  }
+
+  @Override
+  public final void close() {
+    try {
+      backgroundResources.close();
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IllegalStateException("Failed to close resource", e);
+    }
+  }
+
+  @Override
+  public void shutdown() {
+    backgroundResources.shutdown();
+  }
+
+  @Override
+  public boolean isShutdown() {
+    return backgroundResources.isShutdown();
+  }
+
+  @Override
+  public boolean isTerminated() {
+    return backgroundResources.isTerminated();
+  }
+
+  @Override
+  public void shutdownNow() {
+    backgroundResources.shutdownNow();
+  }
+
+  @Override
+  public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException {
+    return backgroundResources.awaitTermination(duration, unit);
+  }
+}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java
index 5a9ddb75fde..477fdd2fa75 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java
@@ -27,6 +27,9 @@
 import com.google.api.gax.grpc.GaxGrpcProperties;
 import com.google.api.gax.grpc.GrpcTransportChannel;
 import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.HttpJsonTransportChannel;
+import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
 import com.google.api.gax.retrying.RetrySettings;
 import com.google.api.gax.rpc.ApiCallContext;
 import com.google.api.gax.rpc.ApiClientHeaderProvider;
@@ -274,6 +277,11 @@ public SpannerStub createStub() throws IOException {
         .equals(GrpcTransportChannel.getGrpcTransportName())) {
       return GrpcSpannerStub.create(this);
     }
+    if (getTransportChannelProvider()
+        .getTransportName()
+        .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) {
+      return HttpJsonSpannerStub.create(this);
+    }
     throw new UnsupportedOperationException(
         String.format(
             "Transport not supported: %s", getTransportChannelProvider().getTransportName()));
@@ -306,29 +314,54 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde
         .setUseJwtAccessWithScope(true);
   }
 
-  /** Returns a builder for the default ChannelProvider for this service. */
+  /** Returns a builder for the default gRPC ChannelProvider for this service. */
   public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder() {
     return InstantiatingGrpcChannelProvider.newBuilder()
         .setMaxInboundMessageSize(Integer.MAX_VALUE);
   }
 
+  /** Returns a builder for the default REST ChannelProvider for this service. */
+  @BetaApi
+  public static InstantiatingHttpJsonChannelProvider.Builder
+      defaultHttpJsonTransportProviderBuilder() {
+    return InstantiatingHttpJsonChannelProvider.newBuilder();
+  }
+
   public static TransportChannelProvider defaultTransportChannelProvider() {
     return defaultGrpcTransportProviderBuilder().build();
   }
 
   @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
-  public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
+  public static ApiClientHeaderProvider.Builder defaultGrpcApiClientHeaderProviderBuilder() {
     return ApiClientHeaderProvider.newBuilder()
         .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(SpannerStubSettings.class))
         .setTransportToken(
             GaxGrpcProperties.getGrpcTokenName(), GaxGrpcProperties.getGrpcVersion());
   }
 
-  /** Returns a new builder for this class. */
+  @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
+  public static ApiClientHeaderProvider.Builder defaultHttpJsonApiClientHeaderProviderBuilder() {
+    return ApiClientHeaderProvider.newBuilder()
+        .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(SpannerStubSettings.class))
+        .setTransportToken(
+            GaxHttpJsonProperties.getHttpJsonTokenName(),
+            GaxHttpJsonProperties.getHttpJsonVersion());
+  }
+
+  public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
+    return SpannerStubSettings.defaultGrpcApiClientHeaderProviderBuilder();
+  }
+
+  /** Returns a new gRPC builder for this class. */
   public static Builder newBuilder() {
     return Builder.createDefault();
   }
 
+  /** Returns a new REST builder for this class. */
+  public static Builder newHttpJsonBuilder() {
+    return Builder.createHttpJsonDefault();
+  }
+
   /** Returns a new builder for this class. */
   public static Builder newBuilder(ClientContext clientContext) {
     return new Builder(clientContext);
@@ -545,6 +578,19 @@ private static Builder createDefault() {
       return initDefaults(builder);
     }
 
+    private static Builder createHttpJsonDefault() {
+      Builder builder = new Builder(((ClientContext) null));
+
+      builder.setTransportChannelProvider(defaultHttpJsonTransportProviderBuilder().build());
+      builder.setCredentialsProvider(defaultCredentialsProviderBuilder().build());
+      builder.setInternalHeaderProvider(defaultHttpJsonApiClientHeaderProviderBuilder().build());
+      builder.setEndpoint(getDefaultEndpoint());
+      builder.setMtlsEndpoint(getDefaultMtlsEndpoint());
+      builder.setSwitchToMtlsEndpointAllowed(true);
+
+      return initDefaults(builder);
+    }
+
     private static Builder initDefaults(Builder builder) {
       builder
           .createSessionSettings()
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java
new file mode 100644
index 00000000000..724e2c5f4aa
--- /dev/null
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java
@@ -0,0 +1,2171 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.admin.database.v1;
+
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListBackupOperationsPagedResponse;
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListBackupsPagedResponse;
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabaseOperationsPagedResponse;
+import static com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.ListDatabasesPagedResponse;
+
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.testing.MockHttpService;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ApiExceptionFactory;
+import com.google.api.gax.rpc.InvalidArgumentException;
+import com.google.api.gax.rpc.StatusCode;
+import com.google.api.gax.rpc.testing.FakeStatusCode;
+import com.google.api.resourcenames.ResourceName;
+import com.google.cloud.spanner.admin.database.v1.stub.HttpJsonDatabaseAdminStub;
+import com.google.common.collect.Lists;
+import com.google.iam.v1.AuditConfig;
+import com.google.iam.v1.Binding;
+import com.google.iam.v1.Policy;
+import com.google.iam.v1.TestIamPermissionsResponse;
+import com.google.longrunning.Operation;
+import com.google.protobuf.Any;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Empty;
+import com.google.protobuf.FieldMask;
+import com.google.protobuf.Timestamp;
+import com.google.spanner.admin.database.v1.Backup;
+import com.google.spanner.admin.database.v1.BackupName;
+import com.google.spanner.admin.database.v1.Database;
+import com.google.spanner.admin.database.v1.DatabaseDialect;
+import com.google.spanner.admin.database.v1.DatabaseName;
+import com.google.spanner.admin.database.v1.EncryptionConfig;
+import com.google.spanner.admin.database.v1.EncryptionInfo;
+import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse;
+import com.google.spanner.admin.database.v1.InstanceName;
+import com.google.spanner.admin.database.v1.ListBackupOperationsResponse;
+import com.google.spanner.admin.database.v1.ListBackupsResponse;
+import com.google.spanner.admin.database.v1.ListDatabaseOperationsResponse;
+import com.google.spanner.admin.database.v1.ListDatabasesResponse;
+import com.google.spanner.admin.database.v1.RestoreInfo;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Generated;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+@Generated("by gapic-generator-java")
+public class DatabaseAdminClientHttpJsonTest {
+  private static MockHttpService mockService;
+  private static DatabaseAdminClient client;
+
+  @BeforeClass
+  public static void startStaticServer() throws IOException {
+    mockService =
+        new MockHttpService(
+            HttpJsonDatabaseAdminStub.getMethodDescriptors(),
+            DatabaseAdminSettings.getDefaultEndpoint());
+    DatabaseAdminSettings settings =
+        DatabaseAdminSettings.newHttpJsonBuilder()
+            .setTransportChannelProvider(
+                DatabaseAdminSettings.defaultHttpJsonTransportProviderBuilder()
+                    .setHttpTransport(mockService)
+                    .build())
+            .setCredentialsProvider(NoCredentialsProvider.create())
+            .build();
+    client = DatabaseAdminClient.create(settings);
+  }
+
+  @AfterClass
+  public static void stopServer() {
+    client.close();
+  }
+
+  @Before
+  public void setUp() {}
+
+  @After
+  public void tearDown() throws Exception {
+    mockService.reset();
+  }
+
+  @Test
+  public void listDatabasesTest() throws Exception {
+    Database responsesElement = Database.newBuilder().build();
+    ListDatabasesResponse expectedResponse =
+        ListDatabasesResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllDatabases(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    ListDatabasesPagedResponse pagedListResponse = client.listDatabases(parent);
+
+    List<Database> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getDatabasesList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listDatabasesExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.listDatabases(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listDatabasesTest2() throws Exception {
+    Database responsesElement = Database.newBuilder().build();
+    ListDatabasesResponse expectedResponse =
+        ListDatabasesResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllDatabases(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+
+    ListDatabasesPagedResponse pagedListResponse = client.listDatabases(parent);
+
+    List<Database> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getDatabasesList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listDatabasesExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      client.listDatabases(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void createDatabaseTest() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("createDatabaseTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    String createStatement = "createStatement744686547";
+
+    Database actualResponse = client.createDatabaseAsync(parent, createStatement).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createDatabaseExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      String createStatement = "createStatement744686547";
+      client.createDatabaseAsync(parent, createStatement).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void createDatabaseTest2() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("createDatabaseTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+    String createStatement = "createStatement744686547";
+
+    Database actualResponse = client.createDatabaseAsync(parent, createStatement).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createDatabaseExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      String createStatement = "createStatement744686547";
+      client.createDatabaseAsync(parent, createStatement).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void getDatabaseTest() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    DatabaseName name = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+
+    Database actualResponse = client.getDatabase(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getDatabaseExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName name = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      client.getDatabase(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getDatabaseTest2() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "projects/project-5262/instances/instance-5262/databases/database-5262";
+
+    Database actualResponse = client.getDatabase(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getDatabaseExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "projects/project-5262/instances/instance-5262/databases/database-5262";
+      client.getDatabase(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void updateDatabaseDdlTest() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("updateDatabaseDdlTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+    List<String> statements = new ArrayList<>();
+
+    client.updateDatabaseDdlAsync(database, statements).get();
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void updateDatabaseDdlExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      List<String> statements = new ArrayList<>();
+      client.updateDatabaseDdlAsync(database, statements).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void updateDatabaseDdlTest2() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("updateDatabaseDdlTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+    List<String> statements = new ArrayList<>();
+
+    client.updateDatabaseDdlAsync(database, statements).get();
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void updateDatabaseDdlExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+      List<String> statements = new ArrayList<>();
+      client.updateDatabaseDdlAsync(database, statements).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void dropDatabaseTest() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+
+    client.dropDatabase(database);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void dropDatabaseExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      client.dropDatabase(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void dropDatabaseTest2() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+
+    client.dropDatabase(database);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void dropDatabaseExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+      client.dropDatabase(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getDatabaseDdlTest() throws Exception {
+    GetDatabaseDdlResponse expectedResponse =
+        GetDatabaseDdlResponse.newBuilder().addAllStatements(new ArrayList<String>()).build();
+    mockService.addResponse(expectedResponse);
+
+    DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+
+    GetDatabaseDdlResponse actualResponse = client.getDatabaseDdl(database);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getDatabaseDdlExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      client.getDatabaseDdl(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getDatabaseDdlTest2() throws Exception {
+    GetDatabaseDdlResponse expectedResponse =
+        GetDatabaseDdlResponse.newBuilder().addAllStatements(new ArrayList<String>()).build();
+    mockService.addResponse(expectedResponse);
+
+    String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+
+    GetDatabaseDdlResponse actualResponse = client.getDatabaseDdl(database);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getDatabaseDdlExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+      client.getDatabaseDdl(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void setIamPolicyTest() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName resource = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+    Policy policy = Policy.newBuilder().build();
+
+    Policy actualResponse = client.setIamPolicy(resource, policy);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void setIamPolicyExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName resource = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      Policy policy = Policy.newBuilder().build();
+      client.setIamPolicy(resource, policy);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void setIamPolicyTest2() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String resource = "projects/project-1023/instances/instance-1023/databases/database-1023";
+    Policy policy = Policy.newBuilder().build();
+
+    Policy actualResponse = client.setIamPolicy(resource, policy);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void setIamPolicyExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String resource = "projects/project-1023/instances/instance-1023/databases/database-1023";
+      Policy policy = Policy.newBuilder().build();
+      client.setIamPolicy(resource, policy);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getIamPolicyTest() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName resource = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+
+    Policy actualResponse = client.getIamPolicy(resource);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getIamPolicyExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName resource = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      client.getIamPolicy(resource);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getIamPolicyTest2() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String resource = "projects/project-1023/instances/instance-1023/databases/database-1023";
+
+    Policy actualResponse = client.getIamPolicy(resource);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getIamPolicyExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String resource = "projects/project-1023/instances/instance-1023/databases/database-1023";
+      client.getIamPolicy(resource);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void testIamPermissionsTest() throws Exception {
+    TestIamPermissionsResponse expectedResponse =
+        TestIamPermissionsResponse.newBuilder().addAllPermissions(new ArrayList<String>()).build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName resource = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+    List<String> permissions = new ArrayList<>();
+
+    TestIamPermissionsResponse actualResponse = client.testIamPermissions(resource, permissions);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void testIamPermissionsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName resource = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      List<String> permissions = new ArrayList<>();
+      client.testIamPermissions(resource, permissions);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void testIamPermissionsTest2() throws Exception {
+    TestIamPermissionsResponse expectedResponse =
+        TestIamPermissionsResponse.newBuilder().addAllPermissions(new ArrayList<String>()).build();
+    mockService.addResponse(expectedResponse);
+
+    String resource = "projects/project-1023/instances/instance-1023/databases/database-1023";
+    List<String> permissions = new ArrayList<>();
+
+    TestIamPermissionsResponse actualResponse = client.testIamPermissions(resource, permissions);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void testIamPermissionsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String resource = "projects/project-1023/instances/instance-1023/databases/database-1023";
+      List<String> permissions = new ArrayList<>();
+      client.testIamPermissions(resource, permissions);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void createBackupTest() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("createBackupTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    Backup backup = Backup.newBuilder().build();
+    String backupId = "backupId2121930365";
+
+    Backup actualResponse = client.createBackupAsync(parent, backup, backupId).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createBackupExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      Backup backup = Backup.newBuilder().build();
+      String backupId = "backupId2121930365";
+      client.createBackupAsync(parent, backup, backupId).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void createBackupTest2() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("createBackupTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+    Backup backup = Backup.newBuilder().build();
+    String backupId = "backupId2121930365";
+
+    Backup actualResponse = client.createBackupAsync(parent, backup, backupId).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createBackupExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      Backup backup = Backup.newBuilder().build();
+      String backupId = "backupId2121930365";
+      client.createBackupAsync(parent, backup, backupId).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void copyBackupTest() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("copyBackupTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    String backupId = "backupId2121930365";
+    BackupName sourceBackup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+    Timestamp expireTime = Timestamp.newBuilder().build();
+
+    Backup actualResponse =
+        client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void copyBackupExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      String backupId = "backupId2121930365";
+      BackupName sourceBackup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      Timestamp expireTime = Timestamp.newBuilder().build();
+      client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void copyBackupTest2() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("copyBackupTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    String backupId = "backupId2121930365";
+    String sourceBackup = "sourceBackup823134653";
+    Timestamp expireTime = Timestamp.newBuilder().build();
+
+    Backup actualResponse =
+        client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void copyBackupExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      String backupId = "backupId2121930365";
+      String sourceBackup = "sourceBackup823134653";
+      Timestamp expireTime = Timestamp.newBuilder().build();
+      client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void copyBackupTest3() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("copyBackupTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+    String backupId = "backupId2121930365";
+    BackupName sourceBackup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+    Timestamp expireTime = Timestamp.newBuilder().build();
+
+    Backup actualResponse =
+        client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void copyBackupExceptionTest3() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      String backupId = "backupId2121930365";
+      BackupName sourceBackup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      Timestamp expireTime = Timestamp.newBuilder().build();
+      client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void copyBackupTest4() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("copyBackupTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+    String backupId = "backupId2121930365";
+    String sourceBackup = "sourceBackup823134653";
+    Timestamp expireTime = Timestamp.newBuilder().build();
+
+    Backup actualResponse =
+        client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void copyBackupExceptionTest4() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      String backupId = "backupId2121930365";
+      String sourceBackup = "sourceBackup823134653";
+      Timestamp expireTime = Timestamp.newBuilder().build();
+      client.copyBackupAsync(parent, backupId, sourceBackup, expireTime).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void getBackupTest() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    BackupName name = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+
+    Backup actualResponse = client.getBackup(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getBackupExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      BackupName name = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      client.getBackup(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getBackupTest2() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "projects/project-3271/instances/instance-3271/backups/backup-3271";
+
+    Backup actualResponse = client.getBackup(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getBackupExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "projects/project-3271/instances/instance-3271/backups/backup-3271";
+      client.getBackup(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void updateBackupTest() throws Exception {
+    Backup expectedResponse =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    Backup backup =
+        Backup.newBuilder()
+            .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setVersionTime(Timestamp.newBuilder().build())
+            .setExpireTime(Timestamp.newBuilder().build())
+            .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setSizeBytes(-1796325715)
+            .addAllReferencingDatabases(new ArrayList<String>())
+            .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .addAllReferencingBackups(new ArrayList<String>())
+            .setMaxExpireTime(Timestamp.newBuilder().build())
+            .build();
+    FieldMask updateMask = FieldMask.newBuilder().build();
+
+    Backup actualResponse = client.updateBackup(backup, updateMask);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void updateBackupExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      Backup backup =
+          Backup.newBuilder()
+              .setDatabase(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+              .setVersionTime(Timestamp.newBuilder().build())
+              .setExpireTime(Timestamp.newBuilder().build())
+              .setName(BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]").toString())
+              .setCreateTime(Timestamp.newBuilder().build())
+              .setSizeBytes(-1796325715)
+              .addAllReferencingDatabases(new ArrayList<String>())
+              .setEncryptionInfo(EncryptionInfo.newBuilder().build())
+              .setDatabaseDialect(DatabaseDialect.forNumber(0))
+              .addAllReferencingBackups(new ArrayList<String>())
+              .setMaxExpireTime(Timestamp.newBuilder().build())
+              .build();
+      FieldMask updateMask = FieldMask.newBuilder().build();
+      client.updateBackup(backup, updateMask);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void deleteBackupTest() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    BackupName name = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+
+    client.deleteBackup(name);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void deleteBackupExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      BackupName name = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      client.deleteBackup(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void deleteBackupTest2() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "projects/project-3271/instances/instance-3271/backups/backup-3271";
+
+    client.deleteBackup(name);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void deleteBackupExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "projects/project-3271/instances/instance-3271/backups/backup-3271";
+      client.deleteBackup(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listBackupsTest() throws Exception {
+    Backup responsesElement = Backup.newBuilder().build();
+    ListBackupsResponse expectedResponse =
+        ListBackupsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllBackups(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    ListBackupsPagedResponse pagedListResponse = client.listBackups(parent);
+
+    List<Backup> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getBackupsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listBackupsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.listBackups(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listBackupsTest2() throws Exception {
+    Backup responsesElement = Backup.newBuilder().build();
+    ListBackupsResponse expectedResponse =
+        ListBackupsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllBackups(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+
+    ListBackupsPagedResponse pagedListResponse = client.listBackups(parent);
+
+    List<Backup> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getBackupsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listBackupsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      client.listBackups(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void restoreDatabaseTest() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("restoreDatabaseTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    String databaseId = "databaseId1688905718";
+    BackupName backup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+
+    Database actualResponse = client.restoreDatabaseAsync(parent, databaseId, backup).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void restoreDatabaseExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      String databaseId = "databaseId1688905718";
+      BackupName backup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      client.restoreDatabaseAsync(parent, databaseId, backup).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void restoreDatabaseTest2() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("restoreDatabaseTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    String databaseId = "databaseId1688905718";
+    String backup = "backup-1396673086";
+
+    Database actualResponse = client.restoreDatabaseAsync(parent, databaseId, backup).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void restoreDatabaseExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      String databaseId = "databaseId1688905718";
+      String backup = "backup-1396673086";
+      client.restoreDatabaseAsync(parent, databaseId, backup).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void restoreDatabaseTest3() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("restoreDatabaseTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+    String databaseId = "databaseId1688905718";
+    BackupName backup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+
+    Database actualResponse = client.restoreDatabaseAsync(parent, databaseId, backup).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void restoreDatabaseExceptionTest3() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      String databaseId = "databaseId1688905718";
+      BackupName backup = BackupName.of("[PROJECT]", "[INSTANCE]", "[BACKUP]");
+      client.restoreDatabaseAsync(parent, databaseId, backup).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void restoreDatabaseTest4() throws Exception {
+    Database expectedResponse =
+        Database.newBuilder()
+            .setName(DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]").toString())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setRestoreInfo(RestoreInfo.newBuilder().build())
+            .setEncryptionConfig(EncryptionConfig.newBuilder().build())
+            .addAllEncryptionInfo(new ArrayList<EncryptionInfo>())
+            .setVersionRetentionPeriod("versionRetentionPeriod-629783929")
+            .setEarliestVersionTime(Timestamp.newBuilder().build())
+            .setDefaultLeader("defaultLeader759009962")
+            .setDatabaseDialect(DatabaseDialect.forNumber(0))
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("restoreDatabaseTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+    String databaseId = "databaseId1688905718";
+    String backup = "backup-1396673086";
+
+    Database actualResponse = client.restoreDatabaseAsync(parent, databaseId, backup).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void restoreDatabaseExceptionTest4() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      String databaseId = "databaseId1688905718";
+      String backup = "backup-1396673086";
+      client.restoreDatabaseAsync(parent, databaseId, backup).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void listDatabaseOperationsTest() throws Exception {
+    Operation responsesElement = Operation.newBuilder().build();
+    ListDatabaseOperationsResponse expectedResponse =
+        ListDatabaseOperationsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllOperations(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    ListDatabaseOperationsPagedResponse pagedListResponse = client.listDatabaseOperations(parent);
+
+    List<Operation> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getOperationsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listDatabaseOperationsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.listDatabaseOperations(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listDatabaseOperationsTest2() throws Exception {
+    Operation responsesElement = Operation.newBuilder().build();
+    ListDatabaseOperationsResponse expectedResponse =
+        ListDatabaseOperationsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllOperations(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+
+    ListDatabaseOperationsPagedResponse pagedListResponse = client.listDatabaseOperations(parent);
+
+    List<Operation> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getOperationsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listDatabaseOperationsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      client.listDatabaseOperations(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listBackupOperationsTest() throws Exception {
+    Operation responsesElement = Operation.newBuilder().build();
+    ListBackupOperationsResponse expectedResponse =
+        ListBackupOperationsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllOperations(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    ListBackupOperationsPagedResponse pagedListResponse = client.listBackupOperations(parent);
+
+    List<Operation> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getOperationsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listBackupOperationsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName parent = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.listBackupOperations(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listBackupOperationsTest2() throws Exception {
+    Operation responsesElement = Operation.newBuilder().build();
+    ListBackupOperationsResponse expectedResponse =
+        ListBackupOperationsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllOperations(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "projects/project-8887/instances/instance-8887";
+
+    ListBackupOperationsPagedResponse pagedListResponse = client.listBackupOperations(parent);
+
+    List<Operation> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getOperationsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listBackupOperationsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-8887/instances/instance-8887";
+      client.listBackupOperations(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+}
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientHttpJsonTest.java
new file mode 100644
index 00000000000..af9298a4b81
--- /dev/null
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientHttpJsonTest.java
@@ -0,0 +1,1061 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.admin.instance.v1;
+
+import static com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient.ListInstanceConfigsPagedResponse;
+import static com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient.ListInstancesPagedResponse;
+
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.testing.MockHttpService;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ApiExceptionFactory;
+import com.google.api.gax.rpc.InvalidArgumentException;
+import com.google.api.gax.rpc.StatusCode;
+import com.google.api.gax.rpc.testing.FakeStatusCode;
+import com.google.api.resourcenames.ResourceName;
+import com.google.cloud.spanner.admin.instance.v1.stub.HttpJsonInstanceAdminStub;
+import com.google.common.collect.Lists;
+import com.google.iam.v1.AuditConfig;
+import com.google.iam.v1.Binding;
+import com.google.iam.v1.Policy;
+import com.google.iam.v1.TestIamPermissionsResponse;
+import com.google.longrunning.Operation;
+import com.google.protobuf.Any;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Empty;
+import com.google.protobuf.FieldMask;
+import com.google.protobuf.Timestamp;
+import com.google.spanner.admin.instance.v1.Instance;
+import com.google.spanner.admin.instance.v1.InstanceConfig;
+import com.google.spanner.admin.instance.v1.InstanceConfigName;
+import com.google.spanner.admin.instance.v1.InstanceName;
+import com.google.spanner.admin.instance.v1.ListInstanceConfigsResponse;
+import com.google.spanner.admin.instance.v1.ListInstancesResponse;
+import com.google.spanner.admin.instance.v1.ProjectName;
+import com.google.spanner.admin.instance.v1.ReplicaInfo;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Generated;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+@Generated("by gapic-generator-java")
+public class InstanceAdminClientHttpJsonTest {
+  private static MockHttpService mockService;
+  private static InstanceAdminClient client;
+
+  @BeforeClass
+  public static void startStaticServer() throws IOException {
+    mockService =
+        new MockHttpService(
+            HttpJsonInstanceAdminStub.getMethodDescriptors(),
+            InstanceAdminSettings.getDefaultEndpoint());
+    InstanceAdminSettings settings =
+        InstanceAdminSettings.newHttpJsonBuilder()
+            .setTransportChannelProvider(
+                InstanceAdminSettings.defaultHttpJsonTransportProviderBuilder()
+                    .setHttpTransport(mockService)
+                    .build())
+            .setCredentialsProvider(NoCredentialsProvider.create())
+            .build();
+    client = InstanceAdminClient.create(settings);
+  }
+
+  @AfterClass
+  public static void stopServer() {
+    client.close();
+  }
+
+  @Before
+  public void setUp() {}
+
+  @After
+  public void tearDown() throws Exception {
+    mockService.reset();
+  }
+
+  @Test
+  public void listInstanceConfigsTest() throws Exception {
+    InstanceConfig responsesElement = InstanceConfig.newBuilder().build();
+    ListInstanceConfigsResponse expectedResponse =
+        ListInstanceConfigsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllInstanceConfigs(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ProjectName parent = ProjectName.of("[PROJECT]");
+
+    ListInstanceConfigsPagedResponse pagedListResponse = client.listInstanceConfigs(parent);
+
+    List<InstanceConfig> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getInstanceConfigsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listInstanceConfigsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ProjectName parent = ProjectName.of("[PROJECT]");
+      client.listInstanceConfigs(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listInstanceConfigsTest2() throws Exception {
+    InstanceConfig responsesElement = InstanceConfig.newBuilder().build();
+    ListInstanceConfigsResponse expectedResponse =
+        ListInstanceConfigsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllInstanceConfigs(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "projects/project-2353";
+
+    ListInstanceConfigsPagedResponse pagedListResponse = client.listInstanceConfigs(parent);
+
+    List<InstanceConfig> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getInstanceConfigsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listInstanceConfigsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-2353";
+      client.listInstanceConfigs(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getInstanceConfigTest() throws Exception {
+    InstanceConfig expectedResponse =
+        InstanceConfig.newBuilder()
+            .setName(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .addAllReplicas(new ArrayList<ReplicaInfo>())
+            .addAllLeaderOptions(new ArrayList<String>())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceConfigName name = InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]");
+
+    InstanceConfig actualResponse = client.getInstanceConfig(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getInstanceConfigExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceConfigName name = InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]");
+      client.getInstanceConfig(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getInstanceConfigTest2() throws Exception {
+    InstanceConfig expectedResponse =
+        InstanceConfig.newBuilder()
+            .setName(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .addAllReplicas(new ArrayList<ReplicaInfo>())
+            .addAllLeaderOptions(new ArrayList<String>())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "projects/project-3640/instanceConfigs/instanceConfig-3640";
+
+    InstanceConfig actualResponse = client.getInstanceConfig(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getInstanceConfigExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "projects/project-3640/instanceConfigs/instanceConfig-3640";
+      client.getInstanceConfig(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listInstancesTest() throws Exception {
+    Instance responsesElement = Instance.newBuilder().build();
+    ListInstancesResponse expectedResponse =
+        ListInstancesResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllInstances(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ProjectName parent = ProjectName.of("[PROJECT]");
+
+    ListInstancesPagedResponse pagedListResponse = client.listInstances(parent);
+
+    List<Instance> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getInstancesList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listInstancesExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ProjectName parent = ProjectName.of("[PROJECT]");
+      client.listInstances(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listInstancesTest2() throws Exception {
+    Instance responsesElement = Instance.newBuilder().build();
+    ListInstancesResponse expectedResponse =
+        ListInstancesResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllInstances(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String parent = "projects/project-2353";
+
+    ListInstancesPagedResponse pagedListResponse = client.listInstances(parent);
+
+    List<Instance> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getInstancesList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listInstancesExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-2353";
+      client.listInstances(parent);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getInstanceTest() throws Exception {
+    Instance expectedResponse =
+        Instance.newBuilder()
+            .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+            .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .setNodeCount(1539922066)
+            .setProcessingUnits(-329117885)
+            .putAllLabels(new HashMap<String, String>())
+            .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceName name = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    Instance actualResponse = client.getInstance(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getInstanceExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName name = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.getInstance(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getInstanceTest2() throws Exception {
+    Instance expectedResponse =
+        Instance.newBuilder()
+            .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+            .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .setNodeCount(1539922066)
+            .setProcessingUnits(-329117885)
+            .putAllLabels(new HashMap<String, String>())
+            .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "projects/project-3514/instances/instance-3514";
+
+    Instance actualResponse = client.getInstance(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getInstanceExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "projects/project-3514/instances/instance-3514";
+      client.getInstance(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void createInstanceTest() throws Exception {
+    Instance expectedResponse =
+        Instance.newBuilder()
+            .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+            .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .setNodeCount(1539922066)
+            .setProcessingUnits(-329117885)
+            .putAllLabels(new HashMap<String, String>())
+            .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("createInstanceTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    ProjectName parent = ProjectName.of("[PROJECT]");
+    String instanceId = "instanceId902024336";
+    Instance instance = Instance.newBuilder().build();
+
+    Instance actualResponse = client.createInstanceAsync(parent, instanceId, instance).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createInstanceExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ProjectName parent = ProjectName.of("[PROJECT]");
+      String instanceId = "instanceId902024336";
+      Instance instance = Instance.newBuilder().build();
+      client.createInstanceAsync(parent, instanceId, instance).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void createInstanceTest2() throws Exception {
+    Instance expectedResponse =
+        Instance.newBuilder()
+            .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+            .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .setNodeCount(1539922066)
+            .setProcessingUnits(-329117885)
+            .putAllLabels(new HashMap<String, String>())
+            .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("createInstanceTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    String parent = "projects/project-2353";
+    String instanceId = "instanceId902024336";
+    Instance instance = Instance.newBuilder().build();
+
+    Instance actualResponse = client.createInstanceAsync(parent, instanceId, instance).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createInstanceExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String parent = "projects/project-2353";
+      String instanceId = "instanceId902024336";
+      Instance instance = Instance.newBuilder().build();
+      client.createInstanceAsync(parent, instanceId, instance).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void updateInstanceTest() throws Exception {
+    Instance expectedResponse =
+        Instance.newBuilder()
+            .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+            .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .setNodeCount(1539922066)
+            .setProcessingUnits(-329117885)
+            .putAllLabels(new HashMap<String, String>())
+            .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
+            .build();
+    Operation resultOperation =
+        Operation.newBuilder()
+            .setName("updateInstanceTest")
+            .setDone(true)
+            .setResponse(Any.pack(expectedResponse))
+            .build();
+    mockService.addResponse(resultOperation);
+
+    Instance instance =
+        Instance.newBuilder()
+            .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+            .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+            .setDisplayName("displayName1714148973")
+            .setNodeCount(1539922066)
+            .setProcessingUnits(-329117885)
+            .putAllLabels(new HashMap<String, String>())
+            .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
+            .build();
+    FieldMask fieldMask = FieldMask.newBuilder().build();
+
+    Instance actualResponse = client.updateInstanceAsync(instance, fieldMask).get();
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void updateInstanceExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      Instance instance =
+          Instance.newBuilder()
+              .setName(InstanceName.of("[PROJECT]", "[INSTANCE]").toString())
+              .setConfig(InstanceConfigName.of("[PROJECT]", "[INSTANCE_CONFIG]").toString())
+              .setDisplayName("displayName1714148973")
+              .setNodeCount(1539922066)
+              .setProcessingUnits(-329117885)
+              .putAllLabels(new HashMap<String, String>())
+              .addAllEndpointUris(new ArrayList<String>())
+              .setCreateTime(Timestamp.newBuilder().build())
+              .setUpdateTime(Timestamp.newBuilder().build())
+              .build();
+      FieldMask fieldMask = FieldMask.newBuilder().build();
+      client.updateInstanceAsync(instance, fieldMask).get();
+      Assert.fail("No exception raised");
+    } catch (ExecutionException e) {
+    }
+  }
+
+  @Test
+  public void deleteInstanceTest() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    InstanceName name = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    client.deleteInstance(name);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void deleteInstanceExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      InstanceName name = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.deleteInstance(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void deleteInstanceTest2() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    String name = "projects/project-3514/instances/instance-3514";
+
+    client.deleteInstance(name);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void deleteInstanceExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name = "projects/project-3514/instances/instance-3514";
+      client.deleteInstance(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void setIamPolicyTest() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    Policy policy = Policy.newBuilder().build();
+
+    Policy actualResponse = client.setIamPolicy(resource, policy);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void setIamPolicyExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      Policy policy = Policy.newBuilder().build();
+      client.setIamPolicy(resource, policy);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void setIamPolicyTest2() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String resource = "projects/project-3043/instances/instance-3043";
+    Policy policy = Policy.newBuilder().build();
+
+    Policy actualResponse = client.setIamPolicy(resource, policy);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void setIamPolicyExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String resource = "projects/project-3043/instances/instance-3043";
+      Policy policy = Policy.newBuilder().build();
+      client.setIamPolicy(resource, policy);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getIamPolicyTest() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
+
+    Policy actualResponse = client.getIamPolicy(resource);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getIamPolicyExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      client.getIamPolicy(resource);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getIamPolicyTest2() throws Exception {
+    Policy expectedResponse =
+        Policy.newBuilder()
+            .setVersion(351608024)
+            .addAllBindings(new ArrayList<Binding>())
+            .addAllAuditConfigs(new ArrayList<AuditConfig>())
+            .setEtag(ByteString.EMPTY)
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String resource = "projects/project-3043/instances/instance-3043";
+
+    Policy actualResponse = client.getIamPolicy(resource);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getIamPolicyExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String resource = "projects/project-3043/instances/instance-3043";
+      client.getIamPolicy(resource);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void testIamPermissionsTest() throws Exception {
+    TestIamPermissionsResponse expectedResponse =
+        TestIamPermissionsResponse.newBuilder().addAllPermissions(new ArrayList<String>()).build();
+    mockService.addResponse(expectedResponse);
+
+    ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
+    List<String> permissions = new ArrayList<>();
+
+    TestIamPermissionsResponse actualResponse = client.testIamPermissions(resource, permissions);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void testIamPermissionsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
+      List<String> permissions = new ArrayList<>();
+      client.testIamPermissions(resource, permissions);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void testIamPermissionsTest2() throws Exception {
+    TestIamPermissionsResponse expectedResponse =
+        TestIamPermissionsResponse.newBuilder().addAllPermissions(new ArrayList<String>()).build();
+    mockService.addResponse(expectedResponse);
+
+    String resource = "projects/project-3043/instances/instance-3043";
+    List<String> permissions = new ArrayList<>();
+
+    TestIamPermissionsResponse actualResponse = client.testIamPermissions(resource, permissions);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void testIamPermissionsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String resource = "projects/project-3043/instances/instance-3043";
+      List<String> permissions = new ArrayList<>();
+      client.testIamPermissions(resource, permissions);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+}
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientTest.java
index 323ebb40372..75649dd676c 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientTest.java
@@ -42,6 +42,7 @@
 import com.google.protobuf.ByteString;
 import com.google.protobuf.Empty;
 import com.google.protobuf.FieldMask;
+import com.google.protobuf.Timestamp;
 import com.google.spanner.admin.instance.v1.CreateInstanceRequest;
 import com.google.spanner.admin.instance.v1.DeleteInstanceRequest;
 import com.google.spanner.admin.instance.v1.GetInstanceConfigRequest;
@@ -380,6 +381,8 @@ public void getInstanceTest() throws Exception {
             .setProcessingUnits(-329117885)
             .putAllLabels(new HashMap<String, String>())
             .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
             .build();
     mockInstanceAdmin.addResponse(expectedResponse);
 
@@ -424,6 +427,8 @@ public void getInstanceTest2() throws Exception {
             .setProcessingUnits(-329117885)
             .putAllLabels(new HashMap<String, String>())
             .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
             .build();
     mockInstanceAdmin.addResponse(expectedResponse);
 
@@ -468,6 +473,8 @@ public void createInstanceTest() throws Exception {
             .setProcessingUnits(-329117885)
             .putAllLabels(new HashMap<String, String>())
             .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
             .build();
     Operation resultOperation =
         Operation.newBuilder()
@@ -526,6 +533,8 @@ public void createInstanceTest2() throws Exception {
             .setProcessingUnits(-329117885)
             .putAllLabels(new HashMap<String, String>())
             .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
             .build();
     Operation resultOperation =
         Operation.newBuilder()
@@ -584,6 +593,8 @@ public void updateInstanceTest() throws Exception {
             .setProcessingUnits(-329117885)
             .putAllLabels(new HashMap<String, String>())
             .addAllEndpointUris(new ArrayList<String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setUpdateTime(Timestamp.newBuilder().build())
             .build();
     Operation resultOperation =
         Operation.newBuilder()
@@ -707,7 +718,7 @@ public void setIamPolicyTest() throws Exception {
             .build();
     mockInstanceAdmin.addResponse(expectedResponse);
 
-    ResourceName resource = ProjectName.of("[PROJECT]");
+    ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
     Policy policy = Policy.newBuilder().build();
 
     Policy actualResponse = client.setIamPolicy(resource, policy);
@@ -731,7 +742,7 @@ public void setIamPolicyExceptionTest() throws Exception {
     mockInstanceAdmin.addException(exception);
 
     try {
-      ResourceName resource = ProjectName.of("[PROJECT]");
+      ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
       Policy policy = Policy.newBuilder().build();
       client.setIamPolicy(resource, policy);
       Assert.fail("No exception raised");
@@ -795,7 +806,7 @@ public void getIamPolicyTest() throws Exception {
             .build();
     mockInstanceAdmin.addResponse(expectedResponse);
 
-    ResourceName resource = ProjectName.of("[PROJECT]");
+    ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
 
     Policy actualResponse = client.getIamPolicy(resource);
     Assert.assertEquals(expectedResponse, actualResponse);
@@ -817,7 +828,7 @@ public void getIamPolicyExceptionTest() throws Exception {
     mockInstanceAdmin.addException(exception);
 
     try {
-      ResourceName resource = ProjectName.of("[PROJECT]");
+      ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
       client.getIamPolicy(resource);
       Assert.fail("No exception raised");
     } catch (InvalidArgumentException e) {
@@ -872,7 +883,7 @@ public void testIamPermissionsTest() throws Exception {
         TestIamPermissionsResponse.newBuilder().addAllPermissions(new ArrayList<String>()).build();
     mockInstanceAdmin.addResponse(expectedResponse);
 
-    ResourceName resource = ProjectName.of("[PROJECT]");
+    ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
     List<String> permissions = new ArrayList<>();
 
     TestIamPermissionsResponse actualResponse = client.testIamPermissions(resource, permissions);
@@ -896,7 +907,7 @@ public void testIamPermissionsExceptionTest() throws Exception {
     mockInstanceAdmin.addException(exception);
 
     try {
-      ResourceName resource = ProjectName.of("[PROJECT]");
+      ResourceName resource = InstanceName.of("[PROJECT]", "[INSTANCE]");
       List<String> permissions = new ArrayList<>();
       client.testIamPermissions(resource, permissions);
       Assert.fail("No exception raised");
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java
new file mode 100644
index 00000000000..b17546d293c
--- /dev/null
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java
@@ -0,0 +1,1314 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.spanner.v1;
+
+import static com.google.cloud.spanner.v1.SpannerClient.ListSessionsPagedResponse;
+
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.httpjson.GaxHttpJsonProperties;
+import com.google.api.gax.httpjson.testing.MockHttpService;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ApiExceptionFactory;
+import com.google.api.gax.rpc.InvalidArgumentException;
+import com.google.api.gax.rpc.StatusCode;
+import com.google.api.gax.rpc.testing.FakeStatusCode;
+import com.google.cloud.spanner.v1.stub.HttpJsonSpannerStub;
+import com.google.common.collect.Lists;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Empty;
+import com.google.protobuf.ListValue;
+import com.google.protobuf.Struct;
+import com.google.protobuf.Timestamp;
+import com.google.rpc.Status;
+import com.google.spanner.v1.BatchCreateSessionsResponse;
+import com.google.spanner.v1.CommitResponse;
+import com.google.spanner.v1.DatabaseName;
+import com.google.spanner.v1.ExecuteBatchDmlRequest;
+import com.google.spanner.v1.ExecuteBatchDmlResponse;
+import com.google.spanner.v1.ExecuteSqlRequest;
+import com.google.spanner.v1.KeySet;
+import com.google.spanner.v1.ListSessionsResponse;
+import com.google.spanner.v1.Mutation;
+import com.google.spanner.v1.Partition;
+import com.google.spanner.v1.PartitionOptions;
+import com.google.spanner.v1.PartitionQueryRequest;
+import com.google.spanner.v1.PartitionReadRequest;
+import com.google.spanner.v1.PartitionResponse;
+import com.google.spanner.v1.ReadRequest;
+import com.google.spanner.v1.RequestOptions;
+import com.google.spanner.v1.ResultSet;
+import com.google.spanner.v1.ResultSetMetadata;
+import com.google.spanner.v1.ResultSetStats;
+import com.google.spanner.v1.Session;
+import com.google.spanner.v1.SessionName;
+import com.google.spanner.v1.Transaction;
+import com.google.spanner.v1.TransactionOptions;
+import com.google.spanner.v1.TransactionSelector;
+import com.google.spanner.v1.Type;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import javax.annotation.Generated;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+@Generated("by gapic-generator-java")
+public class SpannerClientHttpJsonTest {
+  private static MockHttpService mockService;
+  private static SpannerClient client;
+
+  @BeforeClass
+  public static void startStaticServer() throws IOException {
+    mockService =
+        new MockHttpService(
+            HttpJsonSpannerStub.getMethodDescriptors(), SpannerSettings.getDefaultEndpoint());
+    SpannerSettings settings =
+        SpannerSettings.newHttpJsonBuilder()
+            .setTransportChannelProvider(
+                SpannerSettings.defaultHttpJsonTransportProviderBuilder()
+                    .setHttpTransport(mockService)
+                    .build())
+            .setCredentialsProvider(NoCredentialsProvider.create())
+            .build();
+    client = SpannerClient.create(settings);
+  }
+
+  @AfterClass
+  public static void stopServer() {
+    client.close();
+  }
+
+  @Before
+  public void setUp() {}
+
+  @After
+  public void tearDown() throws Exception {
+    mockService.reset();
+  }
+
+  @Test
+  public void createSessionTest() throws Exception {
+    Session expectedResponse =
+        Session.newBuilder()
+            .setName(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .putAllLabels(new HashMap<String, String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+
+    Session actualResponse = client.createSession(database);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createSessionExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      client.createSession(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void createSessionTest2() throws Exception {
+    Session expectedResponse =
+        Session.newBuilder()
+            .setName(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .putAllLabels(new HashMap<String, String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+
+    Session actualResponse = client.createSession(database);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void createSessionExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+      client.createSession(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void batchCreateSessionsTest() throws Exception {
+    BatchCreateSessionsResponse expectedResponse =
+        BatchCreateSessionsResponse.newBuilder().addAllSession(new ArrayList<Session>()).build();
+    mockService.addResponse(expectedResponse);
+
+    DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+    int sessionCount = 185691686;
+
+    BatchCreateSessionsResponse actualResponse = client.batchCreateSessions(database, sessionCount);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void batchCreateSessionsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      int sessionCount = 185691686;
+      client.batchCreateSessions(database, sessionCount);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void batchCreateSessionsTest2() throws Exception {
+    BatchCreateSessionsResponse expectedResponse =
+        BatchCreateSessionsResponse.newBuilder().addAllSession(new ArrayList<Session>()).build();
+    mockService.addResponse(expectedResponse);
+
+    String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+    int sessionCount = 185691686;
+
+    BatchCreateSessionsResponse actualResponse = client.batchCreateSessions(database, sessionCount);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void batchCreateSessionsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+      int sessionCount = 185691686;
+      client.batchCreateSessions(database, sessionCount);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getSessionTest() throws Exception {
+    Session expectedResponse =
+        Session.newBuilder()
+            .setName(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .putAllLabels(new HashMap<String, String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    SessionName name = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+
+    Session actualResponse = client.getSession(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getSessionExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      SessionName name = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+      client.getSession(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void getSessionTest2() throws Exception {
+    Session expectedResponse =
+        Session.newBuilder()
+            .setName(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .putAllLabels(new HashMap<String, String>())
+            .setCreateTime(Timestamp.newBuilder().build())
+            .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String name =
+        "projects/project-199/instances/instance-199/databases/database-199/sessions/session-199";
+
+    Session actualResponse = client.getSession(name);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void getSessionExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name =
+          "projects/project-199/instances/instance-199/databases/database-199/sessions/session-199";
+      client.getSession(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listSessionsTest() throws Exception {
+    Session responsesElement = Session.newBuilder().build();
+    ListSessionsResponse expectedResponse =
+        ListSessionsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllSessions(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+
+    ListSessionsPagedResponse pagedListResponse = client.listSessions(database);
+
+    List<Session> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getSessionsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listSessionsExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      DatabaseName database = DatabaseName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]");
+      client.listSessions(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void listSessionsTest2() throws Exception {
+    Session responsesElement = Session.newBuilder().build();
+    ListSessionsResponse expectedResponse =
+        ListSessionsResponse.newBuilder()
+            .setNextPageToken("")
+            .addAllSessions(Arrays.asList(responsesElement))
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+
+    ListSessionsPagedResponse pagedListResponse = client.listSessions(database);
+
+    List<Session> resources = Lists.newArrayList(pagedListResponse.iterateAll());
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(expectedResponse.getSessionsList().get(0), resources.get(0));
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void listSessionsExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String database = "projects/project-3102/instances/instance-3102/databases/database-3102";
+      client.listSessions(database);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void deleteSessionTest() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    SessionName name = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+
+    client.deleteSession(name);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void deleteSessionExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      SessionName name = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+      client.deleteSession(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void deleteSessionTest2() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    String name =
+        "projects/project-199/instances/instance-199/databases/database-199/sessions/session-199";
+
+    client.deleteSession(name);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void deleteSessionExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String name =
+          "projects/project-199/instances/instance-199/databases/database-199/sessions/session-199";
+      client.deleteSession(name);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void executeSqlTest() throws Exception {
+    ResultSet expectedResponse =
+        ResultSet.newBuilder()
+            .setMetadata(ResultSetMetadata.newBuilder().build())
+            .addAllRows(new ArrayList<ListValue>())
+            .setStats(ResultSetStats.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ExecuteSqlRequest request =
+        ExecuteSqlRequest.newBuilder()
+            .setSession(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .setTransaction(TransactionSelector.newBuilder().build())
+            .setSql("sql114126")
+            .setParams(Struct.newBuilder().build())
+            .putAllParamTypes(new HashMap<String, Type>())
+            .setResumeToken(ByteString.EMPTY)
+            .setPartitionToken(ByteString.EMPTY)
+            .setSeqno(109325920)
+            .setQueryOptions(ExecuteSqlRequest.QueryOptions.newBuilder().build())
+            .setRequestOptions(RequestOptions.newBuilder().build())
+            .build();
+
+    ResultSet actualResponse = client.executeSql(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void executeSqlExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ExecuteSqlRequest request =
+          ExecuteSqlRequest.newBuilder()
+              .setSession(
+                  SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+              .setTransaction(TransactionSelector.newBuilder().build())
+              .setSql("sql114126")
+              .setParams(Struct.newBuilder().build())
+              .putAllParamTypes(new HashMap<String, Type>())
+              .setResumeToken(ByteString.EMPTY)
+              .setPartitionToken(ByteString.EMPTY)
+              .setSeqno(109325920)
+              .setQueryOptions(ExecuteSqlRequest.QueryOptions.newBuilder().build())
+              .setRequestOptions(RequestOptions.newBuilder().build())
+              .build();
+      client.executeSql(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void executeStreamingSqlTest() throws Exception {}
+
+  @Test
+  public void executeStreamingSqlExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+  }
+
+  @Test
+  public void executeBatchDmlTest() throws Exception {
+    ExecuteBatchDmlResponse expectedResponse =
+        ExecuteBatchDmlResponse.newBuilder()
+            .addAllResultSets(new ArrayList<ResultSet>())
+            .setStatus(Status.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ExecuteBatchDmlRequest request =
+        ExecuteBatchDmlRequest.newBuilder()
+            .setSession(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .setTransaction(TransactionSelector.newBuilder().build())
+            .addAllStatements(new ArrayList<ExecuteBatchDmlRequest.Statement>())
+            .setSeqno(109325920)
+            .setRequestOptions(RequestOptions.newBuilder().build())
+            .build();
+
+    ExecuteBatchDmlResponse actualResponse = client.executeBatchDml(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void executeBatchDmlExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ExecuteBatchDmlRequest request =
+          ExecuteBatchDmlRequest.newBuilder()
+              .setSession(
+                  SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+              .setTransaction(TransactionSelector.newBuilder().build())
+              .addAllStatements(new ArrayList<ExecuteBatchDmlRequest.Statement>())
+              .setSeqno(109325920)
+              .setRequestOptions(RequestOptions.newBuilder().build())
+              .build();
+      client.executeBatchDml(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void readTest() throws Exception {
+    ResultSet expectedResponse =
+        ResultSet.newBuilder()
+            .setMetadata(ResultSetMetadata.newBuilder().build())
+            .addAllRows(new ArrayList<ListValue>())
+            .setStats(ResultSetStats.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    ReadRequest request =
+        ReadRequest.newBuilder()
+            .setSession(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .setTransaction(TransactionSelector.newBuilder().build())
+            .setTable("table110115790")
+            .setIndex("index100346066")
+            .addAllColumns(new ArrayList<String>())
+            .setKeySet(KeySet.newBuilder().build())
+            .setLimit(102976443)
+            .setResumeToken(ByteString.EMPTY)
+            .setPartitionToken(ByteString.EMPTY)
+            .setRequestOptions(RequestOptions.newBuilder().build())
+            .build();
+
+    ResultSet actualResponse = client.read(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void readExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      ReadRequest request =
+          ReadRequest.newBuilder()
+              .setSession(
+                  SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+              .setTransaction(TransactionSelector.newBuilder().build())
+              .setTable("table110115790")
+              .setIndex("index100346066")
+              .addAllColumns(new ArrayList<String>())
+              .setKeySet(KeySet.newBuilder().build())
+              .setLimit(102976443)
+              .setResumeToken(ByteString.EMPTY)
+              .setPartitionToken(ByteString.EMPTY)
+              .setRequestOptions(RequestOptions.newBuilder().build())
+              .build();
+      client.read(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void streamingReadTest() throws Exception {}
+
+  @Test
+  public void streamingReadExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+  }
+
+  @Test
+  public void beginTransactionTest() throws Exception {
+    Transaction expectedResponse =
+        Transaction.newBuilder()
+            .setId(ByteString.EMPTY)
+            .setReadTimestamp(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+    TransactionOptions options = TransactionOptions.newBuilder().build();
+
+    Transaction actualResponse = client.beginTransaction(session, options);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void beginTransactionExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+      TransactionOptions options = TransactionOptions.newBuilder().build();
+      client.beginTransaction(session, options);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void beginTransactionTest2() throws Exception {
+    Transaction expectedResponse =
+        Transaction.newBuilder()
+            .setId(ByteString.EMPTY)
+            .setReadTimestamp(Timestamp.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String session =
+        "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+    TransactionOptions options = TransactionOptions.newBuilder().build();
+
+    Transaction actualResponse = client.beginTransaction(session, options);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void beginTransactionExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String session =
+          "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+      TransactionOptions options = TransactionOptions.newBuilder().build();
+      client.beginTransaction(session, options);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void commitTest() throws Exception {
+    CommitResponse expectedResponse =
+        CommitResponse.newBuilder()
+            .setCommitTimestamp(Timestamp.newBuilder().build())
+            .setCommitStats(CommitResponse.CommitStats.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+    ByteString transactionId = ByteString.EMPTY;
+    List<Mutation> mutations = new ArrayList<>();
+
+    CommitResponse actualResponse = client.commit(session, transactionId, mutations);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void commitExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+      ByteString transactionId = ByteString.EMPTY;
+      List<Mutation> mutations = new ArrayList<>();
+      client.commit(session, transactionId, mutations);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void commitTest2() throws Exception {
+    CommitResponse expectedResponse =
+        CommitResponse.newBuilder()
+            .setCommitTimestamp(Timestamp.newBuilder().build())
+            .setCommitStats(CommitResponse.CommitStats.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+    TransactionOptions singleUseTransaction = TransactionOptions.newBuilder().build();
+    List<Mutation> mutations = new ArrayList<>();
+
+    CommitResponse actualResponse = client.commit(session, singleUseTransaction, mutations);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void commitExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+      TransactionOptions singleUseTransaction = TransactionOptions.newBuilder().build();
+      List<Mutation> mutations = new ArrayList<>();
+      client.commit(session, singleUseTransaction, mutations);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void commitTest3() throws Exception {
+    CommitResponse expectedResponse =
+        CommitResponse.newBuilder()
+            .setCommitTimestamp(Timestamp.newBuilder().build())
+            .setCommitStats(CommitResponse.CommitStats.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String session =
+        "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+    ByteString transactionId = ByteString.EMPTY;
+    List<Mutation> mutations = new ArrayList<>();
+
+    CommitResponse actualResponse = client.commit(session, transactionId, mutations);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void commitExceptionTest3() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String session =
+          "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+      ByteString transactionId = ByteString.EMPTY;
+      List<Mutation> mutations = new ArrayList<>();
+      client.commit(session, transactionId, mutations);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void commitTest4() throws Exception {
+    CommitResponse expectedResponse =
+        CommitResponse.newBuilder()
+            .setCommitTimestamp(Timestamp.newBuilder().build())
+            .setCommitStats(CommitResponse.CommitStats.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    String session =
+        "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+    TransactionOptions singleUseTransaction = TransactionOptions.newBuilder().build();
+    List<Mutation> mutations = new ArrayList<>();
+
+    CommitResponse actualResponse = client.commit(session, singleUseTransaction, mutations);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void commitExceptionTest4() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String session =
+          "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+      TransactionOptions singleUseTransaction = TransactionOptions.newBuilder().build();
+      List<Mutation> mutations = new ArrayList<>();
+      client.commit(session, singleUseTransaction, mutations);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void rollbackTest() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+    ByteString transactionId = ByteString.EMPTY;
+
+    client.rollback(session, transactionId);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void rollbackExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      SessionName session = SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]");
+      ByteString transactionId = ByteString.EMPTY;
+      client.rollback(session, transactionId);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void rollbackTest2() throws Exception {
+    Empty expectedResponse = Empty.newBuilder().build();
+    mockService.addResponse(expectedResponse);
+
+    String session =
+        "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+    ByteString transactionId = ByteString.EMPTY;
+
+    client.rollback(session, transactionId);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void rollbackExceptionTest2() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      String session =
+          "projects/project-2078/instances/instance-2078/databases/database-2078/sessions/session-2078";
+      ByteString transactionId = ByteString.EMPTY;
+      client.rollback(session, transactionId);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void partitionQueryTest() throws Exception {
+    PartitionResponse expectedResponse =
+        PartitionResponse.newBuilder()
+            .addAllPartitions(new ArrayList<Partition>())
+            .setTransaction(Transaction.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    PartitionQueryRequest request =
+        PartitionQueryRequest.newBuilder()
+            .setSession(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .setTransaction(TransactionSelector.newBuilder().build())
+            .setSql("sql114126")
+            .setParams(Struct.newBuilder().build())
+            .putAllParamTypes(new HashMap<String, Type>())
+            .setPartitionOptions(PartitionOptions.newBuilder().build())
+            .build();
+
+    PartitionResponse actualResponse = client.partitionQuery(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void partitionQueryExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      PartitionQueryRequest request =
+          PartitionQueryRequest.newBuilder()
+              .setSession(
+                  SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+              .setTransaction(TransactionSelector.newBuilder().build())
+              .setSql("sql114126")
+              .setParams(Struct.newBuilder().build())
+              .putAllParamTypes(new HashMap<String, Type>())
+              .setPartitionOptions(PartitionOptions.newBuilder().build())
+              .build();
+      client.partitionQuery(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+
+  @Test
+  public void partitionReadTest() throws Exception {
+    PartitionResponse expectedResponse =
+        PartitionResponse.newBuilder()
+            .addAllPartitions(new ArrayList<Partition>())
+            .setTransaction(Transaction.newBuilder().build())
+            .build();
+    mockService.addResponse(expectedResponse);
+
+    PartitionReadRequest request =
+        PartitionReadRequest.newBuilder()
+            .setSession(
+                SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+            .setTransaction(TransactionSelector.newBuilder().build())
+            .setTable("table110115790")
+            .setIndex("index100346066")
+            .addAllColumns(new ArrayList<String>())
+            .setKeySet(KeySet.newBuilder().build())
+            .setPartitionOptions(PartitionOptions.newBuilder().build())
+            .build();
+
+    PartitionResponse actualResponse = client.partitionRead(request);
+    Assert.assertEquals(expectedResponse, actualResponse);
+
+    List<String> actualRequests = mockService.getRequestPaths();
+    Assert.assertEquals(1, actualRequests.size());
+
+    String apiClientHeaderKey =
+        mockService
+            .getRequestHeaders()
+            .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey())
+            .iterator()
+            .next();
+    Assert.assertTrue(
+        GaxHttpJsonProperties.getDefaultApiClientHeaderPattern()
+            .matcher(apiClientHeaderKey)
+            .matches());
+  }
+
+  @Test
+  public void partitionReadExceptionTest() throws Exception {
+    ApiException exception =
+        ApiExceptionFactory.createException(
+            new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false);
+    mockService.addException(exception);
+
+    try {
+      PartitionReadRequest request =
+          PartitionReadRequest.newBuilder()
+              .setSession(
+                  SessionName.of("[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]").toString())
+              .setTransaction(TransactionSelector.newBuilder().build())
+              .setTable("table110115790")
+              .setIndex("index100346066")
+              .addAllColumns(new ArrayList<String>())
+              .setKeySet(KeySet.newBuilder().build())
+              .setPartitionOptions(PartitionOptions.newBuilder().build())
+              .build();
+      client.partitionRead(request);
+      Assert.fail("No exception raised");
+    } catch (InvalidArgumentException e) {
+      // Expected exception.
+    }
+  }
+}
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java
index 24b2c4bbfbf..863e6007b3b 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java
@@ -134,6 +134,7 @@ public void createSessionTest() throws Exception {
             .putAllLabels(new HashMap<String, String>())
             .setCreateTime(Timestamp.newBuilder().build())
             .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
             .build();
     mockSpanner.addResponse(expectedResponse);
 
@@ -176,6 +177,7 @@ public void createSessionTest2() throws Exception {
             .putAllLabels(new HashMap<String, String>())
             .setCreateTime(Timestamp.newBuilder().build())
             .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
             .build();
     mockSpanner.addResponse(expectedResponse);
 
@@ -296,6 +298,7 @@ public void getSessionTest() throws Exception {
             .putAllLabels(new HashMap<String, String>())
             .setCreateTime(Timestamp.newBuilder().build())
             .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
             .build();
     mockSpanner.addResponse(expectedResponse);
 
@@ -338,6 +341,7 @@ public void getSessionTest2() throws Exception {
             .putAllLabels(new HashMap<String, String>())
             .setCreateTime(Timestamp.newBuilder().build())
             .setApproximateLastUseTime(Timestamp.newBuilder().build())
+            .setCreatorRole("creatorRole-190742846")
             .build();
     mockSpanner.addResponse(expectedResponse);
 
diff --git a/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java b/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java
index 8795dc3c202..6b59f6a4f04 100644
--- a/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java
+++ b/grpc-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceAdminGrpc.java
@@ -699,7 +699,7 @@ public void createInstance(
      * The [response][google.longrunning.Operation.response] field type is
      * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
      * Authorization requires `spanner.instances.update` permission on
-     * resource [name][google.spanner.admin.instance.v1.Instance.name].
+     * the resource [name][google.spanner.admin.instance.v1.Instance.name].
      * </pre>
      */
     public void updateInstance(
@@ -1034,7 +1034,7 @@ public void createInstance(
      * The [response][google.longrunning.Operation.response] field type is
      * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
      * Authorization requires `spanner.instances.update` permission on
-     * resource [name][google.spanner.admin.instance.v1.Instance.name].
+     * the resource [name][google.spanner.admin.instance.v1.Instance.name].
      * </pre>
      */
     public void updateInstance(
@@ -1290,7 +1290,7 @@ public com.google.longrunning.Operation createInstance(
      * The [response][google.longrunning.Operation.response] field type is
      * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
      * Authorization requires `spanner.instances.update` permission on
-     * resource [name][google.spanner.admin.instance.v1.Instance.name].
+     * the resource [name][google.spanner.admin.instance.v1.Instance.name].
      * </pre>
      */
     public com.google.longrunning.Operation updateInstance(
@@ -1533,7 +1533,7 @@ protected InstanceAdminFutureStub build(
      * The [response][google.longrunning.Operation.response] field type is
      * [Instance][google.spanner.admin.instance.v1.Instance], if successful.
      * Authorization requires `spanner.instances.update` permission on
-     * resource [name][google.spanner.admin.instance.v1.Instance.name].
+     * the resource [name][google.spanner.admin.instance.v1.Instance.name].
      * </pre>
      */
     public com.google.common.util.concurrent.ListenableFuture<com.google.longrunning.Operation>
diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java
index 545ba582cac..59c7bec3d1a 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java
+++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java
@@ -134,6 +134,36 @@ private Instance(
           case 72:
             {
               processingUnits_ = input.readInt32();
+              break;
+            }
+          case 90:
+            {
+              com.google.protobuf.Timestamp.Builder subBuilder = null;
+              if (createTime_ != null) {
+                subBuilder = createTime_.toBuilder();
+              }
+              createTime_ =
+                  input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(createTime_);
+                createTime_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+          case 98:
+            {
+              com.google.protobuf.Timestamp.Builder subBuilder = null;
+              if (updateTime_ != null) {
+                subBuilder = updateTime_.toBuilder();
+              }
+              updateTime_ =
+                  input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(updateTime_);
+                updateTime_ = subBuilder.buildPartial();
+              }
+
               break;
             }
           default:
@@ -520,11 +550,13 @@ public com.google.protobuf.ByteString getDisplayNameBytes() {
    *
    *
    * <pre>
-   * Required. The number of nodes allocated to this instance. This may be zero
-   * in API responses for instances that are not yet in state `READY`.
+   * The number of nodes allocated to this instance. At most one of either
+   * node_count or processing_units should be present in the message. This
+   * may be zero in API responses for instances that are not yet in state
+   * `READY`.
    * See [the
-   * documentation](https://cloud.google.com/spanner/docs/instances#node_count)
-   * for more information about nodes.
+   * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+   * for more information about nodes and processing units.
    * </pre>
    *
    * <code>int32 node_count = 5;</code>
@@ -545,6 +577,9 @@ public int getNodeCount() {
    * The number of processing units allocated to this instance. At most one of
    * processing_units or node_count should be present in the message. This may
    * be zero in API responses for instances that are not yet in state `READY`.
+   * See [the
+   * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+   * for more information about nodes and processing units.
    * </pre>
    *
    * <code>int32 processing_units = 9;</code>
@@ -642,9 +677,9 @@ public int getLabelsCount() {
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -681,9 +716,9 @@ public java.util.Map<java.lang.String, java.lang.String> getLabels() {
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -711,9 +746,9 @@ public java.util.Map<java.lang.String, java.lang.String> getLabelsMap() {
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -745,9 +780,9 @@ public java.lang.String getLabelsOrDefault(java.lang.String key, java.lang.Strin
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -833,6 +868,104 @@ public com.google.protobuf.ByteString getEndpointUrisBytes(int index) {
     return endpointUris_.getByteString(index);
   }
 
+  public static final int CREATE_TIME_FIELD_NUMBER = 11;
+  private com.google.protobuf.Timestamp createTime_;
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was created.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return Whether the createTime field is set.
+   */
+  @java.lang.Override
+  public boolean hasCreateTime() {
+    return createTime_ != null;
+  }
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was created.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return The createTime.
+   */
+  @java.lang.Override
+  public com.google.protobuf.Timestamp getCreateTime() {
+    return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_;
+  }
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was created.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   */
+  @java.lang.Override
+  public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() {
+    return getCreateTime();
+  }
+
+  public static final int UPDATE_TIME_FIELD_NUMBER = 12;
+  private com.google.protobuf.Timestamp updateTime_;
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was most recently updated.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return Whether the updateTime field is set.
+   */
+  @java.lang.Override
+  public boolean hasUpdateTime() {
+    return updateTime_ != null;
+  }
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was most recently updated.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return The updateTime.
+   */
+  @java.lang.Override
+  public com.google.protobuf.Timestamp getUpdateTime() {
+    return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_;
+  }
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was most recently updated.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   */
+  @java.lang.Override
+  public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() {
+    return getUpdateTime();
+  }
+
   private byte memoizedIsInitialized = -1;
 
   @java.lang.Override
@@ -871,6 +1004,12 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io
     if (processingUnits_ != 0) {
       output.writeInt32(9, processingUnits_);
     }
+    if (createTime_ != null) {
+      output.writeMessage(11, getCreateTime());
+    }
+    if (updateTime_ != null) {
+      output.writeMessage(12, getUpdateTime());
+    }
     unknownFields.writeTo(output);
   }
 
@@ -917,6 +1056,12 @@ public int getSerializedSize() {
     if (processingUnits_ != 0) {
       size += com.google.protobuf.CodedOutputStream.computeInt32Size(9, processingUnits_);
     }
+    if (createTime_ != null) {
+      size += com.google.protobuf.CodedOutputStream.computeMessageSize(11, getCreateTime());
+    }
+    if (updateTime_ != null) {
+      size += com.google.protobuf.CodedOutputStream.computeMessageSize(12, getUpdateTime());
+    }
     size += unknownFields.getSerializedSize();
     memoizedSize = size;
     return size;
@@ -941,6 +1086,14 @@ public boolean equals(final java.lang.Object obj) {
     if (state_ != other.state_) return false;
     if (!internalGetLabels().equals(other.internalGetLabels())) return false;
     if (!getEndpointUrisList().equals(other.getEndpointUrisList())) return false;
+    if (hasCreateTime() != other.hasCreateTime()) return false;
+    if (hasCreateTime()) {
+      if (!getCreateTime().equals(other.getCreateTime())) return false;
+    }
+    if (hasUpdateTime() != other.hasUpdateTime()) return false;
+    if (hasUpdateTime()) {
+      if (!getUpdateTime().equals(other.getUpdateTime())) return false;
+    }
     if (!unknownFields.equals(other.unknownFields)) return false;
     return true;
   }
@@ -972,6 +1125,14 @@ public int hashCode() {
       hash = (37 * hash) + ENDPOINT_URIS_FIELD_NUMBER;
       hash = (53 * hash) + getEndpointUrisList().hashCode();
     }
+    if (hasCreateTime()) {
+      hash = (37 * hash) + CREATE_TIME_FIELD_NUMBER;
+      hash = (53 * hash) + getCreateTime().hashCode();
+    }
+    if (hasUpdateTime()) {
+      hash = (37 * hash) + UPDATE_TIME_FIELD_NUMBER;
+      hash = (53 * hash) + getUpdateTime().hashCode();
+    }
     hash = (29 * hash) + unknownFields.hashCode();
     memoizedHashCode = hash;
     return hash;
@@ -1152,6 +1313,18 @@ public Builder clear() {
       internalGetMutableLabels().clear();
       endpointUris_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       bitField0_ = (bitField0_ & ~0x00000002);
+      if (createTimeBuilder_ == null) {
+        createTime_ = null;
+      } else {
+        createTime_ = null;
+        createTimeBuilder_ = null;
+      }
+      if (updateTimeBuilder_ == null) {
+        updateTime_ = null;
+      } else {
+        updateTime_ = null;
+        updateTimeBuilder_ = null;
+      }
       return this;
     }
 
@@ -1193,6 +1366,16 @@ public com.google.spanner.admin.instance.v1.Instance buildPartial() {
         bitField0_ = (bitField0_ & ~0x00000002);
       }
       result.endpointUris_ = endpointUris_;
+      if (createTimeBuilder_ == null) {
+        result.createTime_ = createTime_;
+      } else {
+        result.createTime_ = createTimeBuilder_.build();
+      }
+      if (updateTimeBuilder_ == null) {
+        result.updateTime_ = updateTime_;
+      } else {
+        result.updateTime_ = updateTimeBuilder_.build();
+      }
       onBuilt();
       return result;
     }
@@ -1274,6 +1457,12 @@ public Builder mergeFrom(com.google.spanner.admin.instance.v1.Instance other) {
         }
         onChanged();
       }
+      if (other.hasCreateTime()) {
+        mergeCreateTime(other.getCreateTime());
+      }
+      if (other.hasUpdateTime()) {
+        mergeUpdateTime(other.getUpdateTime());
+      }
       this.mergeUnknownFields(other.unknownFields);
       onChanged();
       return this;
@@ -1673,11 +1862,13 @@ public Builder setDisplayNameBytes(com.google.protobuf.ByteString value) {
      *
      *
      * <pre>
-     * Required. The number of nodes allocated to this instance. This may be zero
-     * in API responses for instances that are not yet in state `READY`.
+     * The number of nodes allocated to this instance. At most one of either
+     * node_count or processing_units should be present in the message. This
+     * may be zero in API responses for instances that are not yet in state
+     * `READY`.
      * See [the
-     * documentation](https://cloud.google.com/spanner/docs/instances#node_count)
-     * for more information about nodes.
+     * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+     * for more information about nodes and processing units.
      * </pre>
      *
      * <code>int32 node_count = 5;</code>
@@ -1692,11 +1883,13 @@ public int getNodeCount() {
      *
      *
      * <pre>
-     * Required. The number of nodes allocated to this instance. This may be zero
-     * in API responses for instances that are not yet in state `READY`.
+     * The number of nodes allocated to this instance. At most one of either
+     * node_count or processing_units should be present in the message. This
+     * may be zero in API responses for instances that are not yet in state
+     * `READY`.
      * See [the
-     * documentation](https://cloud.google.com/spanner/docs/instances#node_count)
-     * for more information about nodes.
+     * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+     * for more information about nodes and processing units.
      * </pre>
      *
      * <code>int32 node_count = 5;</code>
@@ -1714,11 +1907,13 @@ public Builder setNodeCount(int value) {
      *
      *
      * <pre>
-     * Required. The number of nodes allocated to this instance. This may be zero
-     * in API responses for instances that are not yet in state `READY`.
+     * The number of nodes allocated to this instance. At most one of either
+     * node_count or processing_units should be present in the message. This
+     * may be zero in API responses for instances that are not yet in state
+     * `READY`.
      * See [the
-     * documentation](https://cloud.google.com/spanner/docs/instances#node_count)
-     * for more information about nodes.
+     * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+     * for more information about nodes and processing units.
      * </pre>
      *
      * <code>int32 node_count = 5;</code>
@@ -1740,6 +1935,9 @@ public Builder clearNodeCount() {
      * The number of processing units allocated to this instance. At most one of
      * processing_units or node_count should be present in the message. This may
      * be zero in API responses for instances that are not yet in state `READY`.
+     * See [the
+     * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+     * for more information about nodes and processing units.
      * </pre>
      *
      * <code>int32 processing_units = 9;</code>
@@ -1757,6 +1955,9 @@ public int getProcessingUnits() {
      * The number of processing units allocated to this instance. At most one of
      * processing_units or node_count should be present in the message. This may
      * be zero in API responses for instances that are not yet in state `READY`.
+     * See [the
+     * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+     * for more information about nodes and processing units.
      * </pre>
      *
      * <code>int32 processing_units = 9;</code>
@@ -1777,6 +1978,9 @@ public Builder setProcessingUnits(int value) {
      * The number of processing units allocated to this instance. At most one of
      * processing_units or node_count should be present in the message. This may
      * be zero in API responses for instances that are not yet in state `READY`.
+     * See [the
+     * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+     * for more information about nodes and processing units.
      * </pre>
      *
      * <code>int32 processing_units = 9;</code>
@@ -1949,9 +2153,9 @@ public int getLabelsCount() {
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -1988,9 +2192,9 @@ public java.util.Map<java.lang.String, java.lang.String> getLabels() {
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -2018,9 +2222,9 @@ public java.util.Map<java.lang.String, java.lang.String> getLabelsMap() {
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -2053,9 +2257,9 @@ public java.lang.String getLabelsOrDefault(
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -2095,9 +2299,9 @@ public Builder clearLabels() {
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -2133,9 +2337,9 @@ public java.util.Map<java.lang.String, java.lang.String> getMutableLabels() {
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -2170,9 +2374,9 @@ public Builder putLabels(java.lang.String key, java.lang.String value) {
      * And they can be used as arguments to policy management rules (e.g. route,
      * firewall, load balancing, etc.).
      *  * Label keys must be between 1 and 63 characters long and must conform to
-     *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+     *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
      *  * Label values must be between 0 and 63 characters long and must conform
-     *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+     *    to the regular expression `[a-z0-9_-]{0,63}`.
      *  * No more than 64 labels can be associated with a given resource.
      * See https://goo.gl/xmQnxf for more information on and examples of labels.
      * If you plan to use labels in your own code, please note that additional
@@ -2358,6 +2562,408 @@ public Builder addEndpointUrisBytes(com.google.protobuf.ByteString value) {
       return this;
     }
 
+    private com.google.protobuf.Timestamp createTime_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp,
+            com.google.protobuf.Timestamp.Builder,
+            com.google.protobuf.TimestampOrBuilder>
+        createTimeBuilder_;
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     *
+     * @return Whether the createTime field is set.
+     */
+    public boolean hasCreateTime() {
+      return createTimeBuilder_ != null || createTime_ != null;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     *
+     * @return The createTime.
+     */
+    public com.google.protobuf.Timestamp getCreateTime() {
+      if (createTimeBuilder_ == null) {
+        return createTime_ == null
+            ? com.google.protobuf.Timestamp.getDefaultInstance()
+            : createTime_;
+      } else {
+        return createTimeBuilder_.getMessage();
+      }
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder setCreateTime(com.google.protobuf.Timestamp value) {
+      if (createTimeBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        createTime_ = value;
+        onChanged();
+      } else {
+        createTimeBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder setCreateTime(com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (createTimeBuilder_ == null) {
+        createTime_ = builderForValue.build();
+        onChanged();
+      } else {
+        createTimeBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder mergeCreateTime(com.google.protobuf.Timestamp value) {
+      if (createTimeBuilder_ == null) {
+        if (createTime_ != null) {
+          createTime_ =
+              com.google.protobuf.Timestamp.newBuilder(createTime_).mergeFrom(value).buildPartial();
+        } else {
+          createTime_ = value;
+        }
+        onChanged();
+      } else {
+        createTimeBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder clearCreateTime() {
+      if (createTimeBuilder_ == null) {
+        createTime_ = null;
+        onChanged();
+      } else {
+        createTime_ = null;
+        createTimeBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() {
+
+      onChanged();
+      return getCreateTimeFieldBuilder().getBuilder();
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() {
+      if (createTimeBuilder_ != null) {
+        return createTimeBuilder_.getMessageOrBuilder();
+      } else {
+        return createTime_ == null
+            ? com.google.protobuf.Timestamp.getDefaultInstance()
+            : createTime_;
+      }
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was created.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp,
+            com.google.protobuf.Timestamp.Builder,
+            com.google.protobuf.TimestampOrBuilder>
+        getCreateTimeFieldBuilder() {
+      if (createTimeBuilder_ == null) {
+        createTimeBuilder_ =
+            new com.google.protobuf.SingleFieldBuilderV3<
+                com.google.protobuf.Timestamp,
+                com.google.protobuf.Timestamp.Builder,
+                com.google.protobuf.TimestampOrBuilder>(
+                getCreateTime(), getParentForChildren(), isClean());
+        createTime_ = null;
+      }
+      return createTimeBuilder_;
+    }
+
+    private com.google.protobuf.Timestamp updateTime_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp,
+            com.google.protobuf.Timestamp.Builder,
+            com.google.protobuf.TimestampOrBuilder>
+        updateTimeBuilder_;
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     *
+     * @return Whether the updateTime field is set.
+     */
+    public boolean hasUpdateTime() {
+      return updateTimeBuilder_ != null || updateTime_ != null;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     *
+     * @return The updateTime.
+     */
+    public com.google.protobuf.Timestamp getUpdateTime() {
+      if (updateTimeBuilder_ == null) {
+        return updateTime_ == null
+            ? com.google.protobuf.Timestamp.getDefaultInstance()
+            : updateTime_;
+      } else {
+        return updateTimeBuilder_.getMessage();
+      }
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder setUpdateTime(com.google.protobuf.Timestamp value) {
+      if (updateTimeBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        updateTime_ = value;
+        onChanged();
+      } else {
+        updateTimeBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (updateTimeBuilder_ == null) {
+        updateTime_ = builderForValue.build();
+        onChanged();
+      } else {
+        updateTimeBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) {
+      if (updateTimeBuilder_ == null) {
+        if (updateTime_ != null) {
+          updateTime_ =
+              com.google.protobuf.Timestamp.newBuilder(updateTime_).mergeFrom(value).buildPartial();
+        } else {
+          updateTime_ = value;
+        }
+        onChanged();
+      } else {
+        updateTimeBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public Builder clearUpdateTime() {
+      if (updateTimeBuilder_ == null) {
+        updateTime_ = null;
+        onChanged();
+      } else {
+        updateTime_ = null;
+        updateTimeBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() {
+
+      onChanged();
+      return getUpdateTimeFieldBuilder().getBuilder();
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() {
+      if (updateTimeBuilder_ != null) {
+        return updateTimeBuilder_.getMessageOrBuilder();
+      } else {
+        return updateTime_ == null
+            ? com.google.protobuf.Timestamp.getDefaultInstance()
+            : updateTime_;
+      }
+    }
+    /**
+     *
+     *
+     * <pre>
+     * Output only. The time at which the instance was most recently updated.
+     * </pre>
+     *
+     * <code>
+     * .google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+     * </code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp,
+            com.google.protobuf.Timestamp.Builder,
+            com.google.protobuf.TimestampOrBuilder>
+        getUpdateTimeFieldBuilder() {
+      if (updateTimeBuilder_ == null) {
+        updateTimeBuilder_ =
+            new com.google.protobuf.SingleFieldBuilderV3<
+                com.google.protobuf.Timestamp,
+                com.google.protobuf.Timestamp.Builder,
+                com.google.protobuf.TimestampOrBuilder>(
+                getUpdateTime(), getParentForChildren(), isClean());
+        updateTime_ = null;
+      }
+      return updateTimeBuilder_;
+    }
+
     @java.lang.Override
     public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
       return super.setUnknownFields(unknownFields);
diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java
index 9051e78c16e..f38d4bc1df1 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java
+++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfig.java
@@ -162,7 +162,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
    * <pre>
    * A unique identifier for the instance configuration.  Values
    * are of the form
-   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
    * </pre>
    *
    * <code>string name = 1;</code>
@@ -187,7 +187,7 @@ public java.lang.String getName() {
    * <pre>
    * A unique identifier for the instance configuration.  Values
    * are of the form
-   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
    * </pre>
    *
    * <code>string name = 1;</code>
@@ -336,7 +336,7 @@ public com.google.spanner.admin.instance.v1.ReplicaInfoOrBuilder getReplicasOrBu
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -351,7 +351,7 @@ public com.google.protobuf.ProtocolStringList getLeaderOptionsList() {
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -366,7 +366,7 @@ public int getLeaderOptionsCount() {
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -382,7 +382,7 @@ public java.lang.String getLeaderOptions(int index) {
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -828,7 +828,7 @@ public Builder mergeFrom(
      * <pre>
      * A unique identifier for the instance configuration.  Values
      * are of the form
-     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
      * </pre>
      *
      * <code>string name = 1;</code>
@@ -852,7 +852,7 @@ public java.lang.String getName() {
      * <pre>
      * A unique identifier for the instance configuration.  Values
      * are of the form
-     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
      * </pre>
      *
      * <code>string name = 1;</code>
@@ -876,7 +876,7 @@ public com.google.protobuf.ByteString getNameBytes() {
      * <pre>
      * A unique identifier for the instance configuration.  Values
      * are of the form
-     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
      * </pre>
      *
      * <code>string name = 1;</code>
@@ -899,7 +899,7 @@ public Builder setName(java.lang.String value) {
      * <pre>
      * A unique identifier for the instance configuration.  Values
      * are of the form
-     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
      * </pre>
      *
      * <code>string name = 1;</code>
@@ -918,7 +918,7 @@ public Builder clearName() {
      * <pre>
      * A unique identifier for the instance configuration.  Values
      * are of the form
-     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+     * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
      * </pre>
      *
      * <code>string name = 1;</code>
@@ -1426,7 +1426,7 @@ private void ensureLeaderOptionsIsMutable() {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1441,7 +1441,7 @@ public com.google.protobuf.ProtocolStringList getLeaderOptionsList() {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1456,7 +1456,7 @@ public int getLeaderOptionsCount() {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1472,7 +1472,7 @@ public java.lang.String getLeaderOptions(int index) {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1488,7 +1488,7 @@ public com.google.protobuf.ByteString getLeaderOptionsBytes(int index) {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1511,7 +1511,7 @@ public Builder setLeaderOptions(int index, java.lang.String value) {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1533,7 +1533,7 @@ public Builder addLeaderOptions(java.lang.String value) {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1552,7 +1552,7 @@ public Builder addAllLeaderOptions(java.lang.Iterable<java.lang.String> values)
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
@@ -1570,7 +1570,7 @@ public Builder clearLeaderOptions() {
      *
      *
      * <pre>
-     * Allowed values of the “default_leader” schema option for databases in
+     * Allowed values of the "default_leader" schema option for databases in
      * instances that use this instance configuration.
      * </pre>
      *
diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java
index 8e786e71614..6b993e71636 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java
+++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceConfigOrBuilder.java
@@ -29,7 +29,7 @@ public interface InstanceConfigOrBuilder
    * <pre>
    * A unique identifier for the instance configuration.  Values
    * are of the form
-   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
    * </pre>
    *
    * <code>string name = 1;</code>
@@ -43,7 +43,7 @@ public interface InstanceConfigOrBuilder
    * <pre>
    * A unique identifier for the instance configuration.  Values
    * are of the form
-   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`
+   * `projects/&lt;project&gt;/instanceConfigs/[a-z][-a-z0-9]*`.
    * </pre>
    *
    * <code>string name = 1;</code>
@@ -138,7 +138,7 @@ public interface InstanceConfigOrBuilder
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -151,7 +151,7 @@ public interface InstanceConfigOrBuilder
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -164,7 +164,7 @@ public interface InstanceConfigOrBuilder
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
@@ -178,7 +178,7 @@ public interface InstanceConfigOrBuilder
    *
    *
    * <pre>
-   * Allowed values of the “default_leader” schema option for databases in
+   * Allowed values of the "default_leader" schema option for databases in
    * instances that use this instance configuration.
    * </pre>
    *
diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java
index ac663b72453..b060a9c1d01 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java
+++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java
@@ -120,11 +120,13 @@ public interface InstanceOrBuilder
    *
    *
    * <pre>
-   * Required. The number of nodes allocated to this instance. This may be zero
-   * in API responses for instances that are not yet in state `READY`.
+   * The number of nodes allocated to this instance. At most one of either
+   * node_count or processing_units should be present in the message. This
+   * may be zero in API responses for instances that are not yet in state
+   * `READY`.
    * See [the
-   * documentation](https://cloud.google.com/spanner/docs/instances#node_count)
-   * for more information about nodes.
+   * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+   * for more information about nodes and processing units.
    * </pre>
    *
    * <code>int32 node_count = 5;</code>
@@ -140,6 +142,9 @@ public interface InstanceOrBuilder
    * The number of processing units allocated to this instance. At most one of
    * processing_units or node_count should be present in the message. This may
    * be zero in API responses for instances that are not yet in state `READY`.
+   * See [the
+   * documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+   * for more information about nodes and processing units.
    * </pre>
    *
    * <code>int32 processing_units = 9;</code>
@@ -196,9 +201,9 @@ public interface InstanceOrBuilder
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -223,9 +228,9 @@ public interface InstanceOrBuilder
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -253,9 +258,9 @@ public interface InstanceOrBuilder
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -280,9 +285,9 @@ public interface InstanceOrBuilder
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -312,9 +317,9 @@ java.lang.String getLabelsOrDefault(
    * And they can be used as arguments to policy management rules (e.g. route,
    * firewall, load balancing, etc.).
    *  * Label keys must be between 1 and 63 characters long and must conform to
-   *    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+   *    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
    *  * Label values must be between 0 and 63 characters long and must conform
-   *    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+   *    to the regular expression `[a-z0-9_-]{0,63}`.
    *  * No more than 64 labels can be associated with a given resource.
    * See https://goo.gl/xmQnxf for more information on and examples of labels.
    * If you plan to use labels in your own code, please note that additional
@@ -379,4 +384,80 @@ java.lang.String getLabelsOrDefault(
    * @return The bytes of the endpointUris at the given index.
    */
   com.google.protobuf.ByteString getEndpointUrisBytes(int index);
+
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was created.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return Whether the createTime field is set.
+   */
+  boolean hasCreateTime();
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was created.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return The createTime.
+   */
+  com.google.protobuf.Timestamp getCreateTime();
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was created.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp create_time = 11 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   */
+  com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder();
+
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was most recently updated.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return Whether the updateTime field is set.
+   */
+  boolean hasUpdateTime();
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was most recently updated.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   *
+   * @return The updateTime.
+   */
+  com.google.protobuf.Timestamp getUpdateTime();
+  /**
+   *
+   *
+   * <pre>
+   * Output only. The time at which the instance was most recently updated.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp update_time = 12 [(.google.api.field_behavior) = OUTPUT_ONLY];
+   * </code>
+   */
+  com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder();
 }
diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java
index dfe7849894e..74cd826b031 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java
+++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java
@@ -117,7 +117,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
           + "in.instance.v1.ReplicaInfo\022\026\n\016leader_opt"
           + "ions\030\004 \003(\t:`\352A]\n%spanner.googleapis.com/"
           + "InstanceConfig\0224projects/{project}/insta"
-          + "nceConfigs/{instance_config}\"\201\004\n\010Instanc"
+          + "nceConfigs/{instance_config}\"\355\004\n\010Instanc"
           + "e\022\021\n\004name\030\001 \001(\tB\003\340A\002\022=\n\006config\030\002 \001(\tB-\340A"
           + "\002\372A\'\n%spanner.googleapis.com/InstanceCon"
           + "fig\022\031\n\014display_name\030\003 \001(\tB\003\340A\002\022\022\n\nnode_c"
@@ -126,112 +126,114 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
           + "nce.v1.Instance.StateB\003\340A\003\022F\n\006labels\030\007 \003"
           + "(\01326.google.spanner.admin.instance.v1.In"
           + "stance.LabelsEntry\022\025\n\rendpoint_uris\030\010 \003("
-          + "\t\032-\n\013LabelsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002"
-          + " \001(\t:\0028\001\"7\n\005State\022\025\n\021STATE_UNSPECIFIED\020\000"
-          + "\022\014\n\010CREATING\020\001\022\t\n\005READY\020\002:M\352AJ\n\037spanner."
-          + "googleapis.com/Instance\022\'projects/{proje"
-          + "ct}/instances/{instance}\"\210\001\n\032ListInstanc"
-          + "eConfigsRequest\022C\n\006parent\030\001 \001(\tB3\340A\002\372A-\n"
-          + "+cloudresourcemanager.googleapis.com/Pro"
-          + "ject\022\021\n\tpage_size\030\002 \001(\005\022\022\n\npage_token\030\003 "
-          + "\001(\t\"\202\001\n\033ListInstanceConfigsResponse\022J\n\020i"
-          + "nstance_configs\030\001 \003(\01320.google.spanner.a"
-          + "dmin.instance.v1.InstanceConfig\022\027\n\017next_"
-          + "page_token\030\002 \001(\t\"W\n\030GetInstanceConfigReq"
-          + "uest\022;\n\004name\030\001 \001(\tB-\340A\002\372A\'\n%spanner.goog"
-          + "leapis.com/InstanceConfig\"{\n\022GetInstance"
-          + "Request\0225\n\004name\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.g"
-          + "oogleapis.com/Instance\022.\n\nfield_mask\030\002 \001"
-          + "(\0132\032.google.protobuf.FieldMask\"\271\001\n\025Creat"
-          + "eInstanceRequest\022C\n\006parent\030\001 \001(\tB3\340A\002\372A-"
-          + "\n+cloudresourcemanager.googleapis.com/Pr"
-          + "oject\022\030\n\013instance_id\030\002 \001(\tB\003\340A\002\022A\n\010insta"
-          + "nce\030\003 \001(\0132*.google.spanner.admin.instanc"
-          + "e.v1.InstanceB\003\340A\002\"\222\001\n\024ListInstancesRequ"
+          + "\t\0224\n\013create_time\030\013 \001(\0132\032.google.protobuf"
+          + ".TimestampB\003\340A\003\0224\n\013update_time\030\014 \001(\0132\032.g"
+          + "oogle.protobuf.TimestampB\003\340A\003\032-\n\013LabelsE"
+          + "ntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"7\n\005"
+          + "State\022\025\n\021STATE_UNSPECIFIED\020\000\022\014\n\010CREATING"
+          + "\020\001\022\t\n\005READY\020\002:M\352AJ\n\037spanner.googleapis.c"
+          + "om/Instance\022\'projects/{project}/instance"
+          + "s/{instance}\"\210\001\n\032ListInstanceConfigsRequ"
           + "est\022C\n\006parent\030\001 \001(\tB3\340A\002\372A-\n+cloudresour"
           + "cemanager.googleapis.com/Project\022\021\n\tpage"
-          + "_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\022\016\n\006filte"
-          + "r\030\004 \001(\t\"o\n\025ListInstancesResponse\022=\n\tinst"
-          + "ances\030\001 \003(\0132*.google.spanner.admin.insta"
-          + "nce.v1.Instance\022\027\n\017next_page_token\030\002 \001(\t"
-          + "\"\217\001\n\025UpdateInstanceRequest\022A\n\010instance\030\001"
-          + " \001(\0132*.google.spanner.admin.instance.v1."
-          + "InstanceB\003\340A\002\0223\n\nfield_mask\030\002 \001(\0132\032.goog"
-          + "le.protobuf.FieldMaskB\003\340A\002\"N\n\025DeleteInst"
-          + "anceRequest\0225\n\004name\030\001 \001(\tB\'\340A\002\372A!\n\037spann"
-          + "er.googleapis.com/Instance\"\345\001\n\026CreateIns"
-          + "tanceMetadata\022<\n\010instance\030\001 \001(\0132*.google"
-          + ".spanner.admin.instance.v1.Instance\022.\n\ns"
-          + "tart_time\030\002 \001(\0132\032.google.protobuf.Timest"
-          + "amp\022/\n\013cancel_time\030\003 \001(\0132\032.google.protob"
-          + "uf.Timestamp\022,\n\010end_time\030\004 \001(\0132\032.google."
-          + "protobuf.Timestamp\"\345\001\n\026UpdateInstanceMet"
-          + "adata\022<\n\010instance\030\001 \001(\0132*.google.spanner"
-          + ".admin.instance.v1.Instance\022.\n\nstart_tim"
-          + "e\030\002 \001(\0132\032.google.protobuf.Timestamp\022/\n\013c"
-          + "ancel_time\030\003 \001(\0132\032.google.protobuf.Times"
-          + "tamp\022,\n\010end_time\030\004 \001(\0132\032.google.protobuf"
-          + ".Timestamp2\277\020\n\rInstanceAdmin\022\314\001\n\023ListIns"
-          + "tanceConfigs\022<.google.spanner.admin.inst"
-          + "ance.v1.ListInstanceConfigsRequest\032=.goo"
-          + "gle.spanner.admin.instance.v1.ListInstan"
-          + "ceConfigsResponse\"8\202\323\344\223\002)\022\'/v1/{parent=p"
-          + "rojects/*}/instanceConfigs\332A\006parent\022\271\001\n\021"
-          + "GetInstanceConfig\022:.google.spanner.admin"
-          + ".instance.v1.GetInstanceConfigRequest\0320."
+          + "_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\"\202\001\n\033List"
+          + "InstanceConfigsResponse\022J\n\020instance_conf"
+          + "igs\030\001 \003(\01320.google.spanner.admin.instanc"
+          + "e.v1.InstanceConfig\022\027\n\017next_page_token\030\002"
+          + " \001(\t\"W\n\030GetInstanceConfigRequest\022;\n\004name"
+          + "\030\001 \001(\tB-\340A\002\372A\'\n%spanner.googleapis.com/I"
+          + "nstanceConfig\"{\n\022GetInstanceRequest\0225\n\004n"
+          + "ame\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleapis.co"
+          + "m/Instance\022.\n\nfield_mask\030\002 \001(\0132\032.google."
+          + "protobuf.FieldMask\"\271\001\n\025CreateInstanceReq"
+          + "uest\022C\n\006parent\030\001 \001(\tB3\340A\002\372A-\n+cloudresou"
+          + "rcemanager.googleapis.com/Project\022\030\n\013ins"
+          + "tance_id\030\002 \001(\tB\003\340A\002\022A\n\010instance\030\003 \001(\0132*."
           + "google.spanner.admin.instance.v1.Instanc"
-          + "eConfig\"6\202\323\344\223\002)\022\'/v1/{name=projects/*/in"
-          + "stanceConfigs/*}\332A\004name\022\264\001\n\rListInstance"
-          + "s\0226.google.spanner.admin.instance.v1.Lis"
-          + "tInstancesRequest\0327.google.spanner.admin"
-          + ".instance.v1.ListInstancesResponse\"2\202\323\344\223"
-          + "\002#\022!/v1/{parent=projects/*}/instances\332A\006"
-          + "parent\022\241\001\n\013GetInstance\0224.google.spanner."
-          + "admin.instance.v1.GetInstanceRequest\032*.g"
-          + "oogle.spanner.admin.instance.v1.Instance"
-          + "\"0\202\323\344\223\002#\022!/v1/{name=projects/*/instances"
-          + "/*}\332A\004name\022\234\002\n\016CreateInstance\0227.google.s"
-          + "panner.admin.instance.v1.CreateInstanceR"
-          + "equest\032\035.google.longrunning.Operation\"\261\001"
-          + "\202\323\344\223\002&\"!/v1/{parent=projects/*}/instance"
-          + "s:\001*\332A\033parent,instance_id,instance\312Ad\n)g"
-          + "oogle.spanner.admin.instance.v1.Instance"
-          + "\0227google.spanner.admin.instance.v1.Creat"
-          + "eInstanceMetadata\022\235\002\n\016UpdateInstance\0227.g"
-          + "oogle.spanner.admin.instance.v1.UpdateIn"
-          + "stanceRequest\032\035.google.longrunning.Opera"
-          + "tion\"\262\001\202\323\344\223\002/2*/v1/{instance.name=projec"
-          + "ts/*/instances/*}:\001*\332A\023instance,field_ma"
-          + "sk\312Ad\n)google.spanner.admin.instance.v1."
-          + "Instance\0227google.spanner.admin.instance."
-          + "v1.UpdateInstanceMetadata\022\223\001\n\016DeleteInst"
-          + "ance\0227.google.spanner.admin.instance.v1."
-          + "DeleteInstanceRequest\032\026.google.protobuf."
-          + "Empty\"0\202\323\344\223\002#*!/v1/{name=projects/*/inst"
-          + "ances/*}\332A\004name\022\232\001\n\014SetIamPolicy\022\".googl"
-          + "e.iam.v1.SetIamPolicyRequest\032\025.google.ia"
-          + "m.v1.Policy\"O\202\323\344\223\0027\"2/v1/{resource=proje"
-          + "cts/*/instances/*}:setIamPolicy:\001*\332A\017res"
-          + "ource,policy\022\223\001\n\014GetIamPolicy\022\".google.i"
-          + "am.v1.GetIamPolicyRequest\032\025.google.iam.v"
-          + "1.Policy\"H\202\323\344\223\0027\"2/v1/{resource=projects"
-          + "/*/instances/*}:getIamPolicy:\001*\332A\010resour"
-          + "ce\022\305\001\n\022TestIamPermissions\022(.google.iam.v"
-          + "1.TestIamPermissionsRequest\032).google.iam"
-          + ".v1.TestIamPermissionsResponse\"Z\202\323\344\223\002=\"8"
-          + "/v1/{resource=projects/*/instances/*}:te"
-          + "stIamPermissions:\001*\332A\024resource,permissio"
-          + "ns\032x\312A\026spanner.googleapis.com\322A\\https://"
-          + "www.googleapis.com/auth/cloud-platform,h"
-          + "ttps://www.googleapis.com/auth/spanner.a"
-          + "dminB\215\002\n$com.google.spanner.admin.instan"
-          + "ce.v1B\031SpannerInstanceAdminProtoP\001ZHgoog"
-          + "le.golang.org/genproto/googleapis/spanne"
-          + "r/admin/instance/v1;instance\252\002&Google.Cl"
-          + "oud.Spanner.Admin.Instance.V1\312\002&Google\\C"
-          + "loud\\Spanner\\Admin\\Instance\\V1\352\002+Google:"
-          + ":Cloud::Spanner::Admin::Instance::V1b\006pr"
-          + "oto3"
+          + "eB\003\340A\002\"\222\001\n\024ListInstancesRequest\022C\n\006paren"
+          + "t\030\001 \001(\tB3\340A\002\372A-\n+cloudresourcemanager.go"
+          + "ogleapis.com/Project\022\021\n\tpage_size\030\002 \001(\005\022"
+          + "\022\n\npage_token\030\003 \001(\t\022\016\n\006filter\030\004 \001(\t\"o\n\025L"
+          + "istInstancesResponse\022=\n\tinstances\030\001 \003(\0132"
+          + "*.google.spanner.admin.instance.v1.Insta"
+          + "nce\022\027\n\017next_page_token\030\002 \001(\t\"\217\001\n\025UpdateI"
+          + "nstanceRequest\022A\n\010instance\030\001 \001(\0132*.googl"
+          + "e.spanner.admin.instance.v1.InstanceB\003\340A"
+          + "\002\0223\n\nfield_mask\030\002 \001(\0132\032.google.protobuf."
+          + "FieldMaskB\003\340A\002\"N\n\025DeleteInstanceRequest\022"
+          + "5\n\004name\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleapi"
+          + "s.com/Instance\"\345\001\n\026CreateInstanceMetadat"
+          + "a\022<\n\010instance\030\001 \001(\0132*.google.spanner.adm"
+          + "in.instance.v1.Instance\022.\n\nstart_time\030\002 "
+          + "\001(\0132\032.google.protobuf.Timestamp\022/\n\013cance"
+          + "l_time\030\003 \001(\0132\032.google.protobuf.Timestamp"
+          + "\022,\n\010end_time\030\004 \001(\0132\032.google.protobuf.Tim"
+          + "estamp\"\345\001\n\026UpdateInstanceMetadata\022<\n\010ins"
+          + "tance\030\001 \001(\0132*.google.spanner.admin.insta"
+          + "nce.v1.Instance\022.\n\nstart_time\030\002 \001(\0132\032.go"
+          + "ogle.protobuf.Timestamp\022/\n\013cancel_time\030\003"
+          + " \001(\0132\032.google.protobuf.Timestamp\022,\n\010end_"
+          + "time\030\004 \001(\0132\032.google.protobuf.Timestamp2\277"
+          + "\020\n\rInstanceAdmin\022\314\001\n\023ListInstanceConfigs"
+          + "\022<.google.spanner.admin.instance.v1.List"
+          + "InstanceConfigsRequest\032=.google.spanner."
+          + "admin.instance.v1.ListInstanceConfigsRes"
+          + "ponse\"8\202\323\344\223\002)\022\'/v1/{parent=projects/*}/i"
+          + "nstanceConfigs\332A\006parent\022\271\001\n\021GetInstanceC"
+          + "onfig\022:.google.spanner.admin.instance.v1"
+          + ".GetInstanceConfigRequest\0320.google.spann"
+          + "er.admin.instance.v1.InstanceConfig\"6\202\323\344"
+          + "\223\002)\022\'/v1/{name=projects/*/instanceConfig"
+          + "s/*}\332A\004name\022\264\001\n\rListInstances\0226.google.s"
+          + "panner.admin.instance.v1.ListInstancesRe"
+          + "quest\0327.google.spanner.admin.instance.v1"
+          + ".ListInstancesResponse\"2\202\323\344\223\002#\022!/v1/{par"
+          + "ent=projects/*}/instances\332A\006parent\022\241\001\n\013G"
+          + "etInstance\0224.google.spanner.admin.instan"
+          + "ce.v1.GetInstanceRequest\032*.google.spanne"
+          + "r.admin.instance.v1.Instance\"0\202\323\344\223\002#\022!/v"
+          + "1/{name=projects/*/instances/*}\332A\004name\022\234"
+          + "\002\n\016CreateInstance\0227.google.spanner.admin"
+          + ".instance.v1.CreateInstanceRequest\032\035.goo"
+          + "gle.longrunning.Operation\"\261\001\202\323\344\223\002&\"!/v1/"
+          + "{parent=projects/*}/instances:\001*\332A\033paren"
+          + "t,instance_id,instance\312Ad\n)google.spanne"
+          + "r.admin.instance.v1.Instance\0227google.spa"
+          + "nner.admin.instance.v1.CreateInstanceMet"
+          + "adata\022\235\002\n\016UpdateInstance\0227.google.spanne"
+          + "r.admin.instance.v1.UpdateInstanceReques"
+          + "t\032\035.google.longrunning.Operation\"\262\001\202\323\344\223\002"
+          + "/2*/v1/{instance.name=projects/*/instanc"
+          + "es/*}:\001*\332A\023instance,field_mask\312Ad\n)googl"
+          + "e.spanner.admin.instance.v1.Instance\0227go"
+          + "ogle.spanner.admin.instance.v1.UpdateIns"
+          + "tanceMetadata\022\223\001\n\016DeleteInstance\0227.googl"
+          + "e.spanner.admin.instance.v1.DeleteInstan"
+          + "ceRequest\032\026.google.protobuf.Empty\"0\202\323\344\223\002"
+          + "#*!/v1/{name=projects/*/instances/*}\332A\004n"
+          + "ame\022\232\001\n\014SetIamPolicy\022\".google.iam.v1.Set"
+          + "IamPolicyRequest\032\025.google.iam.v1.Policy\""
+          + "O\202\323\344\223\0027\"2/v1/{resource=projects/*/instan"
+          + "ces/*}:setIamPolicy:\001*\332A\017resource,policy"
+          + "\022\223\001\n\014GetIamPolicy\022\".google.iam.v1.GetIam"
+          + "PolicyRequest\032\025.google.iam.v1.Policy\"H\202\323"
+          + "\344\223\0027\"2/v1/{resource=projects/*/instances"
+          + "/*}:getIamPolicy:\001*\332A\010resource\022\305\001\n\022TestI"
+          + "amPermissions\022(.google.iam.v1.TestIamPer"
+          + "missionsRequest\032).google.iam.v1.TestIamP"
+          + "ermissionsResponse\"Z\202\323\344\223\002=\"8/v1/{resourc"
+          + "e=projects/*/instances/*}:testIamPermiss"
+          + "ions:\001*\332A\024resource,permissions\032x\312A\026spann"
+          + "er.googleapis.com\322A\\https://www.googleap"
+          + "is.com/auth/cloud-platform,https://www.g"
+          + "oogleapis.com/auth/spanner.adminB\215\002\n$com"
+          + ".google.spanner.admin.instance.v1B\031Spann"
+          + "erInstanceAdminProtoP\001ZHgoogle.golang.or"
+          + "g/genproto/googleapis/spanner/admin/inst"
+          + "ance/v1;instance\252\002&Google.Cloud.Spanner."
+          + "Admin.Instance.V1\312\002&Google\\Cloud\\Spanner"
+          + "\\Admin\\Instance\\V1\352\002+Google::Cloud::Span"
+          + "ner::Admin::Instance::V1b\006proto3"
     };
     descriptor =
         com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
@@ -278,6 +280,8 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
               "State",
               "Labels",
               "EndpointUris",
+              "CreateTime",
+              "UpdateTime",
             });
     internal_static_google_spanner_admin_instance_v1_Instance_LabelsEntry_descriptor =
         internal_static_google_spanner_admin_instance_v1_Instance_descriptor
diff --git a/proto-google-cloud-spanner-admin-instance-v1/src/main/proto/google/spanner/admin/instance/v1/spanner_instance_admin.proto b/proto-google-cloud-spanner-admin-instance-v1/src/main/proto/google/spanner/admin/instance/v1/spanner_instance_admin.proto
index 0e6bf63feb0..3bde51d99d5 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/src/main/proto/google/spanner/admin/instance/v1/spanner_instance_admin.proto
+++ b/proto-google-cloud-spanner-admin-instance-v1/src/main/proto/google/spanner/admin/instance/v1/spanner_instance_admin.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -179,7 +179,7 @@ service InstanceAdmin {
   // [Instance][google.spanner.admin.instance.v1.Instance], if successful.
   //
   // Authorization requires `spanner.instances.update` permission on
-  // resource [name][google.spanner.admin.instance.v1.Instance.name].
+  // the resource [name][google.spanner.admin.instance.v1.Instance.name].
   rpc UpdateInstance(UpdateInstanceRequest) returns (google.longrunning.Operation) {
     option (google.api.http) = {
       patch: "/v1/{instance.name=projects/*/instances/*}"
@@ -309,7 +309,7 @@ message InstanceConfig {
 
   // A unique identifier for the instance configuration.  Values
   // are of the form
-  // `projects/<project>/instanceConfigs/[a-z][-a-z0-9]*`
+  // `projects/<project>/instanceConfigs/[a-z][-a-z0-9]*`.
   string name = 1;
 
   // The name of this instance configuration as it appears in UIs.
@@ -319,7 +319,7 @@ message InstanceConfig {
   // replication properties.
   repeated ReplicaInfo replicas = 3;
 
-  // Allowed values of the “default_leader” schema option for databases in
+  // Allowed values of the "default_leader" schema option for databases in
   // instances that use this instance configuration.
   repeated string leader_options = 4;
 }
@@ -367,17 +367,23 @@ message Instance {
   // Must be unique per project and between 4 and 30 characters in length.
   string display_name = 3 [(google.api.field_behavior) = REQUIRED];
 
-  // Required. The number of nodes allocated to this instance. This may be zero
-  // in API responses for instances that are not yet in state `READY`.
+  // The number of nodes allocated to this instance. At most one of either
+  // node_count or processing_units should be present in the message. This
+  // may be zero in API responses for instances that are not yet in state
+  // `READY`.
   //
   // See [the
-  // documentation](https://cloud.google.com/spanner/docs/instances#node_count)
-  // for more information about nodes.
+  // documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+  // for more information about nodes and processing units.
   int32 node_count = 5;
 
   // The number of processing units allocated to this instance. At most one of
   // processing_units or node_count should be present in the message. This may
   // be zero in API responses for instances that are not yet in state `READY`.
+  //
+  // See [the
+  // documentation](https://cloud.google.com/spanner/docs/compute-capacity)
+  // for more information about nodes and processing units.
   int32 processing_units = 9;
 
   // Output only. The current instance state. For
@@ -395,9 +401,9 @@ message Instance {
   // firewall, load balancing, etc.).
   //
   //  * Label keys must be between 1 and 63 characters long and must conform to
-  //    the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
+  //    the following regular expression: `[a-z][a-z0-9_-]{0,62}`.
   //  * Label values must be between 0 and 63 characters long and must conform
-  //    to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
+  //    to the regular expression `[a-z0-9_-]{0,63}`.
   //  * No more than 64 labels can be associated with a given resource.
   //
   // See https://goo.gl/xmQnxf for more information on and examples of labels.
@@ -412,6 +418,12 @@ message Instance {
 
   // Deprecated. This field is not populated.
   repeated string endpoint_uris = 8;
+
+  // Output only. The time at which the instance was created.
+  google.protobuf.Timestamp create_time = 11 [(google.api.field_behavior) = OUTPUT_ONLY];
+
+  // Output only. The time at which the instance was most recently updated.
+  google.protobuf.Timestamp update_time = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
 }
 
 // The request for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs].
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java
index a5744a50a1f..4a16d3a312b 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java
@@ -54,39 +54,37 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
     java.lang.String[] descriptorData = {
       "\n\"google/spanner/v1/result_set.proto\022\021go"
           + "ogle.spanner.v1\032\034google/protobuf/struct."
-          + "proto\032\'google/spanner/v1/commit_response"
-          + ".proto\032\"google/spanner/v1/query_plan.pro"
-          + "to\032#google/spanner/v1/transaction.proto\032"
-          + "\034google/spanner/v1/type.proto\"\237\001\n\tResult"
-          + "Set\0226\n\010metadata\030\001 \001(\0132$.google.spanner.v"
-          + "1.ResultSetMetadata\022(\n\004rows\030\002 \003(\0132\032.goog"
-          + "le.protobuf.ListValue\0220\n\005stats\030\003 \001(\0132!.g"
-          + "oogle.spanner.v1.ResultSetStats\"\321\001\n\020Part"
-          + "ialResultSet\0226\n\010metadata\030\001 \001(\0132$.google."
-          + "spanner.v1.ResultSetMetadata\022&\n\006values\030\002"
-          + " \003(\0132\026.google.protobuf.Value\022\025\n\rchunked_"
-          + "value\030\003 \001(\010\022\024\n\014resume_token\030\004 \001(\014\0220\n\005sta"
-          + "ts\030\005 \001(\0132!.google.spanner.v1.ResultSetSt"
-          + "ats\"y\n\021ResultSetMetadata\022/\n\010row_type\030\001 \001"
-          + "(\0132\035.google.spanner.v1.StructType\0223\n\013tra"
-          + "nsaction\030\002 \001(\0132\036.google.spanner.v1.Trans"
-          + "action\"\271\001\n\016ResultSetStats\0220\n\nquery_plan\030"
-          + "\001 \001(\0132\034.google.spanner.v1.QueryPlan\022,\n\013q"
-          + "uery_stats\030\002 \001(\0132\027.google.protobuf.Struc"
-          + "t\022\031\n\017row_count_exact\030\003 \001(\003H\000\022\037\n\025row_coun"
-          + "t_lower_bound\030\004 \001(\003H\000B\013\n\trow_countB\267\001\n\025c"
-          + "om.google.spanner.v1B\016ResultSetProtoP\001Z8"
-          + "google.golang.org/genproto/googleapis/sp"
-          + "anner/v1;spanner\370\001\001\252\002\027Google.Cloud.Spann"
-          + "er.V1\312\002\027Google\\Cloud\\Spanner\\V1\352\002\032Google"
-          + "::Cloud::Spanner::V1b\006proto3"
+          + "proto\032\"google/spanner/v1/query_plan.prot"
+          + "o\032#google/spanner/v1/transaction.proto\032\034"
+          + "google/spanner/v1/type.proto\"\237\001\n\tResultS"
+          + "et\0226\n\010metadata\030\001 \001(\0132$.google.spanner.v1"
+          + ".ResultSetMetadata\022(\n\004rows\030\002 \003(\0132\032.googl"
+          + "e.protobuf.ListValue\0220\n\005stats\030\003 \001(\0132!.go"
+          + "ogle.spanner.v1.ResultSetStats\"\321\001\n\020Parti"
+          + "alResultSet\0226\n\010metadata\030\001 \001(\0132$.google.s"
+          + "panner.v1.ResultSetMetadata\022&\n\006values\030\002 "
+          + "\003(\0132\026.google.protobuf.Value\022\025\n\rchunked_v"
+          + "alue\030\003 \001(\010\022\024\n\014resume_token\030\004 \001(\014\0220\n\005stat"
+          + "s\030\005 \001(\0132!.google.spanner.v1.ResultSetSta"
+          + "ts\"y\n\021ResultSetMetadata\022/\n\010row_type\030\001 \001("
+          + "\0132\035.google.spanner.v1.StructType\0223\n\013tran"
+          + "saction\030\002 \001(\0132\036.google.spanner.v1.Transa"
+          + "ction\"\271\001\n\016ResultSetStats\0220\n\nquery_plan\030\001"
+          + " \001(\0132\034.google.spanner.v1.QueryPlan\022,\n\013qu"
+          + "ery_stats\030\002 \001(\0132\027.google.protobuf.Struct"
+          + "\022\031\n\017row_count_exact\030\003 \001(\003H\000\022\037\n\025row_count"
+          + "_lower_bound\030\004 \001(\003H\000B\013\n\trow_countB\267\001\n\025co"
+          + "m.google.spanner.v1B\016ResultSetProtoP\001Z8g"
+          + "oogle.golang.org/genproto/googleapis/spa"
+          + "nner/v1;spanner\370\001\001\252\002\027Google.Cloud.Spanne"
+          + "r.V1\312\002\027Google\\Cloud\\Spanner\\V1\352\002\032Google:"
+          + ":Cloud::Spanner::V1b\006proto3"
     };
     descriptor =
         com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
             descriptorData,
             new com.google.protobuf.Descriptors.FileDescriptor[] {
               com.google.protobuf.StructProto.getDescriptor(),
-              com.google.spanner.v1.CommitResponseProto.getDescriptor(),
               com.google.spanner.v1.QueryPlanProto.getDescriptor(),
               com.google.spanner.v1.TransactionProto.getDescriptor(),
               com.google.spanner.v1.TypeProto.getDescriptor(),
@@ -124,7 +122,6 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
               "QueryPlan", "QueryStats", "RowCountExact", "RowCountLowerBound", "RowCount",
             });
     com.google.protobuf.StructProto.getDescriptor();
-    com.google.spanner.v1.CommitResponseProto.getDescriptor();
     com.google.spanner.v1.QueryPlanProto.getDescriptor();
     com.google.spanner.v1.TransactionProto.getDescriptor();
     com.google.spanner.v1.TypeProto.getDescriptor();
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java
index a41708c4f95..d53bd0ad2dd 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/Session.java
@@ -39,6 +39,7 @@ private Session(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
 
   private Session() {
     name_ = "";
+    creatorRole_ = "";
   }
 
   @java.lang.Override
@@ -119,6 +120,13 @@ private Session(
                 approximateLastUseTime_ = subBuilder.buildPartial();
               }
 
+              break;
+            }
+          case 42:
+            {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              creatorRole_ = s;
               break;
             }
           default:
@@ -443,6 +451,55 @@ public com.google.protobuf.TimestampOrBuilder getApproximateLastUseTimeOrBuilder
     return getApproximateLastUseTime();
   }
 
+  public static final int CREATOR_ROLE_FIELD_NUMBER = 5;
+  private volatile java.lang.Object creatorRole_;
+  /**
+   *
+   *
+   * <pre>
+   * The database role which created this session.
+   * </pre>
+   *
+   * <code>string creator_role = 5;</code>
+   *
+   * @return The creatorRole.
+   */
+  @java.lang.Override
+  public java.lang.String getCreatorRole() {
+    java.lang.Object ref = creatorRole_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      creatorRole_ = s;
+      return s;
+    }
+  }
+  /**
+   *
+   *
+   * <pre>
+   * The database role which created this session.
+   * </pre>
+   *
+   * <code>string creator_role = 5;</code>
+   *
+   * @return The bytes for creatorRole.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString getCreatorRoleBytes() {
+    java.lang.Object ref = creatorRole_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b =
+          com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref);
+      creatorRole_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
   private byte memoizedIsInitialized = -1;
 
   @java.lang.Override
@@ -468,6 +525,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io
     if (approximateLastUseTime_ != null) {
       output.writeMessage(4, getApproximateLastUseTime());
     }
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(creatorRole_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, creatorRole_);
+    }
     unknownFields.writeTo(output);
   }
 
@@ -497,6 +557,9 @@ public int getSerializedSize() {
       size +=
           com.google.protobuf.CodedOutputStream.computeMessageSize(4, getApproximateLastUseTime());
     }
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(creatorRole_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, creatorRole_);
+    }
     size += unknownFields.getSerializedSize();
     memoizedSize = size;
     return size;
@@ -522,6 +585,7 @@ public boolean equals(final java.lang.Object obj) {
     if (hasApproximateLastUseTime()) {
       if (!getApproximateLastUseTime().equals(other.getApproximateLastUseTime())) return false;
     }
+    if (!getCreatorRole().equals(other.getCreatorRole())) return false;
     if (!unknownFields.equals(other.unknownFields)) return false;
     return true;
   }
@@ -547,6 +611,8 @@ public int hashCode() {
       hash = (37 * hash) + APPROXIMATE_LAST_USE_TIME_FIELD_NUMBER;
       hash = (53 * hash) + getApproximateLastUseTime().hashCode();
     }
+    hash = (37 * hash) + CREATOR_ROLE_FIELD_NUMBER;
+    hash = (53 * hash) + getCreatorRole().hashCode();
     hash = (29 * hash) + unknownFields.hashCode();
     memoizedHashCode = hash;
     return hash;
@@ -725,6 +791,8 @@ public Builder clear() {
         approximateLastUseTime_ = null;
         approximateLastUseTimeBuilder_ = null;
       }
+      creatorRole_ = "";
+
       return this;
     }
 
@@ -765,6 +833,7 @@ public com.google.spanner.v1.Session buildPartial() {
       } else {
         result.approximateLastUseTime_ = approximateLastUseTimeBuilder_.build();
       }
+      result.creatorRole_ = creatorRole_;
       onBuilt();
       return result;
     }
@@ -825,6 +894,10 @@ public Builder mergeFrom(com.google.spanner.v1.Session other) {
       if (other.hasApproximateLastUseTime()) {
         mergeApproximateLastUseTime(other.getApproximateLastUseTime());
       }
+      if (!other.getCreatorRole().isEmpty()) {
+        creatorRole_ = other.creatorRole_;
+        onChanged();
+      }
       this.mergeUnknownFields(other.unknownFields);
       onChanged();
       return this;
@@ -1576,6 +1649,112 @@ public com.google.protobuf.TimestampOrBuilder getApproximateLastUseTimeOrBuilder
       return approximateLastUseTimeBuilder_;
     }
 
+    private java.lang.Object creatorRole_ = "";
+    /**
+     *
+     *
+     * <pre>
+     * The database role which created this session.
+     * </pre>
+     *
+     * <code>string creator_role = 5;</code>
+     *
+     * @return The creatorRole.
+     */
+    public java.lang.String getCreatorRole() {
+      java.lang.Object ref = creatorRole_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        creatorRole_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     *
+     *
+     * <pre>
+     * The database role which created this session.
+     * </pre>
+     *
+     * <code>string creator_role = 5;</code>
+     *
+     * @return The bytes for creatorRole.
+     */
+    public com.google.protobuf.ByteString getCreatorRoleBytes() {
+      java.lang.Object ref = creatorRole_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b =
+            com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref);
+        creatorRole_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     *
+     *
+     * <pre>
+     * The database role which created this session.
+     * </pre>
+     *
+     * <code>string creator_role = 5;</code>
+     *
+     * @param value The creatorRole to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCreatorRole(java.lang.String value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+
+      creatorRole_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * The database role which created this session.
+     * </pre>
+     *
+     * <code>string creator_role = 5;</code>
+     *
+     * @return This builder for chaining.
+     */
+    public Builder clearCreatorRole() {
+
+      creatorRole_ = getDefaultInstance().getCreatorRole();
+      onChanged();
+      return this;
+    }
+    /**
+     *
+     *
+     * <pre>
+     * The database role which created this session.
+     * </pre>
+     *
+     * <code>string creator_role = 5;</code>
+     *
+     * @param value The bytes for creatorRole to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCreatorRoleBytes(com.google.protobuf.ByteString value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      checkByteStringIsUtf8(value);
+
+      creatorRole_ = value;
+      onChanged();
+      return this;
+    }
+
     @java.lang.Override
     public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
       return super.setUnknownFields(unknownFields);
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java
index f25619e848e..b0b8accd8ca 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SessionOrBuilder.java
@@ -218,4 +218,29 @@ java.lang.String getLabelsOrDefault(
    * </code>
    */
   com.google.protobuf.TimestampOrBuilder getApproximateLastUseTimeOrBuilder();
+
+  /**
+   *
+   *
+   * <pre>
+   * The database role which created this session.
+   * </pre>
+   *
+   * <code>string creator_role = 5;</code>
+   *
+   * @return The creatorRole.
+   */
+  java.lang.String getCreatorRole();
+  /**
+   *
+   *
+   * <pre>
+   * The database role which created this session.
+   * </pre>
+   *
+   * <code>string creator_role = 5;</code>
+   *
+   * @return The bytes for creatorRole.
+   */
+  com.google.protobuf.ByteString getCreatorRoleBytes();
 }
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java
index 440f749d535..21c752c5631 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java
@@ -165,195 +165,196 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
           + "session_template\030\002 \001(\0132\032.google.spanner."
           + "v1.Session\022\032\n\rsession_count\030\003 \001(\005B\003\340A\002\"J"
           + "\n\033BatchCreateSessionsResponse\022+\n\007session"
-          + "\030\001 \003(\0132\032.google.spanner.v1.Session\"\363\002\n\007S"
+          + "\030\001 \003(\0132\032.google.spanner.v1.Session\"\211\003\n\007S"
           + "ession\022\021\n\004name\030\001 \001(\tB\003\340A\003\0226\n\006labels\030\002 \003("
           + "\0132&.google.spanner.v1.Session.LabelsEntr"
           + "y\0224\n\013create_time\030\003 \001(\0132\032.google.protobuf"
           + ".TimestampB\003\340A\003\022B\n\031approximate_last_use_"
           + "time\030\004 \001(\0132\032.google.protobuf.TimestampB\003"
-          + "\340A\003\032-\n\013LabelsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value"
-          + "\030\002 \001(\t:\0028\001:t\352Aq\n\036spanner.googleapis.com/"
-          + "Session\022Oprojects/{project}/instances/{i"
-          + "nstance}/databases/{database}/sessions/{"
-          + "session}\"I\n\021GetSessionRequest\0224\n\004name\030\001 "
-          + "\001(\tB&\340A\002\372A \n\036spanner.googleapis.com/Sess"
-          + "ion\"\207\001\n\023ListSessionsRequest\0229\n\010database\030"
-          + "\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleapis.com/Da"
-          + "tabase\022\021\n\tpage_size\030\002 \001(\005\022\022\n\npage_token\030"
-          + "\003 \001(\t\022\016\n\006filter\030\004 \001(\t\"]\n\024ListSessionsRes"
-          + "ponse\022,\n\010sessions\030\001 \003(\0132\032.google.spanner"
-          + ".v1.Session\022\027\n\017next_page_token\030\002 \001(\t\"L\n\024"
-          + "DeleteSessionRequest\0224\n\004name\030\001 \001(\tB&\340A\002\372"
-          + "A \n\036spanner.googleapis.com/Session\"\334\001\n\016R"
-          + "equestOptions\022<\n\010priority\030\001 \001(\0162*.google"
-          + ".spanner.v1.RequestOptions.Priority\022\023\n\013r"
-          + "equest_tag\030\002 \001(\t\022\027\n\017transaction_tag\030\003 \001("
-          + "\t\"^\n\010Priority\022\030\n\024PRIORITY_UNSPECIFIED\020\000\022"
-          + "\020\n\014PRIORITY_LOW\020\001\022\023\n\017PRIORITY_MEDIUM\020\002\022\021"
-          + "\n\rPRIORITY_HIGH\020\003\"\344\005\n\021ExecuteSqlRequest\022"
+          + "\340A\003\022\024\n\014creator_role\030\005 \001(\t\032-\n\013LabelsEntry"
+          + "\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001:t\352Aq\n\036s"
+          + "panner.googleapis.com/Session\022Oprojects/"
+          + "{project}/instances/{instance}/databases"
+          + "/{database}/sessions/{session}\"I\n\021GetSes"
+          + "sionRequest\0224\n\004name\030\001 \001(\tB&\340A\002\372A \n\036spann"
+          + "er.googleapis.com/Session\"\207\001\n\023ListSessio"
+          + "nsRequest\0229\n\010database\030\001 \001(\tB\'\340A\002\372A!\n\037spa"
+          + "nner.googleapis.com/Database\022\021\n\tpage_siz"
+          + "e\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\022\016\n\006filter\030\004 "
+          + "\001(\t\"]\n\024ListSessionsResponse\022,\n\010sessions\030"
+          + "\001 \003(\0132\032.google.spanner.v1.Session\022\027\n\017nex"
+          + "t_page_token\030\002 \001(\t\"L\n\024DeleteSessionReque"
+          + "st\0224\n\004name\030\001 \001(\tB&\340A\002\372A \n\036spanner.google"
+          + "apis.com/Session\"\334\001\n\016RequestOptions\022<\n\010p"
+          + "riority\030\001 \001(\0162*.google.spanner.v1.Reques"
+          + "tOptions.Priority\022\023\n\013request_tag\030\002 \001(\t\022\027"
+          + "\n\017transaction_tag\030\003 \001(\t\"^\n\010Priority\022\030\n\024P"
+          + "RIORITY_UNSPECIFIED\020\000\022\020\n\014PRIORITY_LOW\020\001\022"
+          + "\023\n\017PRIORITY_MEDIUM\020\002\022\021\n\rPRIORITY_HIGH\020\003\""
+          + "\344\005\n\021ExecuteSqlRequest\0227\n\007session\030\001 \001(\tB&"
+          + "\340A\002\372A \n\036spanner.googleapis.com/Session\022;"
+          + "\n\013transaction\030\002 \001(\0132&.google.spanner.v1."
+          + "TransactionSelector\022\020\n\003sql\030\003 \001(\tB\003\340A\002\022\'\n"
+          + "\006params\030\004 \001(\0132\027.google.protobuf.Struct\022I"
+          + "\n\013param_types\030\005 \003(\01324.google.spanner.v1."
+          + "ExecuteSqlRequest.ParamTypesEntry\022\024\n\014res"
+          + "ume_token\030\006 \001(\014\022B\n\nquery_mode\030\007 \001(\0162..go"
+          + "ogle.spanner.v1.ExecuteSqlRequest.QueryM"
+          + "ode\022\027\n\017partition_token\030\010 \001(\014\022\r\n\005seqno\030\t "
+          + "\001(\003\022H\n\rquery_options\030\n \001(\01321.google.span"
+          + "ner.v1.ExecuteSqlRequest.QueryOptions\022:\n"
+          + "\017request_options\030\013 \001(\0132!.google.spanner."
+          + "v1.RequestOptions\032O\n\014QueryOptions\022\031\n\021opt"
+          + "imizer_version\030\001 \001(\t\022$\n\034optimizer_statis"
+          + "tics_package\030\002 \001(\t\032J\n\017ParamTypesEntry\022\013\n"
+          + "\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.google.spann"
+          + "er.v1.Type:\0028\001\".\n\tQueryMode\022\n\n\006NORMAL\020\000\022"
+          + "\010\n\004PLAN\020\001\022\013\n\007PROFILE\020\002\"\240\004\n\026ExecuteBatchD"
+          + "mlRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036span"
+          + "ner.googleapis.com/Session\022@\n\013transactio"
+          + "n\030\002 \001(\0132&.google.spanner.v1.TransactionS"
+          + "electorB\003\340A\002\022L\n\nstatements\030\003 \003(\01323.googl"
+          + "e.spanner.v1.ExecuteBatchDmlRequest.Stat"
+          + "ementB\003\340A\002\022\022\n\005seqno\030\004 \001(\003B\003\340A\002\022:\n\017reques"
+          + "t_options\030\005 \001(\0132!.google.spanner.v1.Requ"
+          + "estOptions\032\354\001\n\tStatement\022\020\n\003sql\030\001 \001(\tB\003\340"
+          + "A\002\022\'\n\006params\030\002 \001(\0132\027.google.protobuf.Str"
+          + "uct\022X\n\013param_types\030\003 \003(\0132C.google.spanne"
+          + "r.v1.ExecuteBatchDmlRequest.Statement.Pa"
+          + "ramTypesEntry\032J\n\017ParamTypesEntry\022\013\n\003key\030"
+          + "\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.google.spanner.v1"
+          + ".Type:\0028\001\"p\n\027ExecuteBatchDmlResponse\0221\n\013"
+          + "result_sets\030\001 \003(\0132\034.google.spanner.v1.Re"
+          + "sultSet\022\"\n\006status\030\002 \001(\0132\022.google.rpc.Sta"
+          + "tus\"H\n\020PartitionOptions\022\034\n\024partition_siz"
+          + "e_bytes\030\001 \001(\003\022\026\n\016max_partitions\030\002 \001(\003\"\243\003"
+          + "\n\025PartitionQueryRequest\0227\n\007session\030\001 \001(\t"
+          + "B&\340A\002\372A \n\036spanner.googleapis.com/Session"
+          + "\022;\n\013transaction\030\002 \001(\0132&.google.spanner.v"
+          + "1.TransactionSelector\022\020\n\003sql\030\003 \001(\tB\003\340A\002\022"
+          + "\'\n\006params\030\004 \001(\0132\027.google.protobuf.Struct"
+          + "\022M\n\013param_types\030\005 \003(\01328.google.spanner.v"
+          + "1.PartitionQueryRequest.ParamTypesEntry\022"
+          + ">\n\021partition_options\030\006 \001(\0132#.google.span"
+          + "ner.v1.PartitionOptions\032J\n\017ParamTypesEnt"
+          + "ry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.google."
+          + "spanner.v1.Type:\0028\001\"\261\002\n\024PartitionReadReq"
+          + "uest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.g"
+          + "oogleapis.com/Session\022;\n\013transaction\030\002 \001"
+          + "(\0132&.google.spanner.v1.TransactionSelect"
+          + "or\022\022\n\005table\030\003 \001(\tB\003\340A\002\022\r\n\005index\030\004 \001(\t\022\017\n"
+          + "\007columns\030\005 \003(\t\022/\n\007key_set\030\006 \001(\0132\031.google"
+          + ".spanner.v1.KeySetB\003\340A\002\022>\n\021partition_opt"
+          + "ions\030\t \001(\0132#.google.spanner.v1.Partition"
+          + "Options\"$\n\tPartition\022\027\n\017partition_token\030"
+          + "\001 \001(\014\"z\n\021PartitionResponse\0220\n\npartitions"
+          + "\030\001 \003(\0132\034.google.spanner.v1.Partition\0223\n\013"
+          + "transaction\030\002 \001(\0132\036.google.spanner.v1.Tr"
+          + "ansaction\"\347\002\n\013ReadRequest\0227\n\007session\030\001 \001"
+          + "(\tB&\340A\002\372A \n\036spanner.googleapis.com/Sessi"
+          + "on\022;\n\013transaction\030\002 \001(\0132&.google.spanner"
+          + ".v1.TransactionSelector\022\022\n\005table\030\003 \001(\tB\003"
+          + "\340A\002\022\r\n\005index\030\004 \001(\t\022\024\n\007columns\030\005 \003(\tB\003\340A\002"
+          + "\022/\n\007key_set\030\006 \001(\0132\031.google.spanner.v1.Ke"
+          + "ySetB\003\340A\002\022\r\n\005limit\030\010 \001(\003\022\024\n\014resume_token"
+          + "\030\t \001(\014\022\027\n\017partition_token\030\n \001(\014\022:\n\017reque"
+          + "st_options\030\013 \001(\0132!.google.spanner.v1.Req"
+          + "uestOptions\"\313\001\n\027BeginTransactionRequest\022"
           + "7\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.google"
-          + "apis.com/Session\022;\n\013transaction\030\002 \001(\0132&."
-          + "google.spanner.v1.TransactionSelector\022\020\n"
-          + "\003sql\030\003 \001(\tB\003\340A\002\022\'\n\006params\030\004 \001(\0132\027.google"
-          + ".protobuf.Struct\022I\n\013param_types\030\005 \003(\01324."
-          + "google.spanner.v1.ExecuteSqlRequest.Para"
-          + "mTypesEntry\022\024\n\014resume_token\030\006 \001(\014\022B\n\nque"
-          + "ry_mode\030\007 \001(\0162..google.spanner.v1.Execut"
-          + "eSqlRequest.QueryMode\022\027\n\017partition_token"
-          + "\030\010 \001(\014\022\r\n\005seqno\030\t \001(\003\022H\n\rquery_options\030\n"
-          + " \001(\01321.google.spanner.v1.ExecuteSqlReque"
-          + "st.QueryOptions\022:\n\017request_options\030\013 \001(\013"
-          + "2!.google.spanner.v1.RequestOptions\032O\n\014Q"
-          + "ueryOptions\022\031\n\021optimizer_version\030\001 \001(\t\022$"
-          + "\n\034optimizer_statistics_package\030\002 \001(\t\032J\n\017"
-          + "ParamTypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 "
-          + "\001(\0132\027.google.spanner.v1.Type:\0028\001\".\n\tQuer"
-          + "yMode\022\n\n\006NORMAL\020\000\022\010\n\004PLAN\020\001\022\013\n\007PROFILE\020\002"
-          + "\"\240\004\n\026ExecuteBatchDmlRequest\0227\n\007session\030\001"
-          + " \001(\tB&\340A\002\372A \n\036spanner.googleapis.com/Ses"
-          + "sion\022@\n\013transaction\030\002 \001(\0132&.google.spann"
-          + "er.v1.TransactionSelectorB\003\340A\002\022L\n\nstatem"
-          + "ents\030\003 \003(\01323.google.spanner.v1.ExecuteBa"
-          + "tchDmlRequest.StatementB\003\340A\002\022\022\n\005seqno\030\004 "
-          + "\001(\003B\003\340A\002\022:\n\017request_options\030\005 \001(\0132!.goog"
-          + "le.spanner.v1.RequestOptions\032\354\001\n\tStateme"
-          + "nt\022\020\n\003sql\030\001 \001(\tB\003\340A\002\022\'\n\006params\030\002 \001(\0132\027.g"
-          + "oogle.protobuf.Struct\022X\n\013param_types\030\003 \003"
-          + "(\0132C.google.spanner.v1.ExecuteBatchDmlRe"
-          + "quest.Statement.ParamTypesEntry\032J\n\017Param"
-          + "TypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027"
-          + ".google.spanner.v1.Type:\0028\001\"p\n\027ExecuteBa"
-          + "tchDmlResponse\0221\n\013result_sets\030\001 \003(\0132\034.go"
-          + "ogle.spanner.v1.ResultSet\022\"\n\006status\030\002 \001("
-          + "\0132\022.google.rpc.Status\"H\n\020PartitionOption"
-          + "s\022\034\n\024partition_size_bytes\030\001 \001(\003\022\026\n\016max_p"
-          + "artitions\030\002 \001(\003\"\243\003\n\025PartitionQueryReques"
-          + "t\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.goog"
-          + "leapis.com/Session\022;\n\013transaction\030\002 \001(\0132"
-          + "&.google.spanner.v1.TransactionSelector\022"
-          + "\020\n\003sql\030\003 \001(\tB\003\340A\002\022\'\n\006params\030\004 \001(\0132\027.goog"
-          + "le.protobuf.Struct\022M\n\013param_types\030\005 \003(\0132"
-          + "8.google.spanner.v1.PartitionQueryReques"
-          + "t.ParamTypesEntry\022>\n\021partition_options\030\006"
-          + " \001(\0132#.google.spanner.v1.PartitionOption"
-          + "s\032J\n\017ParamTypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005val"
-          + "ue\030\002 \001(\0132\027.google.spanner.v1.Type:\0028\001\"\261\002"
-          + "\n\024PartitionReadRequest\0227\n\007session\030\001 \001(\tB"
-          + "&\340A\002\372A \n\036spanner.googleapis.com/Session\022"
-          + ";\n\013transaction\030\002 \001(\0132&.google.spanner.v1"
-          + ".TransactionSelector\022\022\n\005table\030\003 \001(\tB\003\340A\002"
-          + "\022\r\n\005index\030\004 \001(\t\022\017\n\007columns\030\005 \003(\t\022/\n\007key_"
-          + "set\030\006 \001(\0132\031.google.spanner.v1.KeySetB\003\340A"
-          + "\002\022>\n\021partition_options\030\t \001(\0132#.google.sp"
-          + "anner.v1.PartitionOptions\"$\n\tPartition\022\027"
-          + "\n\017partition_token\030\001 \001(\014\"z\n\021PartitionResp"
-          + "onse\0220\n\npartitions\030\001 \003(\0132\034.google.spanne"
-          + "r.v1.Partition\0223\n\013transaction\030\002 \001(\0132\036.go"
-          + "ogle.spanner.v1.Transaction\"\347\002\n\013ReadRequ"
-          + "est\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.go"
-          + "ogleapis.com/Session\022;\n\013transaction\030\002 \001("
-          + "\0132&.google.spanner.v1.TransactionSelecto"
-          + "r\022\022\n\005table\030\003 \001(\tB\003\340A\002\022\r\n\005index\030\004 \001(\t\022\024\n\007"
-          + "columns\030\005 \003(\tB\003\340A\002\022/\n\007key_set\030\006 \001(\0132\031.go"
-          + "ogle.spanner.v1.KeySetB\003\340A\002\022\r\n\005limit\030\010 \001"
-          + "(\003\022\024\n\014resume_token\030\t \001(\014\022\027\n\017partition_to"
-          + "ken\030\n \001(\014\022:\n\017request_options\030\013 \001(\0132!.goo"
-          + "gle.spanner.v1.RequestOptions\"\313\001\n\027BeginT"
-          + "ransactionRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372"
-          + "A \n\036spanner.googleapis.com/Session\022;\n\007op"
-          + "tions\030\002 \001(\0132%.google.spanner.v1.Transact"
-          + "ionOptionsB\003\340A\002\022:\n\017request_options\030\003 \001(\013"
-          + "2!.google.spanner.v1.RequestOptions\"\303\002\n\r"
-          + "CommitRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036"
-          + "spanner.googleapis.com/Session\022\030\n\016transa"
-          + "ction_id\030\002 \001(\014H\000\022G\n\026single_use_transacti"
-          + "on\030\003 \001(\0132%.google.spanner.v1.Transaction"
-          + "OptionsH\000\022.\n\tmutations\030\004 \003(\0132\033.google.sp"
-          + "anner.v1.Mutation\022\033\n\023return_commit_stats"
-          + "\030\005 \001(\010\022:\n\017request_options\030\006 \001(\0132!.google"
-          + ".spanner.v1.RequestOptionsB\r\n\013transactio"
-          + "n\"g\n\017RollbackRequest\0227\n\007session\030\001 \001(\tB&\340"
-          + "A\002\372A \n\036spanner.googleapis.com/Session\022\033\n"
-          + "\016transaction_id\030\002 \001(\014B\003\340A\0022\300\026\n\007Spanner\022\246"
-          + "\001\n\rCreateSession\022\'.google.spanner.v1.Cre"
-          + "ateSessionRequest\032\032.google.spanner.v1.Se"
-          + "ssion\"P\202\323\344\223\002?\":/v1/{database=projects/*/"
-          + "instances/*/databases/*}/sessions:\001*\332A\010d"
-          + "atabase\022\340\001\n\023BatchCreateSessions\022-.google"
-          + ".spanner.v1.BatchCreateSessionsRequest\032."
-          + ".google.spanner.v1.BatchCreateSessionsRe"
-          + "sponse\"j\202\323\344\223\002K\"F/v1/{database=projects/*"
-          + "/instances/*/databases/*}/sessions:batch"
-          + "Create:\001*\332A\026database,session_count\022\227\001\n\nG"
-          + "etSession\022$.google.spanner.v1.GetSession"
-          + "Request\032\032.google.spanner.v1.Session\"G\202\323\344"
-          + "\223\002:\0228/v1/{name=projects/*/instances/*/da"
-          + "tabases/*/sessions/*}\332A\004name\022\256\001\n\014ListSes"
-          + "sions\022&.google.spanner.v1.ListSessionsRe"
-          + "quest\032\'.google.spanner.v1.ListSessionsRe"
-          + "sponse\"M\202\323\344\223\002<\022:/v1/{database=projects/*"
-          + "/instances/*/databases/*}/sessions\332A\010dat"
-          + "abase\022\231\001\n\rDeleteSession\022\'.google.spanner"
-          + ".v1.DeleteSessionRequest\032\026.google.protob"
-          + "uf.Empty\"G\202\323\344\223\002:*8/v1/{name=projects/*/i"
-          + "nstances/*/databases/*/sessions/*}\332A\004nam"
-          + "e\022\243\001\n\nExecuteSql\022$.google.spanner.v1.Exe"
-          + "cuteSqlRequest\032\034.google.spanner.v1.Resul"
-          + "tSet\"Q\202\323\344\223\002K\"F/v1/{session=projects/*/in"
-          + "stances/*/databases/*/sessions/*}:execut"
-          + "eSql:\001*\022\276\001\n\023ExecuteStreamingSql\022$.google"
-          + ".spanner.v1.ExecuteSqlRequest\032#.google.s"
-          + "panner.v1.PartialResultSet\"Z\202\323\344\223\002T\"O/v1/"
+          + "apis.com/Session\022;\n\007options\030\002 \001(\0132%.goog"
+          + "le.spanner.v1.TransactionOptionsB\003\340A\002\022:\n"
+          + "\017request_options\030\003 \001(\0132!.google.spanner."
+          + "v1.RequestOptions\"\303\002\n\rCommitRequest\0227\n\007s"
+          + "ession\030\001 \001(\tB&\340A\002\372A \n\036spanner.googleapis"
+          + ".com/Session\022\030\n\016transaction_id\030\002 \001(\014H\000\022G"
+          + "\n\026single_use_transaction\030\003 \001(\0132%.google."
+          + "spanner.v1.TransactionOptionsH\000\022.\n\tmutat"
+          + "ions\030\004 \003(\0132\033.google.spanner.v1.Mutation\022"
+          + "\033\n\023return_commit_stats\030\005 \001(\010\022:\n\017request_"
+          + "options\030\006 \001(\0132!.google.spanner.v1.Reques"
+          + "tOptionsB\r\n\013transaction\"g\n\017RollbackReque"
+          + "st\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.goo"
+          + "gleapis.com/Session\022\033\n\016transaction_id\030\002 "
+          + "\001(\014B\003\340A\0022\300\026\n\007Spanner\022\246\001\n\rCreateSession\022\'"
+          + ".google.spanner.v1.CreateSessionRequest\032"
+          + "\032.google.spanner.v1.Session\"P\202\323\344\223\002?\":/v1"
+          + "/{database=projects/*/instances/*/databa"
+          + "ses/*}/sessions:\001*\332A\010database\022\340\001\n\023BatchC"
+          + "reateSessions\022-.google.spanner.v1.BatchC"
+          + "reateSessionsRequest\032..google.spanner.v1"
+          + ".BatchCreateSessionsResponse\"j\202\323\344\223\002K\"F/v"
+          + "1/{database=projects/*/instances/*/datab"
+          + "ases/*}/sessions:batchCreate:\001*\332A\026databa"
+          + "se,session_count\022\227\001\n\nGetSession\022$.google"
+          + ".spanner.v1.GetSessionRequest\032\032.google.s"
+          + "panner.v1.Session\"G\202\323\344\223\002:\0228/v1/{name=pro"
+          + "jects/*/instances/*/databases/*/sessions"
+          + "/*}\332A\004name\022\256\001\n\014ListSessions\022&.google.spa"
+          + "nner.v1.ListSessionsRequest\032\'.google.spa"
+          + "nner.v1.ListSessionsResponse\"M\202\323\344\223\002<\022:/v"
+          + "1/{database=projects/*/instances/*/datab"
+          + "ases/*}/sessions\332A\010database\022\231\001\n\rDeleteSe"
+          + "ssion\022\'.google.spanner.v1.DeleteSessionR"
+          + "equest\032\026.google.protobuf.Empty\"G\202\323\344\223\002:*8"
+          + "/v1/{name=projects/*/instances/*/databas"
+          + "es/*/sessions/*}\332A\004name\022\243\001\n\nExecuteSql\022$"
+          + ".google.spanner.v1.ExecuteSqlRequest\032\034.g"
+          + "oogle.spanner.v1.ResultSet\"Q\202\323\344\223\002K\"F/v1/"
           + "{session=projects/*/instances/*/database"
-          + "s/*/sessions/*}:executeStreamingSql:\001*0\001"
-          + "\022\300\001\n\017ExecuteBatchDml\022).google.spanner.v1"
-          + ".ExecuteBatchDmlRequest\032*.google.spanner"
-          + ".v1.ExecuteBatchDmlResponse\"V\202\323\344\223\002P\"K/v1"
-          + "/{session=projects/*/instances/*/databas"
-          + "es/*/sessions/*}:executeBatchDml:\001*\022\221\001\n\004"
-          + "Read\022\036.google.spanner.v1.ReadRequest\032\034.g"
-          + "oogle.spanner.v1.ResultSet\"K\202\323\344\223\002E\"@/v1/"
-          + "{session=projects/*/instances/*/database"
-          + "s/*/sessions/*}:read:\001*\022\254\001\n\rStreamingRea"
-          + "d\022\036.google.spanner.v1.ReadRequest\032#.goog"
-          + "le.spanner.v1.PartialResultSet\"T\202\323\344\223\002N\"I"
-          + "/v1/{session=projects/*/instances/*/data"
-          + "bases/*/sessions/*}:streamingRead:\001*0\001\022\311"
-          + "\001\n\020BeginTransaction\022*.google.spanner.v1."
-          + "BeginTransactionRequest\032\036.google.spanner"
-          + ".v1.Transaction\"i\202\323\344\223\002Q\"L/v1/{session=pr"
+          + "s/*/sessions/*}:executeSql:\001*\022\276\001\n\023Execut"
+          + "eStreamingSql\022$.google.spanner.v1.Execut"
+          + "eSqlRequest\032#.google.spanner.v1.PartialR"
+          + "esultSet\"Z\202\323\344\223\002T\"O/v1/{session=projects/"
+          + "*/instances/*/databases/*/sessions/*}:ex"
+          + "ecuteStreamingSql:\001*0\001\022\300\001\n\017ExecuteBatchD"
+          + "ml\022).google.spanner.v1.ExecuteBatchDmlRe"
+          + "quest\032*.google.spanner.v1.ExecuteBatchDm"
+          + "lResponse\"V\202\323\344\223\002P\"K/v1/{session=projects"
+          + "/*/instances/*/databases/*/sessions/*}:e"
+          + "xecuteBatchDml:\001*\022\221\001\n\004Read\022\036.google.span"
+          + "ner.v1.ReadRequest\032\034.google.spanner.v1.R"
+          + "esultSet\"K\202\323\344\223\002E\"@/v1/{session=projects/"
+          + "*/instances/*/databases/*/sessions/*}:re"
+          + "ad:\001*\022\254\001\n\rStreamingRead\022\036.google.spanner"
+          + ".v1.ReadRequest\032#.google.spanner.v1.Part"
+          + "ialResultSet\"T\202\323\344\223\002N\"I/v1/{session=proje"
+          + "cts/*/instances/*/databases/*/sessions/*"
+          + "}:streamingRead:\001*0\001\022\311\001\n\020BeginTransactio"
+          + "n\022*.google.spanner.v1.BeginTransactionRe"
+          + "quest\032\036.google.spanner.v1.Transaction\"i\202"
+          + "\323\344\223\002Q\"L/v1/{session=projects/*/instances"
+          + "/*/databases/*/sessions/*}:beginTransact"
+          + "ion:\001*\332A\017session,options\022\353\001\n\006Commit\022 .go"
+          + "ogle.spanner.v1.CommitRequest\032!.google.s"
+          + "panner.v1.CommitResponse\"\233\001\202\323\344\223\002G\"B/v1/{"
+          + "session=projects/*/instances/*/databases"
+          + "/*/sessions/*}:commit:\001*\332A session,trans"
+          + "action_id,mutations\332A(session,single_use"
+          + "_transaction,mutations\022\260\001\n\010Rollback\022\".go"
+          + "ogle.spanner.v1.RollbackRequest\032\026.google"
+          + ".protobuf.Empty\"h\202\323\344\223\002I\"D/v1/{session=pr"
           + "ojects/*/instances/*/databases/*/session"
-          + "s/*}:beginTransaction:\001*\332A\017session,optio"
-          + "ns\022\353\001\n\006Commit\022 .google.spanner.v1.Commit"
-          + "Request\032!.google.spanner.v1.CommitRespon"
-          + "se\"\233\001\202\323\344\223\002G\"B/v1/{session=projects/*/ins"
-          + "tances/*/databases/*/sessions/*}:commit:"
-          + "\001*\332A session,transaction_id,mutations\332A("
-          + "session,single_use_transaction,mutations"
-          + "\022\260\001\n\010Rollback\022\".google.spanner.v1.Rollba"
-          + "ckRequest\032\026.google.protobuf.Empty\"h\202\323\344\223\002"
-          + "I\"D/v1/{session=projects/*/instances/*/d"
-          + "atabases/*/sessions/*}:rollback:\001*\332A\026ses"
-          + "sion,transaction_id\022\267\001\n\016PartitionQuery\022("
-          + ".google.spanner.v1.PartitionQueryRequest"
-          + "\032$.google.spanner.v1.PartitionResponse\"U"
-          + "\202\323\344\223\002O\"J/v1/{session=projects/*/instance"
-          + "s/*/databases/*/sessions/*}:partitionQue"
-          + "ry:\001*\022\264\001\n\rPartitionRead\022\'.google.spanner"
-          + ".v1.PartitionReadRequest\032$.google.spanne"
-          + "r.v1.PartitionResponse\"T\202\323\344\223\002N\"I/v1/{ses"
-          + "sion=projects/*/instances/*/databases/*/"
-          + "sessions/*}:partitionRead:\001*\032w\312A\026spanner"
-          + ".googleapis.com\322A[https://www.googleapis"
-          + ".com/auth/cloud-platform,https://www.goo"
-          + "gleapis.com/auth/spanner.dataB\224\002\n\025com.go"
-          + "ogle.spanner.v1B\014SpannerProtoP\001Z8google."
-          + "golang.org/genproto/googleapis/spanner/v"
-          + "1;spanner\252\002\027Google.Cloud.Spanner.V1\312\002\027Go"
-          + "ogle\\Cloud\\Spanner\\V1\352\002\032Google::Cloud::S"
-          + "panner::V1\352A_\n\037spanner.googleapis.com/Da"
-          + "tabase\022<projects/{project}/instances/{in"
-          + "stance}/databases/{database}P\010b\006proto3"
+          + "s/*}:rollback:\001*\332A\026session,transaction_i"
+          + "d\022\267\001\n\016PartitionQuery\022(.google.spanner.v1"
+          + ".PartitionQueryRequest\032$.google.spanner."
+          + "v1.PartitionResponse\"U\202\323\344\223\002O\"J/v1/{sessi"
+          + "on=projects/*/instances/*/databases/*/se"
+          + "ssions/*}:partitionQuery:\001*\022\264\001\n\rPartitio"
+          + "nRead\022\'.google.spanner.v1.PartitionReadR"
+          + "equest\032$.google.spanner.v1.PartitionResp"
+          + "onse\"T\202\323\344\223\002N\"I/v1/{session=projects/*/in"
+          + "stances/*/databases/*/sessions/*}:partit"
+          + "ionRead:\001*\032w\312A\026spanner.googleapis.com\322A["
+          + "https://www.googleapis.com/auth/cloud-pl"
+          + "atform,https://www.googleapis.com/auth/s"
+          + "panner.dataB\224\002\n\025com.google.spanner.v1B\014S"
+          + "pannerProtoP\001Z8google.golang.org/genprot"
+          + "o/googleapis/spanner/v1;spanner\252\002\027Google"
+          + ".Cloud.Spanner.V1\312\002\027Google\\Cloud\\Spanner"
+          + "\\V1\352\002\032Google::Cloud::Spanner::V1\352A_\n\037spa"
+          + "nner.googleapis.com/Database\022<projects/{"
+          + "project}/instances/{instance}/databases/"
+          + "{database}P\010b\006proto3"
     };
     descriptor =
         com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
@@ -403,7 +404,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
         new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
             internal_static_google_spanner_v1_Session_descriptor,
             new java.lang.String[] {
-              "Name", "Labels", "CreateTime", "ApproximateLastUseTime",
+              "Name", "Labels", "CreateTime", "ApproximateLastUseTime", "CreatorRole",
             });
     internal_static_google_spanner_v1_Session_LabelsEntry_descriptor =
         internal_static_google_spanner_v1_Session_descriptor.getNestedTypes().get(0);
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java
index 9c3fd1a22c8..96997aa83b4 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java
@@ -28,18 +28,24 @@
  * towards the one transaction limit). After the active transaction is
  * completed, the session can immediately be re-used for the next transaction.
  * It is not necessary to create a new session for each transaction.
- * Transaction Modes:
+ * Transaction modes:
  * Cloud Spanner supports three transaction modes:
  *   1. Locking read-write. This type of transaction is the only way
  *      to write data into Cloud Spanner. These transactions rely on
  *      pessimistic locking and, if necessary, two-phase commit.
  *      Locking read-write transactions may abort, requiring the
  *      application to retry.
- *   2. Snapshot read-only. This transaction type provides guaranteed
- *      consistency across several reads, but does not allow
- *      writes. Snapshot read-only transactions can be configured to
- *      read at timestamps in the past. Snapshot read-only
- *      transactions do not need to be committed.
+ *   2. Snapshot read-only. Snapshot read-only transactions provide guaranteed
+ *      consistency across several reads, but do not allow
+ *      writes. Snapshot read-only transactions can be configured to read at
+ *      timestamps in the past, or configured to perform a strong read
+ *      (where Spanner will select a timestamp such that the read is
+ *      guaranteed to see the effects of all transactions that have committed
+ *      before the start of the read). Snapshot read-only transactions do not
+ *      need to be committed.
+ *      Queries on change streams must be performed with the snapshot read-only
+ *      transaction mode, specifying a strong read. Please see
+ *      [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong] for more details.
  *   3. Partitioned DML. This type of transaction is used to execute
  *      a single Partitioned DML statement. Partitioned DML partitions
  *      the key space and runs the DML statement over each partition
@@ -51,10 +57,10 @@
  * particular, read-only transactions do not take locks, so they do
  * not conflict with read-write transactions. As a consequence of not
  * taking locks, they also do not abort, so retry loops are not needed.
- * Transactions may only read/write data in a single database. They
- * may, however, read/write data in different tables within that
+ * Transactions may only read-write data in a single database. They
+ * may, however, read-write data in different tables within that
  * database.
- * Locking Read-Write Transactions:
+ * Locking read-write transactions:
  * Locking transactions may be used to atomically read-modify-write
  * data anywhere in a database. This type of transaction is externally
  * consistent.
@@ -64,7 +70,7 @@
  * active as long as the transaction continues to do reads, and the
  * transaction has not been terminated by
  * [Commit][google.spanner.v1.Spanner.Commit] or
- * [Rollback][google.spanner.v1.Spanner.Rollback].  Long periods of
+ * [Rollback][google.spanner.v1.Spanner.Rollback]. Long periods of
  * inactivity at the client may cause Cloud Spanner to release a
  * transaction's locks and abort it.
  * Conceptually, a read-write transaction consists of zero or more
@@ -83,7 +89,7 @@
  * how long the transaction's locks were held for. It is an error to
  * use Cloud Spanner locks for any sort of mutual exclusion other than
  * between Cloud Spanner transactions themselves.
- * Retrying Aborted Transactions:
+ * Retrying aborted transactions:
  * When a transaction aborts, the application can choose to retry the
  * whole transaction again. To maximize the chances of successfully
  * committing the retry, the client should execute the retry in the
@@ -96,7 +102,7 @@
  * idea to cap the number of retries a transaction can attempt;
  * instead, it is better to limit the total amount of time spent
  * retrying.
- * Idle Transactions:
+ * Idle transactions:
  * A transaction is considered idle if it has no outstanding reads or
  * SQL queries and has not started a read or SQL query within the last 10
  * seconds. Idle transactions can be aborted by Cloud Spanner so that they
@@ -105,7 +111,7 @@
  * If this behavior is undesirable, periodically executing a simple
  * SQL query in the transaction (for example, `SELECT 1`) prevents the
  * transaction from becoming idle.
- * Snapshot Read-Only Transactions:
+ * Snapshot read-only transactions:
  * Snapshot read-only transactions provides a simpler method than
  * locking read-write transactions for doing several consistent
  * reads. However, this type of transaction does not support writes.
@@ -130,11 +136,10 @@
  *   - Exact staleness.
  * If the Cloud Spanner database to be read is geographically distributed,
  * stale read-only transactions can execute more quickly than strong
- * or read-write transaction, because they are able to execute far
+ * or read-write transactions, because they are able to execute far
  * from the leader replica.
  * Each type of timestamp bound is discussed in detail below.
- * Strong:
- * Strong reads are guaranteed to see the effects of all transactions
+ * Strong: Strong reads are guaranteed to see the effects of all transactions
  * that have committed before the start of the read. Furthermore, all
  * rows yielded by a single read are consistent with each other -- if
  * any part of the read observes a transaction, all parts of the read
@@ -144,8 +149,10 @@
  * concurrent writes. If consistency across reads is required, the
  * reads should be executed within a transaction or at an exact read
  * timestamp.
+ * Queries on change streams (see below for more details) must also specify
+ * the strong read timestamp bound.
  * See [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong].
- * Exact Staleness:
+ * Exact staleness:
  * These timestamp bounds execute reads at a user-specified
  * timestamp. Reads at a timestamp are guaranteed to see a consistent
  * prefix of the global transaction history: they observe
@@ -162,7 +169,7 @@
  * boundedly stale reads usually return fresher results.
  * See [TransactionOptions.ReadOnly.read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.read_timestamp] and
  * [TransactionOptions.ReadOnly.exact_staleness][google.spanner.v1.TransactionOptions.ReadOnly.exact_staleness].
- * Bounded Staleness:
+ * Bounded staleness:
  * Bounded staleness modes allow Cloud Spanner to pick the read timestamp,
  * subject to a user-provided staleness bound. Cloud Spanner chooses the
  * newest timestamp within the staleness bound that allows execution
@@ -185,7 +192,7 @@
  * read-only transactions.
  * See [TransactionOptions.ReadOnly.max_staleness][google.spanner.v1.TransactionOptions.ReadOnly.max_staleness] and
  * [TransactionOptions.ReadOnly.min_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.min_read_timestamp].
- * Old Read Timestamps and Garbage Collection:
+ * Old read timestamps and garbage collection:
  * Cloud Spanner continuously garbage collects deleted and overwritten data
  * in the background to reclaim storage space. This process is known
  * as "version GC". By default, version GC reclaims versions after they
@@ -194,7 +201,33 @@
  * restriction also applies to in-progress reads and/or SQL queries whose
  * timestamp become too old while executing. Reads and SQL queries with
  * too-old read timestamps fail with the error `FAILED_PRECONDITION`.
- * Partitioned DML Transactions:
+ * You can configure and extend the `VERSION_RETENTION_PERIOD` of a
+ * database up to a period as long as one week, which allows Cloud Spanner
+ * to perform reads up to one week in the past.
+ * Querying change Streams:
+ * A Change Stream is a schema object that can be configured to watch data
+ * changes on the entire database, a set of tables, or a set of columns
+ * in a database.
+ * When a change stream is created, Spanner automatically defines a
+ * corresponding SQL Table-Valued Function (TVF) that can be used to query
+ * the change records in the associated change stream using the
+ * ExecuteStreamingSql API. The name of the TVF for a change stream is
+ * generated from the name of the change stream: READ_&lt;change_stream_name&gt;.
+ * All queries on change stream TVFs must be executed using the
+ * ExecuteStreamingSql API with a single-use read-only transaction with a
+ * strong read-only timestamp_bound. The change stream TVF allows users to
+ * specify the start_timestamp and end_timestamp for the time range of
+ * interest. All change records within the retention period is accessible
+ * using the strong read-only timestamp_bound. All other TransactionOptions
+ * are invalid for change stream queries.
+ * In addition, if TransactionOptions.read_only.return_read_timestamp is set
+ * to true, a special value of 2^63 - 2 will be returned in the
+ * [Transaction][google.spanner.v1.Transaction] message that describes the
+ * transaction, instead of a valid read timestamp. This special value should be
+ * discarded and not used for any subsequent queries.
+ * Please see https://cloud.google.com/spanner/docs/change-streams
+ * for more details on how to query the change stream TVFs.
+ * Partitioned DML transactions:
  * Partitioned DML transactions are used to execute DML statements with a
  * different execution strategy that provides different, and often better,
  * scalability properties for large, table-wide operations than DML in a
@@ -4374,18 +4407,24 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * towards the one transaction limit). After the active transaction is
    * completed, the session can immediately be re-used for the next transaction.
    * It is not necessary to create a new session for each transaction.
-   * Transaction Modes:
+   * Transaction modes:
    * Cloud Spanner supports three transaction modes:
    *   1. Locking read-write. This type of transaction is the only way
    *      to write data into Cloud Spanner. These transactions rely on
    *      pessimistic locking and, if necessary, two-phase commit.
    *      Locking read-write transactions may abort, requiring the
    *      application to retry.
-   *   2. Snapshot read-only. This transaction type provides guaranteed
-   *      consistency across several reads, but does not allow
-   *      writes. Snapshot read-only transactions can be configured to
-   *      read at timestamps in the past. Snapshot read-only
-   *      transactions do not need to be committed.
+   *   2. Snapshot read-only. Snapshot read-only transactions provide guaranteed
+   *      consistency across several reads, but do not allow
+   *      writes. Snapshot read-only transactions can be configured to read at
+   *      timestamps in the past, or configured to perform a strong read
+   *      (where Spanner will select a timestamp such that the read is
+   *      guaranteed to see the effects of all transactions that have committed
+   *      before the start of the read). Snapshot read-only transactions do not
+   *      need to be committed.
+   *      Queries on change streams must be performed with the snapshot read-only
+   *      transaction mode, specifying a strong read. Please see
+   *      [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong] for more details.
    *   3. Partitioned DML. This type of transaction is used to execute
    *      a single Partitioned DML statement. Partitioned DML partitions
    *      the key space and runs the DML statement over each partition
@@ -4397,10 +4436,10 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * particular, read-only transactions do not take locks, so they do
    * not conflict with read-write transactions. As a consequence of not
    * taking locks, they also do not abort, so retry loops are not needed.
-   * Transactions may only read/write data in a single database. They
-   * may, however, read/write data in different tables within that
+   * Transactions may only read-write data in a single database. They
+   * may, however, read-write data in different tables within that
    * database.
-   * Locking Read-Write Transactions:
+   * Locking read-write transactions:
    * Locking transactions may be used to atomically read-modify-write
    * data anywhere in a database. This type of transaction is externally
    * consistent.
@@ -4410,7 +4449,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * active as long as the transaction continues to do reads, and the
    * transaction has not been terminated by
    * [Commit][google.spanner.v1.Spanner.Commit] or
-   * [Rollback][google.spanner.v1.Spanner.Rollback].  Long periods of
+   * [Rollback][google.spanner.v1.Spanner.Rollback]. Long periods of
    * inactivity at the client may cause Cloud Spanner to release a
    * transaction's locks and abort it.
    * Conceptually, a read-write transaction consists of zero or more
@@ -4429,7 +4468,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * how long the transaction's locks were held for. It is an error to
    * use Cloud Spanner locks for any sort of mutual exclusion other than
    * between Cloud Spanner transactions themselves.
-   * Retrying Aborted Transactions:
+   * Retrying aborted transactions:
    * When a transaction aborts, the application can choose to retry the
    * whole transaction again. To maximize the chances of successfully
    * committing the retry, the client should execute the retry in the
@@ -4442,7 +4481,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * idea to cap the number of retries a transaction can attempt;
    * instead, it is better to limit the total amount of time spent
    * retrying.
-   * Idle Transactions:
+   * Idle transactions:
    * A transaction is considered idle if it has no outstanding reads or
    * SQL queries and has not started a read or SQL query within the last 10
    * seconds. Idle transactions can be aborted by Cloud Spanner so that they
@@ -4451,7 +4490,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * If this behavior is undesirable, periodically executing a simple
    * SQL query in the transaction (for example, `SELECT 1`) prevents the
    * transaction from becoming idle.
-   * Snapshot Read-Only Transactions:
+   * Snapshot read-only transactions:
    * Snapshot read-only transactions provides a simpler method than
    * locking read-write transactions for doing several consistent
    * reads. However, this type of transaction does not support writes.
@@ -4476,11 +4515,10 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    *   - Exact staleness.
    * If the Cloud Spanner database to be read is geographically distributed,
    * stale read-only transactions can execute more quickly than strong
-   * or read-write transaction, because they are able to execute far
+   * or read-write transactions, because they are able to execute far
    * from the leader replica.
    * Each type of timestamp bound is discussed in detail below.
-   * Strong:
-   * Strong reads are guaranteed to see the effects of all transactions
+   * Strong: Strong reads are guaranteed to see the effects of all transactions
    * that have committed before the start of the read. Furthermore, all
    * rows yielded by a single read are consistent with each other -- if
    * any part of the read observes a transaction, all parts of the read
@@ -4490,8 +4528,10 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * concurrent writes. If consistency across reads is required, the
    * reads should be executed within a transaction or at an exact read
    * timestamp.
+   * Queries on change streams (see below for more details) must also specify
+   * the strong read timestamp bound.
    * See [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong].
-   * Exact Staleness:
+   * Exact staleness:
    * These timestamp bounds execute reads at a user-specified
    * timestamp. Reads at a timestamp are guaranteed to see a consistent
    * prefix of the global transaction history: they observe
@@ -4508,7 +4548,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * boundedly stale reads usually return fresher results.
    * See [TransactionOptions.ReadOnly.read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.read_timestamp] and
    * [TransactionOptions.ReadOnly.exact_staleness][google.spanner.v1.TransactionOptions.ReadOnly.exact_staleness].
-   * Bounded Staleness:
+   * Bounded staleness:
    * Bounded staleness modes allow Cloud Spanner to pick the read timestamp,
    * subject to a user-provided staleness bound. Cloud Spanner chooses the
    * newest timestamp within the staleness bound that allows execution
@@ -4531,7 +4571,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * read-only transactions.
    * See [TransactionOptions.ReadOnly.max_staleness][google.spanner.v1.TransactionOptions.ReadOnly.max_staleness] and
    * [TransactionOptions.ReadOnly.min_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.min_read_timestamp].
-   * Old Read Timestamps and Garbage Collection:
+   * Old read timestamps and garbage collection:
    * Cloud Spanner continuously garbage collects deleted and overwritten data
    * in the background to reclaim storage space. This process is known
    * as "version GC". By default, version GC reclaims versions after they
@@ -4540,7 +4580,33 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    * restriction also applies to in-progress reads and/or SQL queries whose
    * timestamp become too old while executing. Reads and SQL queries with
    * too-old read timestamps fail with the error `FAILED_PRECONDITION`.
-   * Partitioned DML Transactions:
+   * You can configure and extend the `VERSION_RETENTION_PERIOD` of a
+   * database up to a period as long as one week, which allows Cloud Spanner
+   * to perform reads up to one week in the past.
+   * Querying change Streams:
+   * A Change Stream is a schema object that can be configured to watch data
+   * changes on the entire database, a set of tables, or a set of columns
+   * in a database.
+   * When a change stream is created, Spanner automatically defines a
+   * corresponding SQL Table-Valued Function (TVF) that can be used to query
+   * the change records in the associated change stream using the
+   * ExecuteStreamingSql API. The name of the TVF for a change stream is
+   * generated from the name of the change stream: READ_&lt;change_stream_name&gt;.
+   * All queries on change stream TVFs must be executed using the
+   * ExecuteStreamingSql API with a single-use read-only transaction with a
+   * strong read-only timestamp_bound. The change stream TVF allows users to
+   * specify the start_timestamp and end_timestamp for the time range of
+   * interest. All change records within the retention period is accessible
+   * using the strong read-only timestamp_bound. All other TransactionOptions
+   * are invalid for change stream queries.
+   * In addition, if TransactionOptions.read_only.return_read_timestamp is set
+   * to true, a special value of 2^63 - 2 will be returned in the
+   * [Transaction][google.spanner.v1.Transaction] message that describes the
+   * transaction, instead of a valid read timestamp. This special value should be
+   * discarded and not used for any subsequent queries.
+   * Please see https://cloud.google.com/spanner/docs/change-streams
+   * for more details on how to query the change stream TVFs.
+   * Partitioned DML transactions:
    * Partitioned DML transactions are used to execute DML statements with a
    * different execution strategy that provides different, and often better,
    * scalability properties for large, table-wide operations than DML in a
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/commit_response.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/commit_response.proto
index d43a83a3206..69e073092f6 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/commit_response.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/commit_response.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/keys.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/keys.proto
index 12495a616ab..df3607aa401 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/keys.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/keys.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/mutation.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/mutation.proto
index ef7e75f8dc8..eae0af72d53 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/mutation.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/mutation.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/query_plan.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/query_plan.proto
index f700014e283..9ea40fe4a1f 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/query_plan.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/query_plan.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto
index 89dfa234653..714d8bea9ea 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ syntax = "proto3";
 package google.spanner.v1;
 
 import "google/protobuf/struct.proto";
-import "google/spanner/v1/commit_response.proto";
 import "google/spanner/v1/query_plan.proto";
 import "google/spanner/v1/transaction.proto";
 import "google/spanner/v1/type.proto";
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto
index 41e2ad83fea..ef772170bf8 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/spanner.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -358,6 +358,9 @@ message Session {
   // Output only. The approximate timestamp when the session is last used. It is
   // typically earlier than the actual last use time.
   google.protobuf.Timestamp approximate_last_use_time = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
+
+  // The database role which created this session.
+  string creator_role = 5;
 }
 
 // The request for [GetSession][google.spanner.v1.Spanner.GetSession].
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto
index 1e4c655ee2c..3577f797cbf 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -35,7 +35,8 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // completed, the session can immediately be re-used for the next transaction.
 // It is not necessary to create a new session for each transaction.
 //
-// Transaction Modes:
+// Transaction modes:
+//
 // Cloud Spanner supports three transaction modes:
 //
 //   1. Locking read-write. This type of transaction is the only way
@@ -44,11 +45,18 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 //      Locking read-write transactions may abort, requiring the
 //      application to retry.
 //
-//   2. Snapshot read-only. This transaction type provides guaranteed
-//      consistency across several reads, but does not allow
-//      writes. Snapshot read-only transactions can be configured to
-//      read at timestamps in the past. Snapshot read-only
-//      transactions do not need to be committed.
+//   2. Snapshot read-only. Snapshot read-only transactions provide guaranteed
+//      consistency across several reads, but do not allow
+//      writes. Snapshot read-only transactions can be configured to read at
+//      timestamps in the past, or configured to perform a strong read
+//      (where Spanner will select a timestamp such that the read is
+//      guaranteed to see the effects of all transactions that have committed
+//      before the start of the read). Snapshot read-only transactions do not
+//      need to be committed.
+//
+//      Queries on change streams must be performed with the snapshot read-only
+//      transaction mode, specifying a strong read. Please see
+//      [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong] for more details.
 //
 //   3. Partitioned DML. This type of transaction is used to execute
 //      a single Partitioned DML statement. Partitioned DML partitions
@@ -63,11 +71,12 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // not conflict with read-write transactions. As a consequence of not
 // taking locks, they also do not abort, so retry loops are not needed.
 //
-// Transactions may only read/write data in a single database. They
-// may, however, read/write data in different tables within that
+// Transactions may only read-write data in a single database. They
+// may, however, read-write data in different tables within that
 // database.
 //
-// Locking Read-Write Transactions:
+// Locking read-write transactions:
+//
 // Locking transactions may be used to atomically read-modify-write
 // data anywhere in a database. This type of transaction is externally
 // consistent.
@@ -78,7 +87,7 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // active as long as the transaction continues to do reads, and the
 // transaction has not been terminated by
 // [Commit][google.spanner.v1.Spanner.Commit] or
-// [Rollback][google.spanner.v1.Spanner.Rollback].  Long periods of
+// [Rollback][google.spanner.v1.Spanner.Rollback]. Long periods of
 // inactivity at the client may cause Cloud Spanner to release a
 // transaction's locks and abort it.
 //
@@ -90,6 +99,7 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // transaction.
 //
 // Semantics:
+//
 // Cloud Spanner can commit the transaction if all read locks it acquired
 // are still valid at commit time, and it is able to acquire write
 // locks for all writes. Cloud Spanner can abort the transaction for any
@@ -101,7 +111,8 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // use Cloud Spanner locks for any sort of mutual exclusion other than
 // between Cloud Spanner transactions themselves.
 //
-// Retrying Aborted Transactions:
+// Retrying aborted transactions:
+//
 // When a transaction aborts, the application can choose to retry the
 // whole transaction again. To maximize the chances of successfully
 // committing the retry, the client should execute the retry in the
@@ -116,7 +127,8 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // instead, it is better to limit the total amount of time spent
 // retrying.
 //
-// Idle Transactions:
+// Idle transactions:
+//
 // A transaction is considered idle if it has no outstanding reads or
 // SQL queries and has not started a read or SQL query within the last 10
 // seconds. Idle transactions can be aborted by Cloud Spanner so that they
@@ -127,7 +139,8 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // SQL query in the transaction (for example, `SELECT 1`) prevents the
 // transaction from becoming idle.
 //
-// Snapshot Read-Only Transactions:
+// Snapshot read-only transactions:
+//
 // Snapshot read-only transactions provides a simpler method than
 // locking read-write transactions for doing several consistent
 // reads. However, this type of transaction does not support writes.
@@ -159,13 +172,12 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 //
 // If the Cloud Spanner database to be read is geographically distributed,
 // stale read-only transactions can execute more quickly than strong
-// or read-write transaction, because they are able to execute far
+// or read-write transactions, because they are able to execute far
 // from the leader replica.
 //
 // Each type of timestamp bound is discussed in detail below.
 //
-// Strong:
-// Strong reads are guaranteed to see the effects of all transactions
+// Strong: Strong reads are guaranteed to see the effects of all transactions
 // that have committed before the start of the read. Furthermore, all
 // rows yielded by a single read are consistent with each other -- if
 // any part of the read observes a transaction, all parts of the read
@@ -177,9 +189,13 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // reads should be executed within a transaction or at an exact read
 // timestamp.
 //
+// Queries on change streams (see below for more details) must also specify
+// the strong read timestamp bound.
+//
 // See [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong].
 //
-// Exact Staleness:
+// Exact staleness:
+//
 // These timestamp bounds execute reads at a user-specified
 // timestamp. Reads at a timestamp are guaranteed to see a consistent
 // prefix of the global transaction history: they observe
@@ -200,7 +216,8 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // See [TransactionOptions.ReadOnly.read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.read_timestamp] and
 // [TransactionOptions.ReadOnly.exact_staleness][google.spanner.v1.TransactionOptions.ReadOnly.exact_staleness].
 //
-// Bounded Staleness:
+// Bounded staleness:
+//
 // Bounded staleness modes allow Cloud Spanner to pick the read timestamp,
 // subject to a user-provided staleness bound. Cloud Spanner chooses the
 // newest timestamp within the staleness bound that allows execution
@@ -229,7 +246,8 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // See [TransactionOptions.ReadOnly.max_staleness][google.spanner.v1.TransactionOptions.ReadOnly.max_staleness] and
 // [TransactionOptions.ReadOnly.min_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.min_read_timestamp].
 //
-// Old Read Timestamps and Garbage Collection:
+// Old read timestamps and garbage collection:
+//
 // Cloud Spanner continuously garbage collects deleted and overwritten data
 // in the background to reclaim storage space. This process is known
 // as "version GC". By default, version GC reclaims versions after they
@@ -239,7 +257,41 @@ option ruby_package = "Google::Cloud::Spanner::V1";
 // timestamp become too old while executing. Reads and SQL queries with
 // too-old read timestamps fail with the error `FAILED_PRECONDITION`.
 //
-// Partitioned DML Transactions:
+// You can configure and extend the `VERSION_RETENTION_PERIOD` of a
+// database up to a period as long as one week, which allows Cloud Spanner
+// to perform reads up to one week in the past.
+//
+// Querying change Streams:
+//
+// A Change Stream is a schema object that can be configured to watch data
+// changes on the entire database, a set of tables, or a set of columns
+// in a database.
+//
+// When a change stream is created, Spanner automatically defines a
+// corresponding SQL Table-Valued Function (TVF) that can be used to query
+// the change records in the associated change stream using the
+// ExecuteStreamingSql API. The name of the TVF for a change stream is
+// generated from the name of the change stream: READ_<change_stream_name>.
+//
+// All queries on change stream TVFs must be executed using the
+// ExecuteStreamingSql API with a single-use read-only transaction with a
+// strong read-only timestamp_bound. The change stream TVF allows users to
+// specify the start_timestamp and end_timestamp for the time range of
+// interest. All change records within the retention period is accessible
+// using the strong read-only timestamp_bound. All other TransactionOptions
+// are invalid for change stream queries.
+//
+// In addition, if TransactionOptions.read_only.return_read_timestamp is set
+// to true, a special value of 2^63 - 2 will be returned in the
+// [Transaction][google.spanner.v1.Transaction] message that describes the
+// transaction, instead of a valid read timestamp. This special value should be
+// discarded and not used for any subsequent queries.
+//
+// Please see https://cloud.google.com/spanner/docs/change-streams
+// for more details on how to query the change stream TVFs.
+//
+// Partitioned DML transactions:
+//
 // Partitioned DML transactions are used to execute DML statements with a
 // different execution strategy that provides different, and often better,
 // scalability properties for large, table-wide operations than DML in a
diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto
index 3d28c331300..126e4a0c2fd 100644
--- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto
+++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/type.proto
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2022 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.

From fd0b84523535ba583a1b56acbea98835191daa06 Mon Sep 17 00:00:00 2001
From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com>
Date: Wed, 13 Jul 2022 19:32:21 +0000
Subject: [PATCH 09/11] fix: enable longpaths support for windows test (#1485)
 (#1946)

Source-Link: https://github.com/googleapis/synthtool/commit/73365620c41d96e97ff474b2c4d39b890ad51967
Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:d4b80feffe1579818cdc39466152e9de95789a193408506cd4a1ffbe8804dc00
---
 .github/.OwlBot.lock.yaml | 4 ++--
 README.md                 | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml
index 1b645c01291..de9173d95ef 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/.OwlBot.lock.yaml
@@ -13,5 +13,5 @@
 # limitations under the License.
 docker:
   image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest
-  digest: sha256:f8374176dc59291f05dd3fec927a9da2cda687a9ef4de32e77f699a2be12ab45
-# created: 2022-07-07T14:26:11.880812641Z
+  digest: sha256:d4b80feffe1579818cdc39466152e9de95789a193408506cd4a1ffbe8804dc00
+# created: 2022-07-13T13:53:17.676447481Z
diff --git a/README.md b/README.md
index f438c296463..056f2835ee4 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ If you are using Maven without BOM, add this to your dependencies:
 If you are using Gradle 5.x or later, add this to your dependencies:
 
 ```Groovy
-implementation platform('com.google.cloud:libraries-bom:25.4.0')
+implementation platform('com.google.cloud:libraries-bom:26.0.0')
 
 implementation 'com.google.cloud:google-cloud-spanner'
 ```

From 1822a138b254c8645dee629a5a055ba3dfe822a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= <koloite@gmail.com>
Date: Thu, 14 Jul 2022 00:03:09 +0200
Subject: [PATCH 10/11] test: test embedded comment in comment (#1919)

---
 .../cloud/spanner/connection/StatementParserTest.java      | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java
index 319180894dd..2e39025bf33 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java
@@ -154,6 +154,13 @@ public void testRemoveComments() {
                   + "line\n"
                   + "comment\n"
                   + "*/SELECT \"FOO\nBAR\" FROM \"BAR\" WHERE name='test\ntest' and id=1"));
+      assertEquals(
+          "SELECT 1",
+          parser.removeCommentsAndTrim(
+              "/* This block comment surrounds a query which itself has a block comment...\n"
+                  + "SELECT /* embedded single line */ 'embedded' AS x2;\n"
+                  + "*/\n"
+                  + "SELECT 1"));
     }
   }
 

From 6ea1e2e1d982ff67e3e18ddeb768669a72895548 Mon Sep 17 00:00:00 2001
From: "release-please[bot]"
 <55107282+release-please[bot]@users.noreply.github.com>
Date: Thu, 14 Jul 2022 13:56:25 +0000
Subject: [PATCH 11/11] chore(main): release 6.26.0 (#1935)

:robot: I have created a release *beep* *boop*
---


## [6.26.0](https://github.com/googleapis/java-spanner/compare/v6.25.7...v6.26.0) (2022-07-13)


### Features

* Adding two new fields for Instance create_time and update_time ([#1908](https://github.com/googleapis/java-spanner/issues/1908)) ([00b3817](https://github.com/googleapis/java-spanner/commit/00b38178e851401e293aa457f7ba5ea593a7b7c5))
* changes to support data, timestamp and arrays in IT tests ([#1840](https://github.com/googleapis/java-spanner/issues/1840)) ([c667653](https://github.com/googleapis/java-spanner/commit/c667653ec380dccbf205e7b419843da11cf4155a))
* Error Details Improvement ([c8a2184](https://github.com/googleapis/java-spanner/commit/c8a2184c51cc92ec35c759eff68e614fc78fb2e6))
* Error Details Improvement ([#1929](https://github.com/googleapis/java-spanner/issues/1929)) ([c8a2184](https://github.com/googleapis/java-spanner/commit/c8a2184c51cc92ec35c759eff68e614fc78fb2e6))


### Bug Fixes

* enable longpaths support for windows test ([#1485](https://github.com/googleapis/java-spanner/issues/1485)) ([#1946](https://github.com/googleapis/java-spanner/issues/1946)) ([fd0b845](https://github.com/googleapis/java-spanner/commit/fd0b84523535ba583a1b56acbea98835191daa06))


### Dependencies

* update dependency com.google.cloud:google-cloud-trace to v2.3.0 ([#1934](https://github.com/googleapis/java-spanner/issues/1934)) ([2813eb2](https://github.com/googleapis/java-spanner/commit/2813eb21c9f168e8dea149e40dac188933c7e2db))

---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
---
 CHANGELOG.md                                  | 20 +++++++++++++++++++
 google-cloud-spanner-bom/pom.xml              | 18 ++++++++---------
 google-cloud-spanner/pom.xml                  |  4 ++--
 .../pom.xml                                   |  4 ++--
 .../pom.xml                                   |  4 ++--
 grpc-google-cloud-spanner-v1/pom.xml          |  4 ++--
 pom.xml                                       | 16 +++++++--------
 .../pom.xml                                   |  4 ++--
 .../pom.xml                                   |  4 ++--
 proto-google-cloud-spanner-v1/pom.xml         |  4 ++--
 samples/snapshot/pom.xml                      |  2 +-
 versions.txt                                  | 14 ++++++-------
 12 files changed, 59 insertions(+), 39 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index df654988e32..7702ea80a17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,25 @@
 # Changelog
 
+## [6.26.0](https://github.com/googleapis/java-spanner/compare/v6.25.7...v6.26.0) (2022-07-13)
+
+
+### Features
+
+* Adding two new fields for Instance create_time and update_time ([#1908](https://github.com/googleapis/java-spanner/issues/1908)) ([00b3817](https://github.com/googleapis/java-spanner/commit/00b38178e851401e293aa457f7ba5ea593a7b7c5))
+* changes to support data, timestamp and arrays in IT tests ([#1840](https://github.com/googleapis/java-spanner/issues/1840)) ([c667653](https://github.com/googleapis/java-spanner/commit/c667653ec380dccbf205e7b419843da11cf4155a))
+* Error Details Improvement ([c8a2184](https://github.com/googleapis/java-spanner/commit/c8a2184c51cc92ec35c759eff68e614fc78fb2e6))
+* Error Details Improvement ([#1929](https://github.com/googleapis/java-spanner/issues/1929)) ([c8a2184](https://github.com/googleapis/java-spanner/commit/c8a2184c51cc92ec35c759eff68e614fc78fb2e6))
+
+
+### Bug Fixes
+
+* enable longpaths support for windows test ([#1485](https://github.com/googleapis/java-spanner/issues/1485)) ([#1946](https://github.com/googleapis/java-spanner/issues/1946)) ([fd0b845](https://github.com/googleapis/java-spanner/commit/fd0b84523535ba583a1b56acbea98835191daa06))
+
+
+### Dependencies
+
+* update dependency com.google.cloud:google-cloud-trace to v2.3.0 ([#1934](https://github.com/googleapis/java-spanner/issues/1934)) ([2813eb2](https://github.com/googleapis/java-spanner/commit/2813eb21c9f168e8dea149e40dac188933c7e2db))
+
 ## [6.25.7](https://github.com/googleapis/java-spanner/compare/v6.25.6...v6.25.7) (2022-06-30)
 
 
diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml
index d1973f706b7..3b2b98742f6 100644
--- a/google-cloud-spanner-bom/pom.xml
+++ b/google-cloud-spanner-bom/pom.xml
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner-bom</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+  <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   <packaging>pom</packaging>
   <parent>
     <groupId>com.google.cloud</groupId>
@@ -53,43 +53,43 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+        <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner</artifactId>
         <type>test-jar</type>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+        <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
     </dependencies>
   </dependencyManagement>
diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml
index c9c66fca10d..80217a17713 100644
--- a/google-cloud-spanner/pom.xml
+++ b/google-cloud-spanner/pom.xml
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+  <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   <packaging>jar</packaging>
   <name>Google Cloud Spanner</name>
   <url>https://github.com/googleapis/java-spanner</url>
@@ -11,7 +11,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <properties>
     <site.installationModule>google-cloud-spanner</site.installationModule>
diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml
index 586e45055a9..d392ff9e12e 100644
--- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml
+++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
+  <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
   <name>grpc-google-cloud-spanner-admin-database-v1</name>
   <description>GRPC library for grpc-google-cloud-spanner-admin-database-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml
index 635f2b33675..9c49df39fbd 100644
--- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml
+++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
+  <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
   <name>grpc-google-cloud-spanner-admin-instance-v1</name>
   <description>GRPC library for grpc-google-cloud-spanner-admin-instance-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml
index e3be92a9925..5d213541fee 100644
--- a/grpc-google-cloud-spanner-v1/pom.xml
+++ b/grpc-google-cloud-spanner-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-spanner-v1</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
+  <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
   <name>grpc-google-cloud-spanner-v1</name>
   <description>GRPC library for grpc-google-cloud-spanner-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/pom.xml b/pom.xml
index fdaa4995fbc..5687e3a34d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-spanner-parent</artifactId>
   <packaging>pom</packaging>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+  <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   <name>Google Cloud Spanner Parent</name>
   <url>https://github.com/googleapis/java-spanner</url>
   <description>
@@ -62,37 +62,37 @@
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
+        <version>6.26.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-spanner</artifactId>
-        <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+        <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
       </dependency>
 
       <dependency>
diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml
index 9af1acd5e29..d48562524b5 100644
--- a/proto-google-cloud-spanner-admin-database-v1/pom.xml
+++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
+  <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
   <name>proto-google-cloud-spanner-admin-database-v1</name>
   <description>PROTO library for proto-google-cloud-spanner-admin-database-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml
index ace386ca693..7e376f42145 100644
--- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml
+++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
+  <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
   <name>proto-google-cloud-spanner-admin-instance-v1</name>
   <description>PROTO library for proto-google-cloud-spanner-admin-instance-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml
index f9d30b28869..01894f48f9b 100644
--- a/proto-google-cloud-spanner-v1/pom.xml
+++ b/proto-google-cloud-spanner-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-spanner-v1</artifactId>
-  <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
+  <version>6.26.0</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
   <name>proto-google-cloud-spanner-v1</name>
   <description>PROTO library for proto-google-cloud-spanner-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-spanner-parent</artifactId>
-    <version>6.25.8-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
+    <version>6.26.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index 02704451ed8..1a5bd024413 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -31,7 +31,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-spanner</artifactId>
-      <version>6.25.8-SNAPSHOT</version>
+      <version>6.26.0</version>
     </dependency>
     <!-- {x-version-update-end} -->
     
diff --git a/versions.txt b/versions.txt
index 357a42c9284..4c3c1b66817 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,10 +1,10 @@
 # Format:
 # module:released-version:current-version
 
-proto-google-cloud-spanner-admin-instance-v1:6.25.7:6.25.8-SNAPSHOT
-proto-google-cloud-spanner-v1:6.25.7:6.25.8-SNAPSHOT
-proto-google-cloud-spanner-admin-database-v1:6.25.7:6.25.8-SNAPSHOT
-grpc-google-cloud-spanner-v1:6.25.7:6.25.8-SNAPSHOT
-grpc-google-cloud-spanner-admin-instance-v1:6.25.7:6.25.8-SNAPSHOT
-grpc-google-cloud-spanner-admin-database-v1:6.25.7:6.25.8-SNAPSHOT
-google-cloud-spanner:6.25.7:6.25.8-SNAPSHOT
+proto-google-cloud-spanner-admin-instance-v1:6.26.0:6.26.0
+proto-google-cloud-spanner-v1:6.26.0:6.26.0
+proto-google-cloud-spanner-admin-database-v1:6.26.0:6.26.0
+grpc-google-cloud-spanner-v1:6.26.0:6.26.0
+grpc-google-cloud-spanner-admin-instance-v1:6.26.0:6.26.0
+grpc-google-cloud-spanner-admin-database-v1:6.26.0:6.26.0
+google-cloud-spanner:6.26.0:6.26.0