Skip to content

Commit

Permalink
Add tool library for updating Spanner schema using Liquibase.
Browse files Browse the repository at this point in the history
  • Loading branch information
SanjayVas committed May 6, 2022
1 parent c814c4f commit 90afdf5
Show file tree
Hide file tree
Showing 20 changed files with 167 additions and 116 deletions.
4 changes: 2 additions & 2 deletions build/cloud_spanner_emulator/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ _cloud_spanner_emulator_binaries = repository_rule(
def cloud_spanner_emulator_binaries():
_cloud_spanner_emulator_binaries(
name = "cloud_spanner_emulator",
sha256 = "7a3cdd5db7f5a427230ab67a8dc09cfcb6752dd7f0b28d51e8d08150b2641506",
version = "1.1.1",
sha256 = "7048efb8708e0b2af98d84c9bd86ecb158b5663116c5dea789974d6a616f0e12",
version = "1.4.2",
)
13 changes: 10 additions & 3 deletions build/com_github_grpc_grpc/repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ def com_github_grpc_grpc_repo():
if "com_github_grpc_grpc" not in native.existing_rules():
http_archive(
name = "com_github_grpc_grpc",
sha256 = "8eb9d86649c4d4a7df790226df28f081b97a62bf12c5c5fe9b5d31a29cd6541a",
strip_prefix = "grpc-1.36.4",
urls = ["https://github.com/grpc/grpc/archive/v1.36.4.tar.gz"],
sha256 = "67423a4cd706ce16a88d1549297023f0f9f0d695a96dd684adc21e67b021f9bc",
strip_prefix = "grpc-1.46.0",
urls = ["https://github.com/grpc/grpc/archive/v1.46.0.tar.gz"],
)

# http_archive(
# name = "com_github_grpc_grpc",
# sha256 = "46ee3d12c6d42a4ded46ba025c8ba09850425312c710c6ee6e084bd808ebc1e8",
# strip_prefix = "grpc-1.45.1",
# urls = ["https://github.com/grpc/grpc/archive/v1.45.1.tar.gz"],
# )
14 changes: 10 additions & 4 deletions build/com_github_grpc_grpc_kotlin/repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ def com_github_grpc_grpc_kotlin_repo():
if "io_grpc_grpc_java" not in native.existing_rules():
http_archive(
name = "io_grpc_grpc_java",
sha256 = "85927f857e0b3ad5c4e51c2e6d29213d3e0319f20784aa2113552f71311ba74c",
# Latest compatible version per https://github.com/grpc/grpc-kotlin/blob/v1.2.1/compiler/README.md
strip_prefix = "grpc-java-1.39.0",
url = "https://github.com/grpc/grpc-java/archive/refs/tags/v1.39.0.tar.gz",
sha256 = "c1b80883511ceb1e433fb2d4b2f6d85dca0c62a265a6a3e6695144610d6f65b8",
strip_prefix = "grpc-java-1.46.0",
url = "https://github.com/grpc/grpc-java/archive/refs/tags/v1.46.0.tar.gz",
)

# http_archive(
# name = "io_grpc_grpc_java",
# sha256 = "51bac553d269b97214dbd6aee4e65fc616d8ccd414fc12d708e85979ed4c19b4",
# strip_prefix = "grpc-java-1.45.1",
# url = "https://github.com/grpc/grpc-java/archive/refs/tags/v1.45.1.tar.gz",
# )
4 changes: 1 addition & 3 deletions build/common_jvm_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,18 @@ load("//build/io_bazel_rules_kotlin:deps.bzl", "rules_kotlin_deps")
load("//build/io_bazel_rules_docker:base_images.bzl", "base_java_images")
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
load("//build/io_bazel_rules_go:deps.bzl", "rules_go_deps")
load("@tink_java//:tink_java_deps.bzl", "tink_java_deps")

def common_jvm_deps():
"""
Adds all external repos necessary for common-jvm.
"""
grpc_deps()
container_repositories()
rules_kotlin_deps()
base_java_images()
grpc_deps()
switched_rules_by_language(
name = "com_google_googleapis_imports",
java = True,
)
rules_go_deps()
tink_java_deps()
2 changes: 1 addition & 1 deletion build/common_jvm_extra_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def common_jvm_extra_deps():
Adds all external repos necessary for common-jvm.
"""
compat_repositories()
grpc_extra_deps()
container_deps()
java_image_repositories()
grpc_extra_deps()
grpc_kt_repositories()
grpc_java_repositories()
9 changes: 4 additions & 5 deletions build/common_jvm_maven.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ def common_jvm_maven_artifacts():
# or default dependency versions).
maven_artifacts.update({
"com.adobe.testing:s3mock-junit4": "2.2.3",
"com.google.api:gax-grpc": "2.12.2",
"com.google.api.grpc:grpc-core-proto": "0.0.6",
"com.google.cloud:google-cloud-bigquery": "2.4.1",
"com.google.cloud:google-cloud-nio": "0.123.10",
"com.google.cloud:google-cloud-spanner": "3.0.3",
"com.google.cloud:google-cloud-bigquery": "2.10.10",
"com.google.cloud:google-cloud-nio": "0.123.28",
"com.google.cloud:google-cloud-spanner": "6.23.3",
"com.google.guava:guava": "31.0.1-jre",
"info.picocli:picocli": "4.4.0",
"junit:junit": "4.13",
Expand All @@ -75,6 +73,7 @@ def common_jvm_maven_artifacts():
# Liquibase.
"org.liquibase:liquibase-core": "4.9.1",
"com.google.cloudspannerecosystem:liquibase-spanner": "4.6.1",
"com.google.cloud:google-cloud-spanner-jdbc": "2.6.4",

# For grpc-kotlin. This should be a version that is compatible with the
# Kotlin release used by rules_kotlin.
Expand Down
2 changes: 0 additions & 2 deletions build/common_jvm_repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ load(
"//build/io_bazel_rules_kotlin:repo.bzl",
"rules_kotlin_repo",
)
load("//build/io_bazel_rules_go:repo.bzl", "rules_go_repo")
load("//build/tink:repo.bzl", "tink_java")

def common_jvm_repositories():
Expand All @@ -48,5 +47,4 @@ def common_jvm_repositories():
grpc_health_probe_repo()
rules_docker_repo()
com_google_googleapis_repo()
rules_go_repo()
tink_java()
Empty file.
26 changes: 0 additions & 26 deletions build/io_bazel_rules_go/deps.bzl

This file was deleted.

41 changes: 0 additions & 41 deletions build/io_bazel_rules_go/repo.bzl

This file was deleted.

6 changes: 0 additions & 6 deletions imports/java/com/google/api/grpc/BUILD.bazel

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ kt_jvm_library(
srcs = glob(["*.kt"]),
deps = [
"//imports/java/com/google/api/core",
"//imports/java/com/google/api/grpc",
"//imports/java/com/google/cloud:core",
"//imports/java/com/google/protobuf",
"//imports/kotlin/kotlinx/coroutines:core",
"@com_google_googleapis//google/type:type_java_proto",
],
)
15 changes: 13 additions & 2 deletions src/main/kotlin/org/wfanet/measurement/gcloud/spanner/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@ load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")

package(default_visibility = ["//visibility:public"])

kt_jvm_library(
name = "flags",
srcs = ["SpannerFlags.kt"],
deps = ["//imports/java/picocli"],
)

kt_jvm_library(
name = "spanner",
srcs = glob(["*.kt"]),
srcs = glob(
["*.kt"],
exclude = ["SpannerFlags.kt"],
),
resources = ["//src/main/resources/META-INF/services:grpclb"],
exports = [":flags"],
deps = [
":flags",
"//imports/java/com/google/cloud/spanner",
"//imports/java/picocli",
"//imports/kotlin/kotlinx/coroutines:core",
"//src/main/kotlin/org/wfanet/measurement/common",
"//src/main/kotlin/org/wfanet/measurement/common/identity",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package org.wfanet.measurement.gcloud.spanner
import com.google.cloud.spanner.DatabaseClient
import com.google.cloud.spanner.DatabaseId
import com.google.cloud.spanner.Spanner
import io.grpc.LoadBalancerRegistry
import io.grpc.grpclb.GrpclbLoadBalancerProvider
import java.time.Duration
import java.util.logging.Logger
import kotlinx.coroutines.TimeoutCancellationException
Expand Down Expand Up @@ -78,3 +80,24 @@ class SpannerDatabaseConnector(
private val logger = Logger.getLogger(this::class.java.name)
}
}

/** Builds a [SpannerDatabaseConnector] from these flags. */
private fun SpannerFlags.toSpannerDatabaseConnector(): SpannerDatabaseConnector {
return SpannerDatabaseConnector(
projectName = projectName,
instanceName = instanceName,
databaseName = databaseName,
readyTimeout = readyTimeout,
emulatorHost = emulatorHost
)
}

/**
* Executes [block] with a [SpannerDatabaseConnector] resource once it's ready, ensuring that the
* resource is closed.
*/
suspend fun <R> SpannerFlags.usingSpanner(
block: suspend (spanner: SpannerDatabaseConnector) -> R
): R {
return toSpannerDatabaseConnector().usingSpanner(block)
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,6 @@ class SpannerFlags {
description = ["Host name and port of the spanner emulator."],
required = false
)
var spannerEmulatorHost: String? = null
var emulatorHost: String? = null
private set

/** Builds a [SpannerDatabaseConnector] from these flags. */
private fun toSpannerDatabaseConnector(): SpannerDatabaseConnector {
return SpannerDatabaseConnector(
projectName = projectName,
instanceName = instanceName,
databaseName = databaseName,
readyTimeout = readyTimeout,
emulatorHost = spannerEmulatorHost
)
}

/**
* Executes [block] with a [SpannerDatabaseConnector] resource once it's ready, ensuring that the
* resource is closed.
*/
suspend fun <R> usingSpanner(block: suspend (spanner: SpannerDatabaseConnector) -> R): R {
return toSpannerDatabaseConnector().usingSpanner(block)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")

package(default_visibility = ["//visibility:public"])

kt_jvm_library(
name = "update_schema",
srcs = ["UpdateSchema.kt"],
resources = ["//src/main/resources/META-INF/services:grpclb"],
runtime_deps = ["//imports/java/liquibase/ext/spanner"],
deps = [
"//src/main/kotlin/org/wfanet/measurement/common",
"//src/main/kotlin/org/wfanet/measurement/common/db/liquibase",
"//src/main/kotlin/org/wfanet/measurement/gcloud/spanner:flags",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2022 The Cross-Media Measurement Authors
*
* 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.
*/

package org.wfanet.measurement.gcloud.spanner.tools

import java.sql.DriverManager
import java.util.logging.Level
import java.util.logging.Logger
import liquibase.Contexts
import liquibase.Scope
import org.wfanet.measurement.common.commandLineMain
import org.wfanet.measurement.common.db.liquibase.Liquibase
import org.wfanet.measurement.common.db.liquibase.setLogLevel
import org.wfanet.measurement.common.getJarResourcePath
import org.wfanet.measurement.gcloud.spanner.SpannerFlags
import picocli.CommandLine.Command
import picocli.CommandLine.Mixin
import picocli.CommandLine.Option

@Command
class UpdateSchema : Runnable {
@Mixin private lateinit var flags: SpannerFlags

@Option(
names = ["--changelog"],
description = ["Liquibase changelog resource name"],
required = true,
)
private lateinit var changelog: String

override fun run() {
val connectionString =
if (flags.emulatorHost == null) {
"jdbc:cloudspanner:/projects/${flags.projectName}/instances/${flags.instanceName}/" +
"databases/${flags.databaseName}"
} else {
"jdbc:cloudspanner://${flags.emulatorHost}/projects/${flags.projectName}/instances/" +
"${flags.instanceName}/databases/${flags.databaseName}" +
";usePlainText=true;autoConfigEmulator=true"
}

val changelogPath =
checkNotNull(Thread.currentThread().contextClassLoader.getJarResourcePath(changelog)) {
"JAR resource $changelog not found"
}

logger.info("Connecting to $connectionString")
DriverManager.getConnection(connectionString).use { connection ->
logger.info("Loading changelog from $changelogPath")
Liquibase.fromPath(connection, changelogPath).use { liquibase ->
logger.info("Updating...")
Scope.getCurrentScope().setLogLevel(Level.FINE)
liquibase.update(Contexts())
}
}
}

companion object {
private val logger = Logger.getLogger(this::class.java.name)

@JvmStatic fun main(args: Array<String>) = commandLineMain(UpdateSchema(), args)
}
}
8 changes: 8 additions & 0 deletions src/main/resources/META-INF/services/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package(default_visibility = ["//visibility:public"])

# TODO(grpc/grpc-java#9149): Remove once @io_grpc_grpc_java//grpclb contains
# these resources.
filegroup(
name = "grpclb",
srcs = glob(["io.grpc.*"]),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.grpc.grpclb.GrpclbLoadBalancerProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.grpc.grpclb.SecretGrpclbNameResolverProvider$Provider

0 comments on commit 90afdf5

Please sign in to comment.