diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..e11826876 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,51 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +Thanks for stopping by to let us know something could be better! + +**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. + +Please run down the following list and make sure you've tried the usual "quick fixes": + + - Search the issues already opened: https://github.com/googleapis/java-spanner-jdbc/issues + - Check for answers on StackOverflow: http://stackoverflow.com/questions/tagged/google-cloud-platform + +If you are still having issues, please include as much information as possible: + +#### Environment details + +1. Specify the API at the beginning of the title. For example, "BigQuery: ..."). + General, Core, and Other are also allowed as types +2. OS type and version: +3. Java version: +4. spanner-jdbc version(s): + +#### Steps to reproduce + + 1. ? + 2. ? + +#### Code example + +```java +// example +``` + +#### Stack trace +``` +Any relevant stacktrace here. +``` + +#### External references such as API reference guides + +- ? + +#### Any additional information below + + +Following these steps guarantees the quickest resolution possible. + +Thanks! diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..754e30c68 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Suggest an idea for this library + +--- + +Thanks for stopping by to let us know something could be better! + +**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. + +**Is your feature request related to a problem? Please describe.** +What the problem is. Example: I'm always frustrated when [...] + +**Describe the solution you'd like** +What you want to happen. + +**Describe alternatives you've considered** +Any alternative solutions or features you've considered. + +**Additional context** +Any other context or screenshots about the feature request. diff --git a/.github/ISSUE_TEMPLATE/support_request.md b/.github/ISSUE_TEMPLATE/support_request.md new file mode 100644 index 000000000..995869032 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support_request.md @@ -0,0 +1,7 @@ +--- +name: Support request +about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. + +--- + +**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..0bd0ee062 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ +Fixes # (it's a good idea to open an issue first for context and/or discussion) \ No newline at end of file diff --git a/.github/release-please.yml b/.github/release-please.yml new file mode 100644 index 000000000..dce2c8450 --- /dev/null +++ b/.github/release-please.yml @@ -0,0 +1,2 @@ +releaseType: java-yoshi +bumpMinorPreMajor: true \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..488765800 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Packages +dist +bin +var +sdist +target + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg + +.metadata +.project +.pydevproject +*.iml +.idea +.settings +.DS_Store +.classpath + +# Built documentation +docs/ + + +# Wheel directory used in Travis builds. +gcloud-java-wheels/ +src/test/resources/gcd-head.zip +src/test/resources/gcd-v1beta2-rev1-2.1.1.zip + +# API key file containing value of GOOGLE_API_KEY for integration tests +api_key + +# Python utilities +*.pyc +artman-genfiles \ No newline at end of file diff --git a/.kokoro/build.bat b/.kokoro/build.bat new file mode 100644 index 000000000..680ad2804 --- /dev/null +++ b/.kokoro/build.bat @@ -0,0 +1,3 @@ +:: See documentation in type-shell-output.bat + +"C:\Program Files\Git\bin\bash.exe" github/java-spanner-jdbc/.kokoro/build.sh diff --git a/.kokoro/build.sh b/.kokoro/build.sh new file mode 100755 index 000000000..f1ae58408 --- /dev/null +++ b/.kokoro/build.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright 2019 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 +# +# http://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. + +set -eo pipefail + +## Get the directory of the build script +scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}")) +## cd to the parent directory, i.e. the root of the git repo +cd ${scriptDir}/.. + +# Print out Java version +java -version +echo ${JOB_TYPE} + +mvn install -B -V \ + -DskipTests=true \ + -Dclirr.skip=true \ + -Denforcer.skip=true \ + -Dmaven.javadoc.skip=true \ + -Dgcloud.download.skip=true \ + -T 1C + +# if GOOGLE_APPLICATION_CREDIENTIALS is specified as a relative path prepend Kokoro root directory onto it +if [[ ! -z "${GOOGLE_APPLICATION_CREDENTIALS}" && "${GOOGLE_APPLICATION_CREDENTIALS}" != /* ]]; then + export GOOGLE_APPLICATION_CREDENTIALS=$(realpath ${KOKORO_ROOT}/src/${GOOGLE_APPLICATION_CREDENTIALS}) +fi + +case ${JOB_TYPE} in +test) + mvn test -B -Dclirr.skip=true -Denforcer.skip=true + bash ${KOKORO_GFILE_DIR}/codecov.sh + bash .kokoro/coerce_logs.sh + ;; +lint) + mvn \ + -Penable-samples \ + com.coveo:fmt-maven-plugin:check + ;; +javadoc) + mvn javadoc:javadoc javadoc:test-javadoc + ;; +integration) + mvn -B ${INTEGRATION_TEST_ARGS} \ + -Penable-integration-tests \ + -DtrimStackTrace=false \ + -Dclirr.skip=true \ + -Denforcer.skip=true \ + -fae \ + verify + bash .kokoro/coerce_logs.sh + ;; +samples) + mvn -B \ + -Penable-samples \ + -DtrimStackTrace=false \ + -Dclirr.skip=true \ + -Denforcer.skip=true \ + -fae \ + verify + bash .kokoro/coerce_logs.sh + ;; +clirr) + mvn -B -Denforcer.skip=true clirr:check + ;; +*) + ;; +esac diff --git a/.kokoro/coerce_logs.sh b/.kokoro/coerce_logs.sh new file mode 100755 index 000000000..5cf7ba49e --- /dev/null +++ b/.kokoro/coerce_logs.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Copyright 2019 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 +# +# http://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. + +# This script finds and moves sponge logs so that they can be found by placer +# and are not flagged as flaky by sponge. + +set -eo pipefail + +## Get the directory of the build script +scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}")) +## cd to the parent directory, i.e. the root of the git repo +cd ${scriptDir}/.. + +job=$(basename ${KOKORO_JOB_NAME}) + +echo "coercing sponge logs..." +for xml in `find . -name *-sponge_log.xml` +do + echo "processing ${xml}" + class=$(basename ${xml} | cut -d- -f2) + dir=$(dirname ${xml})/${job}/${class} + text=$(dirname ${xml})/${class}-sponge_log.txt + mkdir -p ${dir} + mv ${xml} ${dir}/sponge_log.xml + mv ${text} ${dir}/sponge_log.txt +done diff --git a/.kokoro/common.cfg b/.kokoro/common.cfg new file mode 100644 index 000000000..bc068f6cb --- /dev/null +++ b/.kokoro/common.cfg @@ -0,0 +1,13 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Download trampoline resources. These will be in ${KOKORO_GFILE_DIR} +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# All builds use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +# Tell the trampoline which build file to use. +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/build.sh" +} diff --git a/.kokoro/continuous/common.cfg b/.kokoro/continuous/common.cfg new file mode 100644 index 000000000..dbc14991a --- /dev/null +++ b/.kokoro/continuous/common.cfg @@ -0,0 +1,25 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.txt" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/build.sh" +} + +env_vars: { + key: "JOB_TYPE" + value: "test" +} diff --git a/.kokoro/continuous/dependencies.cfg b/.kokoro/continuous/dependencies.cfg new file mode 100644 index 000000000..2d09bcc0a --- /dev/null +++ b/.kokoro/continuous/dependencies.cfg @@ -0,0 +1,12 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/dependencies.sh" +} diff --git a/.kokoro/continuous/integration.cfg b/.kokoro/continuous/integration.cfg new file mode 100644 index 000000000..3b017fc80 --- /dev/null +++ b/.kokoro/continuous/integration.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} diff --git a/.kokoro/continuous/java11.cfg b/.kokoro/continuous/java11.cfg new file mode 100644 index 000000000..709f2b4c7 --- /dev/null +++ b/.kokoro/continuous/java11.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java11" +} diff --git a/.kokoro/continuous/java7.cfg b/.kokoro/continuous/java7.cfg new file mode 100644 index 000000000..cb24f44ee --- /dev/null +++ b/.kokoro/continuous/java7.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java7" +} diff --git a/.kokoro/continuous/java8-osx.cfg b/.kokoro/continuous/java8-osx.cfg new file mode 100644 index 000000000..c6980278d --- /dev/null +++ b/.kokoro/continuous/java8-osx.cfg @@ -0,0 +1,3 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +build_file: "java-spanner-jdbc/.kokoro/build.sh" diff --git a/.kokoro/continuous/java8-win.cfg b/.kokoro/continuous/java8-win.cfg new file mode 100644 index 000000000..90e4b928a --- /dev/null +++ b/.kokoro/continuous/java8-win.cfg @@ -0,0 +1,3 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +build_file: "java-spanner-jdbc/.kokoro/build.bat" diff --git a/.kokoro/continuous/java8.cfg b/.kokoro/continuous/java8.cfg new file mode 100644 index 000000000..3b017fc80 --- /dev/null +++ b/.kokoro/continuous/java8.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} diff --git a/.kokoro/continuous/lint.cfg b/.kokoro/continuous/lint.cfg new file mode 100644 index 000000000..6d323c8ae --- /dev/null +++ b/.kokoro/continuous/lint.cfg @@ -0,0 +1,13 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. + +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "lint" +} \ No newline at end of file diff --git a/.kokoro/continuous/propose_release.cfg b/.kokoro/continuous/propose_release.cfg new file mode 100644 index 000000000..1b7a1affa --- /dev/null +++ b/.kokoro/continuous/propose_release.cfg @@ -0,0 +1,53 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/continuous/propose_release.sh" +} + +# tokens used by release-please to keep an up-to-date release PR. +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "github-magic-proxy-key-release-please" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "github-magic-proxy-token-release-please" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "github-magic-proxy-url-release-please" + } + } +} diff --git a/.kokoro/continuous/propose_release.sh b/.kokoro/continuous/propose_release.sh new file mode 100755 index 000000000..c2fb269ef --- /dev/null +++ b/.kokoro/continuous/propose_release.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Copyright 2019 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. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=/home/node/.npm-global + +if [ -f ${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-url-release-please ]; then + # Groom the release PR as new commits are merged. + npx release-please release-pr --token=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-token-release-please \ + --repo-url=googleapis/java-spanner-jdbc \ + --package-name="spanner-jdbc" \ + --api-url=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-url-release-please \ + --proxy-key=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-key-release-please \ + --release-type=java-yoshi +fi diff --git a/.kokoro/continuous/samples.cfg b/.kokoro/continuous/samples.cfg new file mode 100644 index 000000000..fa7b493d0 --- /dev/null +++ b/.kokoro/continuous/samples.cfg @@ -0,0 +1,31 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "samples" +} + +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "keystore/73713_java_it_service_account" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "java_it_service_account" + } + } +} diff --git a/.kokoro/dependencies.sh b/.kokoro/dependencies.sh new file mode 100755 index 000000000..d1cb8dc2c --- /dev/null +++ b/.kokoro/dependencies.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Copyright 2019 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 +# +# http://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. + +set -eo pipefail + +cd github/java-spanner-jdbc/ + +# Print out Java +java -version +echo $JOB_TYPE + +export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=128m" + +# this should run maven enforcer +mvn install -B -V \ + -DskipTests=true \ + -Dclirr.skip=true + +mvn -B dependency:analyze -DfailOnWarning=true diff --git a/.kokoro/linkage-monitor.sh b/.kokoro/linkage-monitor.sh new file mode 100755 index 000000000..a3e5ab30e --- /dev/null +++ b/.kokoro/linkage-monitor.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Copyright 2019 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 +# +# http://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. + +set -eo pipefail +# Display commands being run. +set -x + +cd github/java-spanner-jdbc/ + +# Print out Java version +java -version +echo ${JOB_TYPE} + +mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgcloud.download.skip=true -B -V + +# Kokoro job cloud-opensource-java/ubuntu/linkage-monitor-gcs creates this JAR +JAR=linkage-monitor-latest-all-deps.jar +curl -v -O "https://storage.googleapis.com/cloud-opensource-java-linkage-monitor/${JAR}" + +# Fails if there's new linkage errors compared with baseline +java -jar ${JAR} com.google.cloud:libraries-bom diff --git a/.kokoro/nightly/common.cfg b/.kokoro/nightly/common.cfg new file mode 100644 index 000000000..dbc14991a --- /dev/null +++ b/.kokoro/nightly/common.cfg @@ -0,0 +1,25 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.txt" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/build.sh" +} + +env_vars: { + key: "JOB_TYPE" + value: "test" +} diff --git a/.kokoro/nightly/dependencies.cfg b/.kokoro/nightly/dependencies.cfg new file mode 100644 index 000000000..2d09bcc0a --- /dev/null +++ b/.kokoro/nightly/dependencies.cfg @@ -0,0 +1,12 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/dependencies.sh" +} diff --git a/.kokoro/nightly/integration.cfg b/.kokoro/nightly/integration.cfg new file mode 100644 index 000000000..3b017fc80 --- /dev/null +++ b/.kokoro/nightly/integration.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} diff --git a/.kokoro/nightly/java11.cfg b/.kokoro/nightly/java11.cfg new file mode 100644 index 000000000..709f2b4c7 --- /dev/null +++ b/.kokoro/nightly/java11.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java11" +} diff --git a/.kokoro/nightly/java7.cfg b/.kokoro/nightly/java7.cfg new file mode 100644 index 000000000..cb24f44ee --- /dev/null +++ b/.kokoro/nightly/java7.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java7" +} diff --git a/.kokoro/nightly/java8-osx.cfg b/.kokoro/nightly/java8-osx.cfg new file mode 100644 index 000000000..c6980278d --- /dev/null +++ b/.kokoro/nightly/java8-osx.cfg @@ -0,0 +1,3 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +build_file: "java-spanner-jdbc/.kokoro/build.sh" diff --git a/.kokoro/nightly/java8-win.cfg b/.kokoro/nightly/java8-win.cfg new file mode 100644 index 000000000..90e4b928a --- /dev/null +++ b/.kokoro/nightly/java8-win.cfg @@ -0,0 +1,3 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +build_file: "java-spanner-jdbc/.kokoro/build.bat" diff --git a/.kokoro/nightly/java8.cfg b/.kokoro/nightly/java8.cfg new file mode 100644 index 000000000..3b017fc80 --- /dev/null +++ b/.kokoro/nightly/java8.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} diff --git a/.kokoro/nightly/lint.cfg b/.kokoro/nightly/lint.cfg new file mode 100644 index 000000000..6d323c8ae --- /dev/null +++ b/.kokoro/nightly/lint.cfg @@ -0,0 +1,13 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. + +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "lint" +} \ No newline at end of file diff --git a/.kokoro/nightly/samples.cfg b/.kokoro/nightly/samples.cfg new file mode 100644 index 000000000..9a9102490 --- /dev/null +++ b/.kokoro/nightly/samples.cfg @@ -0,0 +1,31 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "samples" +} + +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "keystore/73713_java_it_service_account" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "java_it_service_account" + } + } +} diff --git a/.kokoro/presubmit/clirr.cfg b/.kokoro/presubmit/clirr.cfg new file mode 100644 index 000000000..ec572442e --- /dev/null +++ b/.kokoro/presubmit/clirr.cfg @@ -0,0 +1,13 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. + +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "clirr" +} \ No newline at end of file diff --git a/.kokoro/presubmit/common.cfg b/.kokoro/presubmit/common.cfg new file mode 100644 index 000000000..175502fdc --- /dev/null +++ b/.kokoro/presubmit/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.txt" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/build.sh" +} + +env_vars: { + key: "JOB_TYPE" + value: "test" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "dpebot_codecov_token" + } + } +} diff --git a/.kokoro/presubmit/dependencies.cfg b/.kokoro/presubmit/dependencies.cfg new file mode 100644 index 000000000..2d09bcc0a --- /dev/null +++ b/.kokoro/presubmit/dependencies.cfg @@ -0,0 +1,12 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/dependencies.sh" +} diff --git a/.kokoro/presubmit/integration.cfg b/.kokoro/presubmit/integration.cfg new file mode 100644 index 000000000..141f90c13 --- /dev/null +++ b/.kokoro/presubmit/integration.cfg @@ -0,0 +1,31 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "integration" +} + +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "keystore/73713_java_it_service_account" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "java_it_service_account" + } + } +} diff --git a/.kokoro/presubmit/java11.cfg b/.kokoro/presubmit/java11.cfg new file mode 100644 index 000000000..709f2b4c7 --- /dev/null +++ b/.kokoro/presubmit/java11.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java11" +} diff --git a/.kokoro/presubmit/java7.cfg b/.kokoro/presubmit/java7.cfg new file mode 100644 index 000000000..cb24f44ee --- /dev/null +++ b/.kokoro/presubmit/java7.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java7" +} diff --git a/.kokoro/presubmit/java8-osx.cfg b/.kokoro/presubmit/java8-osx.cfg new file mode 100644 index 000000000..c6980278d --- /dev/null +++ b/.kokoro/presubmit/java8-osx.cfg @@ -0,0 +1,3 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +build_file: "java-spanner-jdbc/.kokoro/build.sh" diff --git a/.kokoro/presubmit/java8-win.cfg b/.kokoro/presubmit/java8-win.cfg new file mode 100644 index 000000000..90e4b928a --- /dev/null +++ b/.kokoro/presubmit/java8-win.cfg @@ -0,0 +1,3 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +build_file: "java-spanner-jdbc/.kokoro/build.bat" diff --git a/.kokoro/presubmit/java8.cfg b/.kokoro/presubmit/java8.cfg new file mode 100644 index 000000000..3b017fc80 --- /dev/null +++ b/.kokoro/presubmit/java8.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} diff --git a/.kokoro/presubmit/linkage-monitor.cfg b/.kokoro/presubmit/linkage-monitor.cfg new file mode 100644 index 000000000..0e904ec1f --- /dev/null +++ b/.kokoro/presubmit/linkage-monitor.cfg @@ -0,0 +1,12 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/linkage-monitor.sh" +} \ No newline at end of file diff --git a/.kokoro/presubmit/lint.cfg b/.kokoro/presubmit/lint.cfg new file mode 100644 index 000000000..6d323c8ae --- /dev/null +++ b/.kokoro/presubmit/lint.cfg @@ -0,0 +1,13 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. + +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "lint" +} \ No newline at end of file diff --git a/.kokoro/presubmit/samples.cfg b/.kokoro/presubmit/samples.cfg new file mode 100644 index 000000000..fa7b493d0 --- /dev/null +++ b/.kokoro/presubmit/samples.cfg @@ -0,0 +1,31 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +env_vars: { + key: "JOB_TYPE" + value: "samples" +} + +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "keystore/73713_java_it_service_account" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "java_it_service_account" + } + } +} diff --git a/.kokoro/release/bump_snapshot.cfg b/.kokoro/release/bump_snapshot.cfg new file mode 100644 index 000000000..3dc06f216 --- /dev/null +++ b/.kokoro/release/bump_snapshot.cfg @@ -0,0 +1,53 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/release/bump_snapshot.sh" +} + +# tokens used by release-please to keep an up-to-date release PR. +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "github-magic-proxy-key-release-please" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "github-magic-proxy-token-release-please" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "github-magic-proxy-url-release-please" + } + } +} diff --git a/.kokoro/release/bump_snapshot.sh b/.kokoro/release/bump_snapshot.sh new file mode 100755 index 000000000..4d76d4393 --- /dev/null +++ b/.kokoro/release/bump_snapshot.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Copyright 2019 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. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=/home/node/.npm-global + +if [ -f ${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-url-release-please ]; then + # Groom the snapshot release PR immediately after publishing a release + npx release-please release-pr --token=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-token-release-please \ + --repo-url=googleapis/java-spanner-jdbc \ + --package-name="spanner-jdbc" \ + --api-url=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-url-release-please \ + --proxy-key=${KOKORO_KEYSTORE_DIR}/73713_github-magic-proxy-key-release-please \ + --snapshot \ + --release-type=java-auth-yoshi +fi diff --git a/.kokoro/release/common.cfg b/.kokoro/release/common.cfg new file mode 100644 index 000000000..2ace079c9 --- /dev/null +++ b/.kokoro/release/common.cfg @@ -0,0 +1,49 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "java-spanner-jdbc/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/java8" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 70247 + keyname: "maven-gpg-keyring" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 70247 + keyname: "maven-gpg-passphrase" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 70247 + keyname: "maven-gpg-pubkeyring" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 70247 + keyname: "sonatype-credentials" + } + } +} diff --git a/.kokoro/release/common.sh b/.kokoro/release/common.sh new file mode 100755 index 000000000..6e3f65999 --- /dev/null +++ b/.kokoro/release/common.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright 2018 Google Inc. +# +# 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 +# +# http://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. + +set -eo pipefail + +# Get secrets from keystore and set and environment variables +setup_environment_secrets() { + export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) + export GPG_TTY=$(tty) + export GPG_HOMEDIR=/gpg + mkdir $GPG_HOMEDIR + mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-pubkeyring $GPG_HOMEDIR/pubring.gpg + mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-keyring $GPG_HOMEDIR/secring.gpg + export SONATYPE_USERNAME=$(cat ${KOKORO_KEYSTORE_DIR}/70247_sonatype-credentials | cut -f1 -d'|') + export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/70247_sonatype-credentials | cut -f2 -d'|') +} + +create_settings_xml_file() { + echo " + + + ossrh + ${SONATYPE_USERNAME} + ${SONATYPE_PASSWORD} + + + sonatype-nexus-staging + ${SONATYPE_USERNAME} + ${SONATYPE_PASSWORD} + + + sonatype-nexus-snapshots + ${SONATYPE_USERNAME} + ${SONATYPE_PASSWORD} + + +" > $1 +} \ No newline at end of file diff --git a/.kokoro/release/drop.cfg b/.kokoro/release/drop.cfg new file mode 100644 index 000000000..245e96b4c --- /dev/null +++ b/.kokoro/release/drop.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/release/drop.sh" +} diff --git a/.kokoro/release/drop.sh b/.kokoro/release/drop.sh new file mode 100755 index 000000000..5c4551efa --- /dev/null +++ b/.kokoro/release/drop.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Copyright 2018 Google Inc. +# +# 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 +# +# http://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. + +set -eo pipefail + +# STAGING_REPOSITORY_ID must be set +if [ -z "${STAGING_REPOSITORY_ID}" ]; then + echo "Missing STAGING_REPOSITORY_ID environment variable" + exit 1 +fi + +source $(dirname "$0")/common.sh +pushd $(dirname "$0")/../../ + +setup_environment_secrets +create_settings_xml_file "settings.xml" + +mvn nexus-staging:drop -B \ + --settings=settings.xml \ + -DstagingRepositoryId=${STAGING_REPOSITORY_ID} diff --git a/.kokoro/release/promote.cfg b/.kokoro/release/promote.cfg new file mode 100644 index 000000000..1ee66ee99 --- /dev/null +++ b/.kokoro/release/promote.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/release/promote.sh" +} diff --git a/.kokoro/release/promote.sh b/.kokoro/release/promote.sh new file mode 100755 index 000000000..1fa95fa53 --- /dev/null +++ b/.kokoro/release/promote.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Copyright 2018 Google Inc. +# +# 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 +# +# http://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. + +set -eo pipefail + +# STAGING_REPOSITORY_ID must be set +if [ -z "${STAGING_REPOSITORY_ID}" ]; then + echo "Missing STAGING_REPOSITORY_ID environment variable" + exit 1 +fi + +source $(dirname "$0")/common.sh + +pushd $(dirname "$0")/../../ + +setup_environment_secrets +create_settings_xml_file "settings.xml" + +mvn nexus-staging:release -B \ + -DperformRelease=true \ + --settings=settings.xml \ + -DstagingRepositoryId=${STAGING_REPOSITORY_ID} diff --git a/.kokoro/release/publish_javadoc.cfg b/.kokoro/release/publish_javadoc.cfg new file mode 100644 index 000000000..fc95786fa --- /dev/null +++ b/.kokoro/release/publish_javadoc.cfg @@ -0,0 +1,19 @@ +# Format: //devtools/kokoro/config/proto/build.proto +env_vars: { + key: "STAGING_BUCKET" + value: "docs-staging" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/release/publish_javadoc.sh" +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "docuploader_service_account" + } + } +} diff --git a/.kokoro/release/publish_javadoc.sh b/.kokoro/release/publish_javadoc.sh new file mode 100755 index 000000000..99de3944b --- /dev/null +++ b/.kokoro/release/publish_javadoc.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Copyright 2019 Google Inc. +# +# 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 +# +# http://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. + +set -eo pipefail + +if [[ -z "${CREDENTIALS}" ]]; then + CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account +fi + +if [[ -z "${STAGING_BUCKET}" ]]; then + echo "Need to set STAGING_BUCKET environment variable" + exit 1 +fi + +# work from the git root directory +pushd $(dirname "$0")/../../ + +# install docuploader package +python3 -m pip install gcp-docuploader + +# compile all packages +mvn clean install -B -DskipTests=true + +NAME=google-cloud-spanner-jdbc +VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3) + +# build the docs +mvn site -B + +pushd target/site/apidocs + +# create metadata +python3 -m docuploader create-metadata \ + --name ${NAME} \ + --version ${VERSION} \ + --language java + +# upload docs +python3 -m docuploader upload . \ + --credentials ${CREDENTIALS} \ + --staging-bucket ${STAGING_BUCKET} + +popd diff --git a/.kokoro/release/snapshot.cfg b/.kokoro/release/snapshot.cfg new file mode 100644 index 000000000..aa772391f --- /dev/null +++ b/.kokoro/release/snapshot.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/release/snapshot.sh" +} \ No newline at end of file diff --git a/.kokoro/release/snapshot.sh b/.kokoro/release/snapshot.sh new file mode 100755 index 000000000..098168a73 --- /dev/null +++ b/.kokoro/release/snapshot.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Copyright 2019 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 +# +# http://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. + +set -eo pipefail + +source $(dirname "$0")/common.sh +MAVEN_SETTINGS_FILE=$(realpath $(dirname "$0")/../../)/settings.xml +pushd $(dirname "$0")/../../ + +# ensure we're trying to push a snapshot (no-result returns non-zero exit code) +grep SNAPSHOT versions.txt + +setup_environment_secrets +create_settings_xml_file "settings.xml" + +mvn clean install deploy -B \ + --settings ${MAVEN_SETTINGS_FILE} \ + -DperformRelease=true \ + -Dgpg.executable=gpg \ + -Dgpg.passphrase=${GPG_PASSPHRASE} \ + -Dgpg.homedir=${GPG_HOMEDIR} diff --git a/.kokoro/release/stage.cfg b/.kokoro/release/stage.cfg new file mode 100644 index 000000000..8ea66bc79 --- /dev/null +++ b/.kokoro/release/stage.cfg @@ -0,0 +1,44 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/java-spanner-jdbc/.kokoro/release/stage.sh" +} + +# Need to save the properties file +action { + define_artifacts { + regex: "github/java-spanner-jdbc/target/nexus-staging/staging/*.properties" + strip_prefix: "github/java-spanner-jdbc" + } +} + +# Fetch the token needed for reporting release status to GitHub +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "yoshi-automation-github-key" + } + } +} + +# Fetch magictoken to use with Magic Github Proxy +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "releasetool-magictoken" + } + } +} + +# Fetch api key to use with Magic Github Proxy +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "magic-github-proxy-api-key" + } + } +} diff --git a/.kokoro/release/stage.sh b/.kokoro/release/stage.sh new file mode 100755 index 000000000..3c482cbc5 --- /dev/null +++ b/.kokoro/release/stage.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Copyright 2018 Google Inc. +# +# 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 +# +# http://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. + +set -eo pipefail + +# Start the releasetool reporter +python3 -m pip install gcp-releasetool +python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script + +source $(dirname "$0")/common.sh +MAVEN_SETTINGS_FILE=$(realpath $(dirname "$0")/../../)/settings.xml +pushd $(dirname "$0")/../../ + +setup_environment_secrets +create_settings_xml_file "settings.xml" + +mvn clean install deploy -B \ + --settings ${MAVEN_SETTINGS_FILE} \ + -DskipTests=true \ + -DperformRelease=true \ + -Dgpg.executable=gpg \ + -Dgpg.passphrase=${GPG_PASSPHRASE} \ + -Dgpg.homedir=${GPG_HOMEDIR} + +if [[ -n "${AUTORELEASE_PR}" ]] +then + mvn nexus-staging:release -B \ + -DperformRelease=true \ + --settings=settings.xml +fi \ No newline at end of file diff --git a/.kokoro/trampoline.sh b/.kokoro/trampoline.sh new file mode 100644 index 000000000..ba17ce014 --- /dev/null +++ b/.kokoro/trampoline.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Copyright 2018 Google Inc. +# +# 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 +# +# http://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. +set -eo pipefail +# Always run the cleanup script, regardless of the success of bouncing into +# the container. +function cleanup() { + chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + echo "cleanup"; +} +trap cleanup EXIT +python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" diff --git a/.repo-metadata.json b/.repo-metadata.json new file mode 100644 index 000000000..83c6f64d7 --- /dev/null +++ b/.repo-metadata.json @@ -0,0 +1,11 @@ +{ + "name": "spanner-jdbc", + "name_pretty": "Google Cloud Spanner JDBC", + "product_documentation": "https://cloud.google.com/pubsub/docs/", + "client_documentation": "https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/spanner/jdbc/v1", + "release_level": "ga", + "language": "java", + "repo": "googleapis/java-spanner-jdbc", + "repo_short": "java-spanner-jdbc", + "distribution_name": "com.google.cloud:google-cloud-spanner-jdbc" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..3fbddecd3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +## [1.13.0](https://www.github.com/googleapis/java-spanner-jdbc/compare/1.12.0...v1.13.0) (2020-01-28) + + +### Features + +* allow using existing OAuth token for JDBC connection ([#37](https://www.github.com/googleapis/java-spanner-jdbc/issues/37)) ([b368b84](https://www.github.com/googleapis/java-spanner-jdbc/commit/b368b8407b3e2884458d956a9207cb4e12e37848)), closes [#29](https://www.github.com/googleapis/java-spanner-jdbc/issues/29) + + +### Bug Fixes + +* add support for WITH clauses ([#42](https://www.github.com/googleapis/java-spanner-jdbc/issues/42)) ([7f4bea4](https://www.github.com/googleapis/java-spanner-jdbc/commit/7f4bea43c42df68258f776944ea744069a1a218e)) +* allow dots and colons in project id ([#36](https://www.github.com/googleapis/java-spanner-jdbc/issues/36)) ([5957008](https://www.github.com/googleapis/java-spanner-jdbc/commit/59570085403fa7002616dd535df4666a384c3438)), closes [#33](https://www.github.com/googleapis/java-spanner-jdbc/issues/33) + + +### Dependencies + +* update core dependencies ([#25](https://www.github.com/googleapis/java-spanner-jdbc/issues/25)) ([9f4f4ad](https://www.github.com/googleapis/java-spanner-jdbc/commit/9f4f4ad1b076bd3131296c9f7f6558f2bc885d42)) +* update dependency org.threeten:threetenbp to v1.4.1 ([7cc951b](https://www.github.com/googleapis/java-spanner-jdbc/commit/7cc951b340b072e7853df868aaf7c17f854a69f5)) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..6b2238bb7 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,93 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + +Reports should be directed to *[PROJECT STEWARD NAME(s) AND EMAIL(s)]*, the +Project Steward(s) for *[PROJECT NAME]*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..085021dde --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,130 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution; +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. + +## Community Guidelines + +This project follows +[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). + +## Building the project + +To build, package, and run all unit tests run the command + +``` +mvn clean verify +``` + +### Running Integration tests + +To include integration tests when building the project, you need access to +a GCP Project with a valid service account. + +For instructions on how to generate a service account and corresponding +credentials JSON see: [Creating a Service Account][1]. + +Then run the following to build, package, run all unit tests and run all +integration tests. + +```bash +export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service/account.json +mvn -Penable-integration-tests clean verify +``` + +## Code Samples + +Code Samples must be bundled in separate Maven modules, and guarded by a +Maven profile with the name `enable-samples`. + +The samples must be separate from the primary project for a few reasons: +1. Primary projects have a minimum Java version of Java 7 whereas samples have + a minimum Java version of Java 8. Due to this we need the ability to + selectively exclude samples from a build run. +2. Many code samples depend on external GCP services and need + credentials to access the service. +3. Code samples are not released as Maven artifacts and must be excluded from + release builds. + +### Building + +```bash +mvn -Penable-samples clean verify +``` + +Some samples require access to GCP services and require a service account: + +```bash +export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service/account.json +mvn -Penable-samples clean verify +``` + +### Profile Config + +1. To add samples in a profile to your Maven project, add the following to your +`pom.xml` + + ```xml + + [...] + + + enable-samples + + sample + + + + [...] + + ``` + +2. [Activate](#profile-activation) the profile. +3. Define your samples in a normal Maven project in the `samples/` directory + +### Profile Activation + +To include code samples when building and testing the project, enable the +`enable-samples` Maven profile. + +#### Command line + +To activate the Maven profile on the command line add `-Penable-samples` to your +Maven command. + +#### Maven `settings.xml` + +To activate the Maven profile in your `~/.m2/settings.xml` add an entry of +`enable-samples` following the instructions in [Active Profiles][2]. + +This method has the benefit of applying to all projects you build (and is +respected by IntelliJ IDEA) and is recommended if you are going to be +contributing samples to several projects. + +#### IntelliJ IDEA + +To activate the Maven Profile inside IntelliJ IDEA, follow the instructions in +[Activate Maven profiles][3] to activate `enable-samples`. + +[1]: https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account +[2]: https://maven.apache.org/settings.html#Active_Profiles +[3]: https://www.jetbrains.com/help/idea/work-with-maven-profiles.html#activate_maven_profiles diff --git a/LICENSE b/LICENSE index 4eedc0116..d64569567 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,5 @@ -Apache License + + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -178,7 +179,7 @@ Apache License APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" + boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a diff --git a/README.md b/README.md index 666bc7384..db50ef106 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud google-cloud-spanner-jdbc - 1.12.0 + 1.13.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:google-cloud-spanner-jdbc:1.12.0' +compile 'com.google.cloud:google-cloud-spanner-jdbc:1.13.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "1.12.0" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner-jdbc" % "1.13.0" ``` [//]: # ({x-version-update-end}) diff --git a/codecov.yaml b/codecov.yaml new file mode 100644 index 000000000..5724ea947 --- /dev/null +++ b/codecov.yaml @@ -0,0 +1,4 @@ +--- +codecov: + ci: + - source.cloud.google.com diff --git a/java.header b/java.header new file mode 100644 index 000000000..3a9b503aa --- /dev/null +++ b/java.header @@ -0,0 +1,15 @@ +^/\*$ +^ \* Copyright \d\d\d\d,? Google (Inc\.|LLC)( All [rR]ights [rR]eserved\.)?$ +^ \*$ +^ \* 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\.$ +^ \*/$ diff --git a/license-checks.xml b/license-checks.xml new file mode 100644 index 000000000..6597fced8 --- /dev/null +++ b/license-checks.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/pom.xml b/pom.xml index 9348bd170..05fc70031 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 google-cloud-spanner-jdbc - 1.12.0 + 1.13.0 jar Google Cloud Spanner JDBC https://github.com/googleapis/google-cloud-java/tree/master/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc @@ -13,40 +13,272 @@ com.google.cloud - google-cloud-contrib - 0.120.0-alpha + google-cloud-shared-config + 0.4.0 + + + chingor + Jeff Ching + chingor@google.com + Google + + Developer + + + + + Google LLC + + + scm:git:git@github.com:googleapis/java-spanner-jdbc.git + scm:git:git@github.com:googleapis/java-spanner-jdbc.git + https://github.com/googleapis/java-spanner-jdbc + HEAD + + + https://github.com/googleapis/java-spanner-jdbc/issues + GitHub Issues + + + + sonatype-nexus-snapshots + https://oss.sonatype.org/content/repositories/snapshots + + + sonatype-nexus-staging + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + google-cloud-spanner-jdbc + 1.26.0 + 1.30.7 + 1.92.2 + 1.53.0 + 1.34.0 + 28.2-android + 4.13 + 1.17.0 + 3.11.1 + 1.4.1 + 1.8.1 + 1.47.0 + 2.2 + 2.3.4 + 0.19.0 + + + + + io.grpc + grpc-bom + ${grpc.version} + pom + import + + + com.google.api-client + google-api-client-bom + ${api-client.version} + pom + import + + + com.google.cloud + google-cloud-core-bom + ${google.core.version} + pom + import + + + com.google.api + gax-bom + ${gax.version} + pom + import + + + com.google.http-client + google-http-client-bom + ${http-client-bom.version} + pom + import + + + com.google.guava + guava-bom + ${guava.version} + pom + import + + + com.google.auth + google-auth-library-bom + ${google.auth.version} + pom + import + + + com.google.errorprone + error_prone_annotations + ${error-prone.version} + + + com.google.protobuf + protobuf-java + ${protobuf.version} + + + org.hamcrest + hamcrest-core + ${hamcrest.version} + test + + + + - com.google.cloud - google-cloud-spanner - 1.47.0 + com.google.api.grpc + proto-google-common-protos + ${google.common-protos.version} com.google.cloud google-cloud-spanner - 1.47.0 - test-jar - test + ${spanner.version} + + + com.google.protobuf + protobuf-java + ${protobuf.version} + + + com.google.guava + guava + ${guava.version} com.google.api - gax-grpc - testlib + gax + ${gax.version} + + + org.threeten + threetenbp + ${threeten.version} + + + io.grpc + grpc-api + ${grpc.version} + + + com.google.api + api-common + ${google.api-common.version} + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.google.http-client + google-http-client + ${http-client-bom.version} + + + com.google.auth + google-auth-library-oauth2-http + ${google.auth.version} + + + com.google.cloud + google-cloud-core + ${google.core.version} + + + com.google.code.gson + gson + 2.8.6 + + + com.google.auth + google-auth-library-credentials + ${google.auth.version} + + + org.apache.commons + commons-lang3 + 3.5 + + + com.google.api.grpc + proto-google-cloud-spanner-v1 + ${spanner.version} + + + com.google.api.grpc + proto-google-cloud-spanner-admin-database-v1 + ${spanner.version} + + + com.google.protobuf + protobuf-java-util + ${protobuf.version} + + + + com.google.cloud + google-cloud-spanner + ${spanner.version} + test-jar test com.google.truth truth + 1.0 test org.mockito mockito-core - 1.9.5 + 1.10.19 + test + + + org.hamcrest + hamcrest + ${hamcrest.version} + test + + + junit + junit + ${junit.version} + test + + + io.grpc + grpc-netty-shaded + ${grpc.version} + test + + + com.google.api + gax-grpc + ${gax.version} + testlib test @@ -64,7 +296,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.0.0-M3 + 3.0.0-M4 com.google.cloud.spanner.GceTestEnvConfig @@ -83,6 +315,17 @@ + + + + org.apache.maven.plugins + maven-dependency-plugin + + com.google.api:gax-grpc + + + + @@ -186,4 +429,73 @@ + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 3.0.0 + + + + index + dependency-info + team + ci-management + issue-management + licenses + scm + dependency-management + distribution-management + summary + modules + + + + + true + ${site.installationModule} + jar + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.1 + + + html + + aggregate + javadoc + + + + + none + protected + true + ${project.build.directory}/javadoc + + + Test helpers packages + com.google.cloud.testing + + + SPI packages + com.google.cloud.spi* + + + + + https://grpc.io/grpc-java/javadoc/ + https://developers.google.com/protocol-buffers/docs/reference/java/ + https://googleapis.dev/java/google-auth-library/latest/ + https://googleapis.dev/java/gax/latest/ + https://googleapis.github.io/api-common-java/${google.api-common.version}/apidocs/ + + + + + diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..a5cdff45c --- /dev/null +++ b/renovate.json @@ -0,0 +1,70 @@ +{ + "extends": [ + ":separateMajorReleases", + ":combinePatchMinorReleases", + ":ignoreUnstable", + ":prImmediately", + ":updateNotScheduled", + ":automergeDisabled", + ":ignoreModulesAndTests", + ":maintainLockFilesDisabled", + ":autodetectPinVersions" + ], + "packageRules": [ + { + "packagePatterns": [ + "^com.google.guava:" + ], + "versionScheme": "docker" + }, + { + "packagePatterns": [ + "^com.google.api:gax", + "^com.google.auth:", + "^com.google.cloud:google-cloud-core", + "^io.grpc:" + ], + "groupName": "core dependencies" + }, + { + "packagePatterns": [ + "^com.google.http-client:", + "^com.google.oauth-client:", + "^com.google.api-client:" + ], + "groupName": "core transport dependencies" + }, + { + "packagePatterns": [ + "*" + ], + "semanticCommitType": "deps", + "semanticCommitScope": null + }, + { + "packagePatterns": [ + "^org.apache.maven", + "^org.jacoco:", + "^org.codehaus.mojo:", + "^org.sonatype.plugins:", + "^com.coveo:", + "^com.google.cloud:google-cloud-shared-config" + ], + "semanticCommitType": "build", + "semanticCommitScope": "deps" + }, + { + "packagePatterns": [ + "^com.google.cloud:google-cloud-" + ], + "ignoreUnstable": false + }, + { + "packagePatterns": [ + "^com.fasterxml.jackson.core" + ], + "groupName": "jackson dependencies" + } + ], + "semanticCommits": true +} diff --git a/src/main/java/com/google/cloud/spanner/jdbc/ConnectionOptions.java b/src/main/java/com/google/cloud/spanner/jdbc/ConnectionOptions.java index 3b03aca5e..f2e4358d6 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/ConnectionOptions.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/ConnectionOptions.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.jdbc; import com.google.auth.Credentials; +import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.cloud.NoCredentials; @@ -140,6 +141,7 @@ public String[] getValidValues() { static final boolean DEFAULT_READONLY = false; static final boolean DEFAULT_RETRY_ABORTS_INTERNALLY = true; private static final String DEFAULT_CREDENTIALS = null; + private static final String DEFAULT_OAUTH_TOKEN = null; private static final String DEFAULT_NUM_CHANNELS = null; private static final String DEFAULT_USER_AGENT = null; @@ -156,6 +158,10 @@ public String[] getValidValues() { public static final String RETRY_ABORTS_INTERNALLY_PROPERTY_NAME = "retryAbortsInternally"; /** Name of the 'credentials' connection property. */ public static final String CREDENTIALS_PROPERTY_NAME = "credentials"; + /** + * OAuth token to use for authentication. Cannot be used in combination with a credentials file. + */ + public static final String OAUTH_TOKEN_PROPERTY_NAME = "oauthToken"; /** Name of the 'numChannels' connection property. */ public static final String NUM_CHANNELS_PROPERTY_NAME = "numChannels"; /** Custom user agent string is only for other Google libraries. */ @@ -173,6 +179,7 @@ public String[] getValidValues() { ConnectionProperty.createBooleanProperty( RETRY_ABORTS_INTERNALLY_PROPERTY_NAME, "", DEFAULT_RETRY_ABORTS_INTERNALLY), ConnectionProperty.createStringProperty(CREDENTIALS_PROPERTY_NAME, ""), + ConnectionProperty.createStringProperty(OAUTH_TOKEN_PROPERTY_NAME, ""), ConnectionProperty.createStringProperty(NUM_CHANNELS_PROPERTY_NAME, ""), ConnectionProperty.createBooleanProperty( USE_PLAIN_TEXT_PROPERTY_NAME, "", DEFAULT_USE_PLAIN_TEXT), @@ -223,6 +230,7 @@ public static void closeSpanner() { public static class Builder { private String uri; private String credentialsUrl; + private String oauthToken; private Credentials credentials; private List statementExecutionInterceptors = Collections.emptyList(); @@ -231,7 +239,7 @@ private Builder() {} /** Spanner {@link ConnectionOptions} URI format. */ public static final String SPANNER_URI_FORMAT = - "(?:cloudspanner:)(?//[\\w.-]+(?:\\.[\\w\\.-]+)*[\\w\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=.]+)?/projects/(?(([a-z]|[-]|[0-9])+|(DEFAULT_PROJECT_ID)))(/instances/(?([a-z]|[-]|[0-9])+)(/databases/(?([a-z]|[-]|[_]|[0-9])+))?)?(?:[?|;].*)?"; + "(?:cloudspanner:)(?//[\\w.-]+(?:\\.[\\w\\.-]+)*[\\w\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=.]+)?/projects/(?(([a-z]|[-.:]|[0-9])+|(DEFAULT_PROJECT_ID)))(/instances/(?([a-z]|[-]|[0-9])+)(/databases/(?([a-z]|[-]|[_]|[0-9])+))?)?(?:[?|;].*)?"; private static final String SPANNER_URI_REGEX = "(?is)^" + SPANNER_URI_FORMAT + "$"; private static final Pattern SPANNER_URI_PATTERN = Pattern.compile(SPANNER_URI_REGEX); @@ -308,6 +316,22 @@ public Builder setCredentialsUrl(String credentialsUrl) { return this; } + /** + * Sets the OAuth token to use with this connection. The token must be a valid token with access + * to the resources (project/instance/database) that the connection will be accessing. This + * authentication method cannot be used in combination with a credentials file. If both an OAuth + * token and a credentials file is specified, the {@link #build()} method will throw an + * exception. + * + * @param oauthToken A valid OAuth token for the Google Cloud project that is used by this + * connection. + * @return this builder + */ + public Builder setOAuthToken(String oauthToken) { + this.oauthToken = oauthToken; + return this; + } + @VisibleForTesting Builder setStatementExecutionInterceptors(List interceptors) { this.statementExecutionInterceptors = interceptors; @@ -339,6 +363,7 @@ public static Builder newBuilder() { private final String uri; private final String credentialsUrl; + private final String oauthToken; private final boolean usePlainText; private final String host; @@ -363,6 +388,13 @@ private ConnectionOptions(Builder builder) { this.uri = builder.uri; this.credentialsUrl = builder.credentialsUrl != null ? builder.credentialsUrl : parseCredentials(builder.uri); + this.oauthToken = + builder.oauthToken != null ? builder.oauthToken : parseOAuthToken(builder.uri); + // Check that not both credentials and an OAuth token have been specified. + Preconditions.checkArgument( + (builder.credentials == null && this.credentialsUrl == null) || this.oauthToken == null, + "Cannot specify both credentials and an OAuth token."); + this.usePlainText = parseUsePlainText(this.uri); this.userAgent = parseUserAgent(this.uri); @@ -376,8 +408,13 @@ private ConnectionOptions(Builder builder) { // Using credentials on a plain text connection is not allowed, so if the user has not specified // any credentials and is using a plain text connection, we should not try to get the // credentials from the environment, but default to NoCredentials. - if (builder.credentials == null && this.credentialsUrl == null && this.usePlainText) { + if (builder.credentials == null + && this.credentialsUrl == null + && this.oauthToken == null + && this.usePlainText) { this.credentials = NoCredentials.getInstance(); + } else if (this.oauthToken != null) { + this.credentials = new GoogleCredentials(new AccessToken(oauthToken, null)); } else { this.credentials = builder.credentials == null @@ -446,6 +483,12 @@ static String parseCredentials(String uri) { return value != null ? value : DEFAULT_CREDENTIALS; } + @VisibleForTesting + static String parseOAuthToken(String uri) { + String value = parseUriProperty(uri, OAUTH_TOKEN_PROPERTY_NAME); + return value != null ? value : DEFAULT_OAUTH_TOKEN; + } + @VisibleForTesting static String parseNumChannels(String uri) { String value = parseUriProperty(uri, NUM_CHANNELS_PROPERTY_NAME); diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java index 80ee2cc6d..c43f9797e 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java @@ -74,6 +74,12 @@ *
  • credentials (String): URL for the credentials file to use for the connection. If you do not * specify any credentials at all, the default credentials of the environment as returned by * {@link GoogleCredentials#getApplicationDefault()} will be used. + *
  • oauthtoken (String): A valid OAuth2 token to use for the JDBC connection. The token must + * have been obtained with one or both of the scopes + * 'https://www.googleapis.com/auth/spanner.admin' and/or + * 'https://www.googleapis.com/auth/spanner.data'. If you specify both a credentials file and + * an OAuth token, the JDBC driver will throw an exception when you try to obtain a + * connection. *
  • autocommit (boolean): Sets the initial autocommit mode for the connection. Default is true. *
  • readonly (boolean): Sets the initial readonly mode for the connection. Default is false. *
  • retryAbortsInternally (boolean): Sets the initial retryAbortsInternally mode for the diff --git a/src/main/java/com/google/cloud/spanner/jdbc/StatementParser.java b/src/main/java/com/google/cloud/spanner/jdbc/StatementParser.java index 9ed1ecd23..e43a0974a 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/StatementParser.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/StatementParser.java @@ -161,7 +161,7 @@ ClientSideStatement getClientSideStatement() { } private final Set ddlStatements = ImmutableSet.of("CREATE", "DROP", "ALTER"); - private final Set selectStatements = ImmutableSet.of("SELECT"); + private final Set selectStatements = ImmutableSet.of("SELECT", "WITH"); private final Set dmlStatements = ImmutableSet.of("INSERT", "UPDATE", "DELETE"); private final Set statements; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AbortedTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AbortedTest.java index af5fcdceb..4346bde5c 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AbortedTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AbortedTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.MockSpannerServiceImpl; import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AbstractConnectionImplTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AbstractConnectionImplTest.java index 798a4d2b7..8b4bdf78d 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AbstractConnectionImplTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AbstractConnectionImplTest.java @@ -22,7 +22,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.Timestamp; import com.google.cloud.spanner.ErrorCode; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcResultSetTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcResultSetTest.java index a267d224f..960287cee 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcResultSetTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcResultSetTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AbstractSqlScriptVerifier.java b/src/test/java/com/google/cloud/spanner/jdbc/AbstractSqlScriptVerifier.java index 71a1865b8..3e854d3e1 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AbstractSqlScriptVerifier.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AbstractSqlScriptVerifier.java @@ -21,8 +21,8 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import com.google.cloud.Timestamp; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeConverterTest.java index 91b54a961..4dcbd410e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeConverterTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.jdbc.ClientSideStatementImpl.CompileException; import com.google.cloud.spanner.jdbc.ClientSideStatementValueConverters.AutocommitDmlModeConverter; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeTest.java index cf7ba02e3..bf350419d 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner.jdbc; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/BooleanConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/BooleanConverterTest.java index 4c9447fb1..f86295be6 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/BooleanConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/BooleanConverterTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.jdbc.ClientSideStatementImpl.CompileException; import com.google.cloud.spanner.jdbc.ClientSideStatementValueConverters.BooleanConverter; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTest.java index 87190f715..38c978766 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTest.java @@ -23,7 +23,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyString; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ConnectionOptionsTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ConnectionOptionsTest.java index 1435cd1d9..8eacbbf3a 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ConnectionOptionsTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ConnectionOptionsTest.java @@ -16,10 +16,8 @@ package com.google.cloud.spanner.jdbc; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; @@ -35,6 +33,23 @@ public class ConnectionOptionsTest { ConnectionOptionsTest.class.getResource("test-key.json").getFile(); private static final String DEFAULT_HOST = "https://spanner.googleapis.com"; + @Test + public void testBuildWithURIWithDots() { + ConnectionOptions.Builder builder = ConnectionOptions.newBuilder(); + builder.setUri( + "cloudspanner:/projects/some-company.com:test-project-123/instances/test-instance-123/databases/test-database-123"); + builder.setCredentialsUrl(FILE_TEST_PATH); + ConnectionOptions options = builder.build(); + assertThat(options.getHost()).isEqualTo(DEFAULT_HOST); + assertThat(options.getProjectId()).isEqualTo("some-company.com:test-project-123"); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(ConnectionOptions.DEFAULT_AUTOCOMMIT); + assertThat(options.isReadOnly()).isEqualTo(ConnectionOptions.DEFAULT_READONLY); + } + @Test public void testBuildWithValidURIAndCredentialsFileURL() { ConnectionOptions.Builder builder = ConnectionOptions.newBuilder(); @@ -42,15 +57,14 @@ public void testBuildWithValidURIAndCredentialsFileURL() { "cloudspanner:/projects/test-project-123/instances/test-instance-123/databases/test-database-123"); builder.setCredentialsUrl(FILE_TEST_PATH); ConnectionOptions options = builder.build(); - assertThat(options.getHost(), is(equalTo(DEFAULT_HOST))); - assertThat(options.getProjectId(), is(equalTo("test-project-123"))); - assertThat(options.getInstanceId(), is(equalTo("test-instance-123"))); - assertThat(options.getDatabaseName(), is(equalTo("test-database-123"))); - assertThat( - (GoogleCredentials) options.getCredentials(), - is(equalTo(new CredentialsService().createCredentials(FILE_TEST_PATH)))); - assertThat(options.isAutocommit(), is(equalTo(ConnectionOptions.DEFAULT_AUTOCOMMIT))); - assertThat(options.isReadOnly(), is(equalTo(ConnectionOptions.DEFAULT_READONLY))); + assertThat(options.getHost()).isEqualTo(DEFAULT_HOST); + assertThat(options.getProjectId()).isEqualTo("test-project-123"); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(ConnectionOptions.DEFAULT_AUTOCOMMIT); + assertThat(options.isReadOnly()).isEqualTo(ConnectionOptions.DEFAULT_READONLY); } @Test @@ -60,15 +74,14 @@ public void testBuildWithValidURIAndProperties() { "cloudspanner:/projects/test-project-123/instances/test-instance-123/databases/test-database-123?autocommit=false;readonly=true"); builder.setCredentialsUrl(FILE_TEST_PATH); ConnectionOptions options = builder.build(); - assertThat(options.getHost(), is(equalTo(DEFAULT_HOST))); - assertThat(options.getProjectId(), is(equalTo("test-project-123"))); - assertThat(options.getInstanceId(), is(equalTo("test-instance-123"))); - assertThat(options.getDatabaseName(), is(equalTo("test-database-123"))); - assertThat( - (GoogleCredentials) options.getCredentials(), - is(equalTo(new CredentialsService().createCredentials(FILE_TEST_PATH)))); - assertThat(options.isAutocommit(), is(equalTo(false))); - assertThat(options.isReadOnly(), is(equalTo(true))); + assertThat(options.getHost()).isEqualTo(DEFAULT_HOST); + assertThat(options.getProjectId()).isEqualTo("test-project-123"); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(false); + assertThat(options.isReadOnly()).isEqualTo(true); } @Test @@ -78,15 +91,14 @@ public void testBuildWithHostAndValidURI() { "cloudspanner://test-spanner.googleapis.com/projects/test-project-123/instances/test-instance-123/databases/test-database-123"); builder.setCredentialsUrl(FILE_TEST_PATH); ConnectionOptions options = builder.build(); - assertThat(options.getHost(), is(equalTo("https://test-spanner.googleapis.com"))); - assertThat(options.getProjectId(), is(equalTo("test-project-123"))); - assertThat(options.getInstanceId(), is(equalTo("test-instance-123"))); - assertThat(options.getDatabaseName(), is(equalTo("test-database-123"))); - assertThat( - (GoogleCredentials) options.getCredentials(), - is(equalTo(new CredentialsService().createCredentials(FILE_TEST_PATH)))); - assertThat(options.isAutocommit(), is(equalTo(ConnectionOptions.DEFAULT_AUTOCOMMIT))); - assertThat(options.isReadOnly(), is(equalTo(ConnectionOptions.DEFAULT_READONLY))); + assertThat(options.getHost()).isEqualTo("https://test-spanner.googleapis.com"); + assertThat(options.getProjectId()).isEqualTo("test-project-123"); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(ConnectionOptions.DEFAULT_AUTOCOMMIT); + assertThat(options.isReadOnly()).isEqualTo(ConnectionOptions.DEFAULT_READONLY); } @Test @@ -96,15 +108,14 @@ public void testBuildWithLocalhostPortAndValidURI() { "cloudspanner://localhost:8443/projects/test-project-123/instances/test-instance-123/databases/test-database-123"); builder.setCredentialsUrl(FILE_TEST_PATH); ConnectionOptions options = builder.build(); - assertThat(options.getHost(), is(equalTo("https://localhost:8443"))); - assertThat(options.getProjectId(), is(equalTo("test-project-123"))); - assertThat(options.getInstanceId(), is(equalTo("test-instance-123"))); - assertThat(options.getDatabaseName(), is(equalTo("test-database-123"))); - assertThat( - (GoogleCredentials) options.getCredentials(), - is(equalTo(new CredentialsService().createCredentials(FILE_TEST_PATH)))); - assertThat(options.isAutocommit(), is(equalTo(ConnectionOptions.DEFAULT_AUTOCOMMIT))); - assertThat(options.isReadOnly(), is(equalTo(ConnectionOptions.DEFAULT_READONLY))); + assertThat(options.getHost()).isEqualTo("https://localhost:8443"); + assertThat(options.getProjectId()).isEqualTo("test-project-123"); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(ConnectionOptions.DEFAULT_AUTOCOMMIT); + assertThat(options.isReadOnly()).isEqualTo(ConnectionOptions.DEFAULT_READONLY); } @Test @@ -114,21 +125,20 @@ public void testBuildWithDefaultProjectPlaceholder() { "cloudspanner:/projects/default_project_id/instances/test-instance-123/databases/test-database-123"); builder.setCredentialsUrl(FILE_TEST_PATH); ConnectionOptions options = builder.build(); - assertThat(options.getHost(), is(equalTo(DEFAULT_HOST))); + assertThat(options.getHost()).isEqualTo(DEFAULT_HOST); String projectId = SpannerOptions.getDefaultProjectId(); if (projectId == null) { projectId = ((ServiceAccountCredentials) new CredentialsService().createCredentials(FILE_TEST_PATH)) .getProjectId(); } - assertThat(options.getProjectId(), is(equalTo(projectId))); - assertThat(options.getInstanceId(), is(equalTo("test-instance-123"))); - assertThat(options.getDatabaseName(), is(equalTo("test-database-123"))); - assertThat( - (GoogleCredentials) options.getCredentials(), - is(equalTo(new CredentialsService().createCredentials(FILE_TEST_PATH)))); - assertThat(options.isAutocommit(), is(equalTo(ConnectionOptions.DEFAULT_AUTOCOMMIT))); - assertThat(options.isReadOnly(), is(equalTo(ConnectionOptions.DEFAULT_READONLY))); + assertThat(options.getProjectId()).isEqualTo(projectId); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(ConnectionOptions.DEFAULT_AUTOCOMMIT); + assertThat(options.isReadOnly()).isEqualTo(ConnectionOptions.DEFAULT_READONLY); } @Test @@ -203,24 +213,21 @@ public void testBuilderSetUri() { } private void setInvalidUri(ConnectionOptions.Builder builder, String uri) { - boolean invalid = false; try { builder.setUri(uri); + fail(uri + " should be considered an invalid uri"); } catch (IllegalArgumentException e) { - invalid = true; } - assertThat(uri + " should be considered an invalid uri", invalid, is(true)); } private void setInvalidProperty( ConnectionOptions.Builder builder, String uri, String expectedInvalidProperties) { - boolean invalid = false; try { builder.setUri(uri); + fail("missing expected exception"); } catch (IllegalArgumentException e) { - invalid = e.getMessage().contains(expectedInvalidProperties); + assertThat(e.getMessage()).contains(expectedInvalidProperties); } - assertThat(uri + " should contain invalid properties", invalid, is(true)); } @Test @@ -228,86 +235,72 @@ public void testParseUriProperty() { final String baseUri = "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database"; - assertThat(ConnectionOptions.parseUriProperty(baseUri, "autocommit"), is(nullValue())); - assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?autocommit=true", "autocommit"), - is(equalTo("true"))); - assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?autocommit=false", "autocommit"), - is(equalTo("false"))); + assertThat(ConnectionOptions.parseUriProperty(baseUri, "autocommit")).isNull(); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?autocommit=true", "autocommit")) + .isEqualTo("true"); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?autocommit=false", "autocommit")) + .isEqualTo("false"); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?autocommit=true;", "autocommit")) + .isEqualTo("true"); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?autocommit=false;", "autocommit")) + .isEqualTo("false"); assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?autocommit=true;", "autocommit"), - is(equalTo("true"))); + ConnectionOptions.parseUriProperty( + baseUri + "?autocommit=true;readOnly=false", "autocommit")) + .isEqualTo("true"); assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?autocommit=false;", "autocommit"), - is(equalTo("false"))); + ConnectionOptions.parseUriProperty( + baseUri + "?autocommit=false;readOnly=false", "autocommit")) + .isEqualTo("false"); assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?autocommit=true;readOnly=false", "autocommit"), - is(equalTo("true"))); + ConnectionOptions.parseUriProperty( + baseUri + "?readOnly=false;autocommit=true", "autocommit")) + .isEqualTo("true"); assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?autocommit=false;readOnly=false", "autocommit"), - is(equalTo("false"))); + ConnectionOptions.parseUriProperty( + baseUri + "?readOnly=false;autocommit=false", "autocommit")) + .isEqualTo("false"); assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?readOnly=false;autocommit=true", "autocommit"), - is(equalTo("true"))); + ConnectionOptions.parseUriProperty( + baseUri + "?readOnly=false;autocommit=true;foo=bar", "autocommit")) + .isEqualTo("true"); assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?readOnly=false;autocommit=false", "autocommit"), - is(equalTo("false"))); - assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?readOnly=false;autocommit=true;foo=bar", "autocommit"), - is(equalTo("true"))); - assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?readOnly=false;autocommit=false;foo=bar", "autocommit"), - is(equalTo("false"))); + ConnectionOptions.parseUriProperty( + baseUri + "?readOnly=false;autocommit=false;foo=bar", "autocommit")) + .isEqualTo("false"); // case insensitive - assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?AutoCommit=true", "autocommit"), - is(equalTo("true"))); - assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?AutoCommit=false", "autocommit"), - is(equalTo("false"))); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?AutoCommit=true", "autocommit")) + .isEqualTo("true"); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?AutoCommit=false", "autocommit")) + .isEqualTo("false"); // ; instead of ? before the properties is ok - assertThat( - ConnectionOptions.parseUriProperty(baseUri + ";autocommit=true", "autocommit"), - is(equalTo("true"))); + assertThat(ConnectionOptions.parseUriProperty(baseUri + ";autocommit=true", "autocommit")) + .isEqualTo("true"); // forgot the ? or ; before the properties - assertThat( - ConnectionOptions.parseUriProperty(baseUri + "autocommit=true", "autocommit"), - is(nullValue())); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "autocommit=true", "autocommit")) + .isNull(); // substring is not ok - assertThat( - ConnectionOptions.parseUriProperty(baseUri + "?isautocommit=true", "autocommit"), - is(nullValue())); + assertThat(ConnectionOptions.parseUriProperty(baseUri + "?isautocommit=true", "autocommit")) + .isNull(); } @Test public void testParseProperties() { final String baseUri = "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database"; - assertThat( - ConnectionOptions.parseProperties(baseUri + "?autocommit=true"), - is(equalTo(Arrays.asList("autocommit")))); - assertThat( - ConnectionOptions.parseProperties(baseUri + "?autocommit=true;readonly=false"), - is(equalTo(Arrays.asList("autocommit", "readonly")))); - assertThat( - ConnectionOptions.parseProperties(baseUri + "?autocommit=true;READONLY=false"), - is(equalTo(Arrays.asList("autocommit", "READONLY")))); - assertThat( - ConnectionOptions.parseProperties(baseUri + ";autocommit=true;readonly=false"), - is(equalTo(Arrays.asList("autocommit", "readonly")))); - assertThat( - ConnectionOptions.parseProperties(baseUri + ";autocommit=true;readonly=false;"), - is(equalTo(Arrays.asList("autocommit", "readonly")))); + assertThat(ConnectionOptions.parseProperties(baseUri + "?autocommit=true")) + .isEqualTo(Arrays.asList("autocommit")); + assertThat(ConnectionOptions.parseProperties(baseUri + "?autocommit=true;readonly=false")) + .isEqualTo(Arrays.asList("autocommit", "readonly")); + assertThat(ConnectionOptions.parseProperties(baseUri + "?autocommit=true;READONLY=false")) + .isEqualTo(Arrays.asList("autocommit", "READONLY")); + assertThat(ConnectionOptions.parseProperties(baseUri + ";autocommit=true;readonly=false")) + .isEqualTo(Arrays.asList("autocommit", "readonly")); + assertThat(ConnectionOptions.parseProperties(baseUri + ";autocommit=true;readonly=false;")) + .isEqualTo(Arrays.asList("autocommit", "readonly")); } @Test @@ -315,20 +308,82 @@ public void testParsePropertiesSpecifiedMultipleTimes() { final String baseUri = "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database"; assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?autocommit=true;autocommit=false", "autocommit"), - is(equalTo("true"))); + ConnectionOptions.parseUriProperty( + baseUri + "?autocommit=true;autocommit=false", "autocommit")) + .isEqualTo("true"); assertThat( - ConnectionOptions.parseUriProperty( - baseUri + "?autocommit=false;autocommit=true", "autocommit"), - is(equalTo("false"))); + ConnectionOptions.parseUriProperty( + baseUri + "?autocommit=false;autocommit=true", "autocommit")) + .isEqualTo("false"); assertThat( - ConnectionOptions.parseUriProperty( - baseUri + ";autocommit=false;readonly=false;autocommit=true", "autocommit"), - is(equalTo("false"))); + ConnectionOptions.parseUriProperty( + baseUri + ";autocommit=false;readonly=false;autocommit=true", "autocommit")) + .isEqualTo("false"); ConnectionOptions.newBuilder() .setUri( "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database" + ";autocommit=false;readonly=false;autocommit=true"); } + + @Test + public void testParseOAuthToken() { + assertThat( + ConnectionOptions.parseUriProperty( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database" + + "?oauthtoken=RsT5OjbzRn430zqMLgV3Ia", + "OAuthToken")) + .isEqualTo("RsT5OjbzRn430zqMLgV3Ia"); + // Try to use both credentials and an OAuth token. That should fail. + ConnectionOptions.Builder builder = + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database" + + "?OAuthToken=RsT5OjbzRn430zqMLgV3Ia;credentials=/path/to/credentials.json"); + try { + builder.build(); + fail("missing expected exception"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage()).contains("Cannot specify both credentials and an OAuth token"); + } + + // Now try to use only an OAuth token. + builder = + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database" + + "?OAuthToken=RsT5OjbzRn430zqMLgV3Ia"); + ConnectionOptions options = builder.build(); + assertThat(options.getCredentials()).isInstanceOf(GoogleCredentials.class); + GoogleCredentials credentials = (GoogleCredentials) options.getCredentials(); + assertThat(credentials.getAccessToken().getTokenValue()).isEqualTo("RsT5OjbzRn430zqMLgV3Ia"); + } + + @Test + public void testSetOAuthToken() { + ConnectionOptions options = + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database") + .setOAuthToken("RsT5OjbzRn430zqMLgV3Ia") + .build(); + assertThat(options.getCredentials()).isInstanceOf(GoogleCredentials.class); + GoogleCredentials credentials = (GoogleCredentials) options.getCredentials(); + assertThat(credentials.getAccessToken()).isNotNull(); + assertThat(credentials.getAccessToken().getTokenValue()).isEqualTo("RsT5OjbzRn430zqMLgV3Ia"); + } + + @Test + public void testSetOAuthTokenAndCredentials() { + try { + ConnectionOptions.newBuilder() + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database") + .setOAuthToken("RsT5OjbzRn430zqMLgV3Ia") + .setCredentialsUrl(FILE_TEST_PATH) + .build(); + fail("missing expected exception"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage()).contains("Cannot specify both credentials and an OAuth token"); + } + } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutorTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutorTest.java index 1709ca408..debd02b84 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutorTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutorTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/CredentialsServiceTest.java b/src/test/java/com/google/cloud/spanner/jdbc/CredentialsServiceTest.java index fbc35f728..268d4a1a0 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/CredentialsServiceTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/CredentialsServiceTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import com.google.auth.oauth2.GoogleCredentials; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/DdlBatchTest.java b/src/test/java/com/google/cloud/spanner/jdbc/DdlBatchTest.java index 3700f4c71..76a5cc5bf 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/DdlBatchTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/DdlBatchTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyString; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/DirectExecuteResultSetTest.java b/src/test/java/com/google/cloud/spanner/jdbc/DirectExecuteResultSetTest.java index b138b1e62..533c417b4 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/DirectExecuteResultSetTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/DirectExecuteResultSetTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner.jdbc; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/DmlBatchTest.java b/src/test/java/com/google/cloud/spanner/jdbc/DmlBatchTest.java index e6c54d115..b8a96cda9 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/DmlBatchTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/DmlBatchTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner.jdbc; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/DurationConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/DurationConverterTest.java index 073f33f31..77b41e9d0 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/DurationConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/DurationConverterTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.jdbc.ClientSideStatementImpl.CompileException; import com.google.cloud.spanner.jdbc.ClientSideStatementValueConverters.DurationConverter; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcAbortedTransactionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcAbortedTransactionTest.java index f55e383be..7b9c4d050 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcAbortedTransactionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcAbortedTransactionTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import com.google.cloud.Timestamp; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcBlobTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcBlobTest.java index c629eac20..46b85fe2d 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcBlobTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcBlobTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.rpc.Code; import java.io.IOException; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcClobTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcClobTest.java index 3bb04fc63..87011ab41 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcClobTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcClobTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.rpc.Code; import java.io.IOException; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java index 6740782a4..3d9c77caf 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java index 6c3363be3..4b7fb713e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcDriverTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcDriverTest.java index 68c252ebe..1215434c9 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcDriverTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcDriverTest.java @@ -16,8 +16,8 @@ package com.google.cloud.spanner.jdbc; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; import com.google.cloud.spanner.MockSpannerServiceImpl; import io.grpc.Server; @@ -72,9 +72,9 @@ public void testConnect() throws SQLException { try (Connection connection = DriverManager.getConnection( String.format( - "jdbc:cloudspanner://localhost:%d/projects/test-project/instances/static-test-instance/databases/test-database;usePlainText=true;credentials=%s", + "jdbc:cloudspanner://localhost:%d/projects/some-company.com:test-project/instances/static-test-instance/databases/test-database;usePlainText=true;credentials=%s", server.getPort(), TEST_KEY_PATH))) { - assertThat(connection.isClosed(), is(false)); + assertThat(connection.isClosed()).isFalse(); } } @@ -83,9 +83,22 @@ public void testInvalidConnect() throws SQLException { try (Connection connection = DriverManager.getConnection( String.format( - "jdbc:cloudspanner://localhost:%d/projects/test-project/instances/static-test-instance/databases/test-database;usePlainText=true;credentialsUrl=%s", + "jdbc:cloudspanner://localhost:%d/projects/some-company.com:test-project/instances/static-test-instance/databases/test-database;usePlainText=true;credentialsUrl=%s", server.getPort(), TEST_KEY_PATH))) { - assertThat(connection.isClosed(), is(false)); + assertThat(connection.isClosed()).isFalse(); + } + } + + @Test + public void testConnectWithCredentialsAndOAuthToken() throws SQLException { + try (Connection connection = + DriverManager.getConnection( + String.format( + "jdbc:cloudspanner://localhost:%d/projects/test-project/instances/static-test-instance/databases/test-database;usePlainText=true;credentials=%s;OAuthToken=%s", + server.getPort(), TEST_KEY_PATH, "some-token"))) { + fail("missing expected exception"); + } catch (SQLException e) { + assertThat(e.getMessage()).contains("Cannot specify both credentials and an OAuth token"); } } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java index 336bfc1a5..cf93d69d0 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.startsWith; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import com.google.cloud.ByteArray; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java index bbfded162..c72db1ec4 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcSqlScriptVerifier.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcSqlScriptVerifier.java index 878b3a6bb..7a4543089 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcSqlScriptVerifier.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcSqlScriptVerifier.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.startsWith; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.jdbc.StatementResult.ResultType; import com.google.rpc.Code; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcStatementTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcStatementTest.java index 648261efd..28bb25849 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcStatementTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcStatementTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java index 5978f3ac3..773fcf94e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java @@ -16,7 +16,19 @@ package com.google.cloud.spanner.jdbc; -import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.*; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.convert; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.getAsSqlTimestamp; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.setTimestampInCalendar; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toGoogleBytes; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toGoogleDate; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toGoogleDates; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toGoogleTimestamp; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toJavaByteArrays; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toSqlDate; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toSqlDates; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toSqlTime; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toSqlTimestamp; +import static com.google.cloud.spanner.jdbc.JdbcTypeConverter.toSqlTimestamps; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessConverterTest.java index 830c90851..12f1094fe 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessConverterTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.Timestamp; import com.google.cloud.spanner.TimestampBound; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessTest.java index 6c0ca2d48..bc43e2aa1 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessTest.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner.jdbc; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessUtilTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessUtilTest.java index 4c96632f3..3af641f1f 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessUtilTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessUtilTest.java @@ -23,7 +23,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.Timestamp; import com.google.cloud.spanner.ErrorCode; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyTransactionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyTransactionTest.java index fe7622d93..0642b75ae 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyTransactionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyTransactionTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ReadWriteTransactionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ReadWriteTransactionTest.java index f64ff464d..54a83c628 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ReadWriteTransactionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ReadWriteTransactionTest.java @@ -21,7 +21,7 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ReplaceableForwardingResultSetTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ReplaceableForwardingResultSetTest.java index 52c2f2600..4f90773cf 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ReplaceableForwardingResultSetTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ReplaceableForwardingResultSetTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/SingleUseTransactionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/SingleUseTransactionTest.java index b9890c5d4..720567c2e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/SingleUseTransactionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/SingleUseTransactionTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/SpannerPoolTest.java b/src/test/java/com/google/cloud/spanner/jdbc/SpannerPoolTest.java index a4b8e3724..fd6e901eb 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/SpannerPoolTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/SpannerPoolTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/SqlScriptVerifier.java b/src/test/java/com/google/cloud/spanner/jdbc/SqlScriptVerifier.java index c32f39076..df683b5ff 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/SqlScriptVerifier.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/SqlScriptVerifier.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.startsWith; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.ResultSet; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/StatementParserTest.java b/src/test/java/com/google/cloud/spanner/jdbc/StatementParserTest.java index 9bfef7546..1344a0f33 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/StatementParserTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/StatementParserTest.java @@ -19,7 +19,10 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.jdbc.ClientSideStatementImpl.CompileException; @@ -263,6 +266,27 @@ public void testIsQuery() { assertTrue(parser.isQuery("select * from foo")); assertFalse(parser.isQuery("INSERT INTO FOO (ID, NAME) SELECT ID+1, NAME FROM FOO")); + assertTrue( + parser.isQuery( + "WITH subQ1 AS (SELECT SchoolID FROM Roster),\n" + + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" + + "SELECT * FROM subQ1\n" + + "UNION ALL\n" + + "SELECT * FROM subQ2")); + assertTrue( + parser.isQuery( + "with subQ1 AS (SELECT SchoolID FROM Roster),\n" + + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" + + "select * FROM subQ1\n" + + "UNION ALL\n" + + "SELECT * FROM subQ2")); + assertTrue( + parser + .parse( + Statement.of( + "-- this is a comment\nwith foo as (select * from bar)\nselect * from foo")) + .isQuery()); + assertTrue(parser.parse(Statement.of("-- this is a comment\nselect * from foo")).isQuery()); assertTrue( parser @@ -307,6 +331,13 @@ public void testQueryHints() { assertTrue( parser.isQuery( "@{JOIN_METHOD=HASH_JOIN}\n /* Multi line comment\n with more comments\n */SELECT * FROM PersonsTable")); + assertTrue( + parser.isQuery( + "@{JOIN_METHOD=HASH_JOIN} WITH subQ1 AS (SELECT SchoolID FROM Roster),\n" + + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" + + "SELECT * FROM subQ1\n" + + "UNION ALL\n" + + "SELECT * FROM subQ2")); // Invalid query hints. assertFalse(parser.isQuery("@{JOIN_METHOD=HASH_JOIN SELECT * FROM PersonsTable")); diff --git a/src/test/java/com/google/cloud/spanner/jdbc/StatementResultImplTest.java b/src/test/java/com/google/cloud/spanner/jdbc/StatementResultImplTest.java index a9f06ce57..ea0b751a6 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/StatementResultImplTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/StatementResultImplTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; import com.google.cloud.Timestamp; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/StatementTimeoutTest.java b/src/test/java/com/google/cloud/spanner/jdbc/StatementTimeoutTest.java index 03eb5a1b6..5a6fb740c 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/StatementTimeoutTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/StatementTimeoutTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.doAnswer; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/TransactionModeConverterTest.java b/src/test/java/com/google/cloud/spanner/jdbc/TransactionModeConverterTest.java index 8e14e6087..60df4fdda 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/TransactionModeConverterTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/TransactionModeConverterTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.jdbc.ClientSideStatementImpl.CompileException; import com.google.cloud.spanner.jdbc.ClientSideStatementValueConverters.TransactionModeConverter; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITBulkConnectionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITBulkConnectionTest.java index a99b5ada6..134963660 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITBulkConnectionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITBulkConnectionTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.IntegrationTest; import com.google.cloud.spanner.ResultSet; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcConnectTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcConnectTest.java index cef3148e3..580bfff98 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcConnectTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcConnectTest.java @@ -16,14 +16,16 @@ package com.google.cloud.spanner.jdbc.it; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static com.google.common.truth.Truth.assertThat; +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.spanner.IntegrationTest; +import com.google.cloud.spanner.SpannerOptions; import com.google.cloud.spanner.jdbc.CloudSpannerJdbcConnection; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; import com.google.cloud.spanner.jdbc.JdbcDataSource; +import java.io.FileInputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; @@ -57,30 +59,30 @@ private String createBaseUrl() { } private void testDefaultConnection(Connection connection) throws SQLException { - assertThat(connection.isWrapperFor(CloudSpannerJdbcConnection.class), is(true)); + assertThat(connection.isWrapperFor(CloudSpannerJdbcConnection.class)).isTrue(); CloudSpannerJdbcConnection cs = connection.unwrap(CloudSpannerJdbcConnection.class); - assertThat(cs.getAutoCommit(), is(true)); - assertThat(cs.isReadOnly(), is(false)); + assertThat(cs.getAutoCommit()).isTrue(); + assertThat(cs.isReadOnly()).isFalse(); try (ResultSet rs = connection.createStatement().executeQuery("SELECT 1")) { - assertThat(rs.next(), is(true)); - assertThat(rs.getInt(1), is(equalTo(1))); + assertThat(rs.next()).isTrue(); + assertThat(rs.getInt(1)).isEqualTo(1); } cs.setAutoCommit(false); - assertThat(cs.isRetryAbortsInternally(), is(true)); + assertThat(cs.isRetryAbortsInternally()).isTrue(); } private void testNonDefaultConnection(Connection connection) throws SQLException { - assertThat(connection.isWrapperFor(CloudSpannerJdbcConnection.class), is(true)); + assertThat(connection.isWrapperFor(CloudSpannerJdbcConnection.class)).isTrue(); CloudSpannerJdbcConnection cs = connection.unwrap(CloudSpannerJdbcConnection.class); - assertThat(cs.getAutoCommit(), is(false)); - assertThat(cs.isReadOnly(), is(true)); + assertThat(cs.getAutoCommit()).isFalse(); + assertThat(cs.isReadOnly()).isTrue(); try (ResultSet rs = connection.createStatement().executeQuery("SELECT 1")) { - assertThat(rs.next(), is(true)); - assertThat(rs.getInt(1), is(equalTo(1))); + assertThat(rs.next()).isTrue(); + assertThat(rs.getInt(1)).isEqualTo(1); } connection.commit(); cs.setReadOnly(false); - assertThat(cs.isRetryAbortsInternally(), is(false)); + assertThat(cs.isRetryAbortsInternally()).isFalse(); } @Test @@ -194,4 +196,21 @@ public void testConnectWithDataSourceWithConflictingValues() throws SQLException testNonDefaultConnection(connection); } } + + @Test + public void testConnectWithOAuthToken() throws Exception { + GoogleCredentials credentials; + if (hasValidKeyFile()) { + credentials = GoogleCredentials.fromStream(new FileInputStream(getKeyFile())); + } else { + credentials = GoogleCredentials.getApplicationDefault(); + } + credentials = credentials.createScoped(SpannerOptions.getDefaultInstance().getScopes()); + AccessToken token = credentials.refreshAccessToken(); + String urlWithOAuth = createBaseUrl() + "?OAuthToken=" + token.getTokenValue(); + try (Connection connectionWithOAuth = DriverManager.getConnection(urlWithOAuth)) { + // Try to do a query using the connection created with an OAuth token. + testDefaultConnection(connectionWithOAuth); + } + } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java index 124664dc7..a43f83c48 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.IntegrationTest; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java index 40b17452d..174e76c2b 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import com.google.api.client.util.Base64; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcReadWriteAutocommitTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcReadWriteAutocommitTest.java index 315cdc17e..dba6764fc 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcReadWriteAutocommitTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcReadWriteAutocommitTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.IntegrationTest; import com.google.cloud.spanner.Mutation; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java index 4a71bfd5c..a1130f2b6 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.IntegrationTest; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java index cc1334662..f8154dc75 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.IntegrationTest; import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadOnlySpannerTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadOnlySpannerTest.java index b3aa8ea75..51882c66e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadOnlySpannerTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadOnlySpannerTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTest; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadWriteAutocommitSpannerTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadWriteAutocommitSpannerTest.java index aa464fd4b..14834cc69 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadWriteAutocommitSpannerTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITReadWriteAutocommitSpannerTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import com.google.cloud.spanner.ErrorCode; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITSqlMusicScriptTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITSqlMusicScriptTest.java index c8a0b8977..d981a3685 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITSqlMusicScriptTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITSqlMusicScriptTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.AbortedDueToConcurrentModificationException; import com.google.cloud.spanner.IntegrationTest; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionModeTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionModeTest.java index 19c204a75..219d2153a 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionModeTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionModeTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTest; diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionRetryTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionRetryTest.java index 159ca7e6c..e3fc90c4e 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionRetryTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionRetryTest.java @@ -18,7 +18,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import com.google.cloud.Timestamp; import com.google.cloud.spanner.AbortedDueToConcurrentModificationException; diff --git a/src/test/resources/com/google/cloud/spanner/jdbc/ITSqlMusicScriptTest.sql b/src/test/resources/com/google/cloud/spanner/jdbc/ITSqlMusicScriptTest.sql index 93218da97..243cdda32 100644 --- a/src/test/resources/com/google/cloud/spanner/jdbc/ITSqlMusicScriptTest.sql +++ b/src/test/resources/com/google/cloud/spanner/jdbc/ITSqlMusicScriptTest.sql @@ -668,3 +668,8 @@ WHERE SingerId=2; SELECT COUNT(*) AS ACTUAL, 0 AS EXPECTED FROM Songs WHERE SingerId=2; + +@EXPECT RESULT_SET +WITH Song2 AS (SELECT * FROM Songs WHERE SingerId=2) +SELECT COUNT(*) AS ACTUAL, 0 AS EXPECTED +FROM Song2; diff --git a/synth.metadata b/synth.metadata new file mode 100644 index 000000000..50195b614 --- /dev/null +++ b/synth.metadata @@ -0,0 +1,818 @@ +{ + "updateTime": "2020-01-16T09:11:16.210833Z", + "sources": [ + { + "template": { + "name": "java_library", + "origin": "synthtool.gcp", + "version": "2019.10.17" + } + } + ], + "newFiles": [ + { + "path": "pom.xml" + }, + { + "path": ".repo-metadata.json" + }, + { + "path": "java.header" + }, + { + "path": "CONTRIBUTING.md" + }, + { + "path": "synth.metadata" + }, + { + "path": "renovate.json" + }, + { + "path": "versions.txt" + }, + { + "path": "synth.py" + }, + { + "path": "license-checks.xml" + }, + { + "path": "CODE_OF_CONDUCT.md" + }, + { + "path": "LICENSE" + }, + { + "path": "codecov.yaml" + }, + { + "path": ".gitignore" + }, + { + "path": "README.md" + }, + { + "path": ".github/release-please.yml" + }, + { + "path": ".github/PULL_REQUEST_TEMPLATE.md" + }, + { + "path": ".github/ISSUE_TEMPLATE/feature_request.md" + }, + { + "path": ".github/ISSUE_TEMPLATE/support_request.md" + }, + { + "path": ".github/ISSUE_TEMPLATE/bug_report.md" + }, + { + "path": ".kokoro/build.sh" + }, + { + "path": ".kokoro/common.cfg" + }, + { + "path": ".kokoro/build.bat" + }, + { + "path": ".kokoro/linkage-monitor.sh" + }, + { + "path": ".kokoro/coerce_logs.sh" + }, + { + "path": ".kokoro/dependencies.sh" + }, + { + "path": ".kokoro/trampoline.sh" + }, + { + "path": ".kokoro/continuous/samples.cfg" + }, + { + "path": ".kokoro/continuous/java8.cfg" + }, + { + "path": ".kokoro/continuous/integration.cfg" + }, + { + "path": ".kokoro/continuous/java11.cfg" + }, + { + "path": ".kokoro/continuous/propose_release.cfg" + }, + { + "path": ".kokoro/continuous/common.cfg" + }, + { + "path": ".kokoro/continuous/propose_release.sh" + }, + { + "path": ".kokoro/continuous/java7.cfg" + }, + { + "path": ".kokoro/continuous/lint.cfg" + }, + { + "path": ".kokoro/continuous/java8-osx.cfg" + }, + { + "path": ".kokoro/continuous/dependencies.cfg" + }, + { + "path": ".kokoro/continuous/java8-win.cfg" + }, + { + "path": ".kokoro/nightly/samples.cfg" + }, + { + "path": ".kokoro/nightly/java8.cfg" + }, + { + "path": ".kokoro/nightly/integration.cfg" + }, + { + "path": ".kokoro/nightly/java11.cfg" + }, + { + "path": ".kokoro/nightly/common.cfg" + }, + { + "path": ".kokoro/nightly/java7.cfg" + }, + { + "path": ".kokoro/nightly/lint.cfg" + }, + { + "path": ".kokoro/nightly/java8-osx.cfg" + }, + { + "path": ".kokoro/nightly/dependencies.cfg" + }, + { + "path": ".kokoro/nightly/java8-win.cfg" + }, + { + "path": ".kokoro/release/publish_javadoc.cfg" + }, + { + "path": ".kokoro/release/common.sh" + }, + { + "path": ".kokoro/release/promote.sh" + }, + { + "path": ".kokoro/release/common.cfg" + }, + { + "path": ".kokoro/release/publish_javadoc.sh" + }, + { + "path": ".kokoro/release/drop.sh" + }, + { + "path": ".kokoro/release/stage.sh" + }, + { + "path": ".kokoro/release/promote.cfg" + }, + { + "path": ".kokoro/release/snapshot.cfg" + }, + { + "path": ".kokoro/release/bump_snapshot.cfg" + }, + { + "path": ".kokoro/release/drop.cfg" + }, + { + "path": ".kokoro/release/bump_snapshot.sh" + }, + { + "path": ".kokoro/release/stage.cfg" + }, + { + "path": ".kokoro/release/snapshot.sh" + }, + { + "path": ".kokoro/presubmit/samples.cfg" + }, + { + "path": ".kokoro/presubmit/java8.cfg" + }, + { + "path": ".kokoro/presubmit/integration.cfg" + }, + { + "path": ".kokoro/presubmit/java11.cfg" + }, + { + "path": ".kokoro/presubmit/linkage-monitor.cfg" + }, + { + "path": ".kokoro/presubmit/common.cfg" + }, + { + "path": ".kokoro/presubmit/java7.cfg" + }, + { + "path": ".kokoro/presubmit/lint.cfg" + }, + { + "path": ".kokoro/presubmit/java8-osx.cfg" + }, + { + "path": ".kokoro/presubmit/dependencies.cfg" + }, + { + "path": ".kokoro/presubmit/clirr.cfg" + }, + { + "path": ".kokoro/presubmit/java8-win.cfg" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeConverterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/StatementResultImplTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionGeneratedSqlScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcDriverTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutorTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatementTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ReplaceableForwardingResultSetTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcParameterStoreTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataWithMockedServerTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcTypeConverterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AbstractSqlScriptVerifier.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcGrpcErrorTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapperTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SqlScriptVerifier.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SetReadOnlyStalenessSqlScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionOptionsTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ITConnectionImpl.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SingleUseTransactionTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ITAbstractJdbcTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcArrayTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SpannerExceptionMatcher.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcBlobTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/DurationConverterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyTransactionTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SqlTestScriptsGenerator.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementWithOneParameterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplAutocommitReadWriteTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/DmlBatchTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTransactionalReadWriteTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcResultSetTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AbortedTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcAbortedTransactionTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SpannerPoolTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/RandomResultSetGenerator.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcExceptionMatcher.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/TransactionModeConverterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/DirectExecuteResultSetTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SpannerJdbcExceptionMatcher.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/DdlBatchTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessUtilTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcClobTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/DdlClientTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AbstractConnectionImplTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplGeneratedSqlScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplTransactionalReadOnlyTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/StatementTimeoutTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionStatementWithNoParametersTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcTimeoutSqlTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcStatementTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/JdbcSqlScriptVerifier.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ClientSideStatementsTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/CredentialsServiceTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/BooleanConverterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ConnectionImplAutocommitReadOnlyTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/StatementParserTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ITAbstractSpannerTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessConverterTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/SetStatementTimeoutSqlScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/AutocommitDmlModeTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/ReadWriteTransactionTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITBulkConnectionTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcConnectTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDdlTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionModeTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcPreparedStatementTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSqlMusicScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITReadOnlySpannerTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcReadWriteAutocommitTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcReadOnlyTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcSimpleStatementsTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITSqlScriptTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITDdlTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITTransactionRetryTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITReadWriteAutocommitSpannerTest.java" + }, + { + "path": "src/test/java/com/google/cloud/spanner/jdbc/it/ITSqlMusicScriptTest.java" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestSetStatements.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestStatementTimeout.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/test-key-cloud-storage.json" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/CommentsTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestAutocommitReadOnly.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/TimeoutSqlScriptTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/test-key-app-default.json" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestInvalidStatements.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestReadOnlyStaleness.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/test-key.json" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_InsertTestData.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestTransactionMode_ReadOnly.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITTransactionModeTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/SetStatementTimeoutTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ClientSideStatementsTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestAutocommitDmlMode.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITReadOnlySpannerTest_CreateTables.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlMusicScriptTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestGetReadTimestamp.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestGetCommitTimestamp.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_CreateTables.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ConnectionImplGeneratedSqlScriptTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITDdlTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestTransactionMode.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/SetReadOnlyStalenessTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITSqlScriptTest_TestTemporaryTransactions.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITReadOnlySpannerTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/ITReadWriteAutocommitSpannerTest.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/it/Songs.txt" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/it/Singers.txt" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/it/Albums.txt" + }, + { + "path": "src/test/resources/com/google/cloud/spanner/jdbc/it/Concerts.txt" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutorImpl.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatement.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcBlob.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/RetriableUpdate.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatements.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcResultSet.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ReadOnlyStalenessUtil.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ConnectionImpl.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcStatement.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcSqlException.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatementSetExecutor.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/StatementExecutionInterceptor.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ConnectionStatementExecutor.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ConnectionPreconditions.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcPreparedStatement.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/TransactionMode.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcStatement.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/DmlBatch.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterMetaData.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/DdlClient.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractMultiUseTransaction.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcConnection.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AnalyzeMode.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatementImpl.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/StatementParser.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaData.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcPreconditions.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatementValueConverter.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcConstants.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcDataSource.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcDriver.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatementNoParamExecutor.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ConnectionOptions.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcClob.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/TransactionRetryListener.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/SingleUseTransaction.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/StatementExecutor.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ChecksumResultSet.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/StatementResultImpl.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AutocommitDmlMode.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/RetriableBatchUpdate.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/Connection.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaData.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcSqlExceptionFactory.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/DdlBatch.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/SpannerPool.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/UnitOfWork.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/FailedBatchUpdate.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/StatementResult.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterStore.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatementExecutor.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/CredentialsService.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ReadOnlyTransaction.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/FailedQuery.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ReadWriteTransaction.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/FailedUpdate.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ReplaceableForwardingResultSet.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/AbstractBaseUnitOfWork.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/ClientSideStatementValueConverters.java" + }, + { + "path": "src/main/java/com/google/cloud/spanner/jdbc/DirectExecuteResultSet.java" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetImportedKeys.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetExportedKeys.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/ClientSideStatements.json" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetPrimaryKeys.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetIndexInfo.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetCrossReferences.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetTables.sql" + }, + { + "path": "src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetSchemas.sql" + }, + { + "path": "src/main/resources/META-INF/services/java.sql.Driver" + } + ] +} \ No newline at end of file diff --git a/synth.py b/synth.py new file mode 100644 index 000000000..259352ead --- /dev/null +++ b/synth.py @@ -0,0 +1,25 @@ +# Copyright 2018 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 +# +# http://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. + +"""This script is used to synthesize generated parts of this library.""" + +import synthtool as s +import synthtool.gcp as gcp + + +common_templates = gcp.CommonTemplates() +templates = common_templates.java_library() +s.copy(templates, excludes=[ + 'README.md' +]) \ No newline at end of file diff --git a/versions.txt b/versions.txt new file mode 100644 index 000000000..72036a35b --- /dev/null +++ b/versions.txt @@ -0,0 +1,4 @@ +# Format: +# module:released-version:current-version + +google-cloud-spanner-jdbc:1.13.0:1.13.0