google-nomulus/db/build.gradle
Michael Muller 06ca9266b4 Upgrade to Gradle 7.0 (#1712)
* Convert to gradle 7.

* More fixes, regenerated lockfiles.

* Update lockfiles for dependency update.

* Fix show_upgrade_diff for new lockfile format

* Add property for allowInsecureProtocol

Allow us to override the restriction against use of plain HTTP for
communication to dependency repositories.  We need this to be able to use a
local proxy for dependency gathering.

* Checking in missing gradle.lockfile
2022-07-26 11:41:27 -04:00

253 lines
7.9 KiB
Groovy

import org.gradle.process.internal.ExecException
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// 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.
plugins {
id "org.flywaydb.flyway" version "6.0.1"
id 'maven-publish'
}
ext {
Set restrictedDbEnv =
[ 'sandbox', 'production' ].asUnmodifiable()
def dbServerProperty = 'dbServer'
def dbNameProperty = 'dbName'
def dbServer = findProperty(dbServerProperty).toString().toLowerCase()
def dbName = findProperty(dbNameProperty)
isRestricted = {
return restrictedDbEnv.contains(dbServer)
}
getAccessInfoByHostPort = { hostAndPort ->
println "Database set to ${hostAndPort}."
return [
url: "jdbc:postgresql://${hostAndPort}/${dbName}",
user: findProperty('dbUser'),
password: findProperty('dbPassword')]
}
getSocketFactoryAccessInfo = { env ->
def cred = getCloudSqlCredential(env).split(' ')
def sqlInstance = cred[0]
println "Database set to Cloud SQL instance ${sqlInstance}."
return [
url: """\
jdbc:postgresql://google/${dbName}?cloudSqlInstance=
${sqlInstance}&socketFactory=
com.google.cloud.sql.postgres.SocketFactory"""
.stripIndent()
.replaceAll(System.lineSeparator(), '') ,
user: cred[1],
password: cred[2]]
}
getJdbcAccessInfo = {
if (rootProject.projects.keySet().contains(dbServer)) {
return getSocketFactoryAccessInfo(dbServer)
} else if (!dbServer.isEmpty()) {
return getAccessInfoByHostPort(dbServer)
} else {
// Not running flyway tasks. Return a dummy object for Flyway config.
return [ url: '', user: '', password: '' ]
}
}
// Retrieves the Cloud SQL credential for the schema deployer. Result is in
// the form of 'instancename username password'.
//
// The env parameter may be one of the following: alpha, crash, sandbox, or
// production.
//
// User must make sure that the nomulus tool can be found on PATH. An alias
// will not work.
getCloudSqlCredential = { env ->
try {
execInBash('which nomulus', '/tmp')
} catch (ExecException e) {
throw new IllegalStateException(
'nomulus not found. Make sure it is on PATH, not just an alias.')
}
def command =
"nomulus -e ${env} get_sql_credential --user schema_deployer"
return execInBash(command, project.rootDir)
}
}
task schemaJar(type: Jar) {
archiveBaseName = 'schema'
from(sourceSets.main.resources) {
include 'sql/flyway/**'
include 'sql/schema/nomulus.golden.sql'
}
}
// Expose NomulusPostgreSql class to ':core' for implementation, without
// leaking unnecessary dependencies to the release artifacts through ':core'.
// Jar is put in the 'implementationApi' configuration.
task implementationApiJar(type: Jar) {
archiveBaseName = 'implementation'
from(sourceSets.main.output) {
include 'google/registry/persistence/NomulusPostgreSql**'
}
}
configurations {
implementationApi
schema
integration
}
artifacts {
implementationApi implementationApiJar
schema schemaJar
}
publishing {
repositories {
maven {
url project.publish_repo
}
}
publications {
sqlSchemaPublication(MavenPublication) {
groupId 'google.registry'
artifactId 'schema'
version project.schema_version
artifact schemaJar
}
}
}
// Adds flyway tasks such as: flywayInfo, flywayValidate, flywayMigrate (
// deploying the schema in local repository), and flywayClean (dropping all data
// in the database). The latter two commands are disallowed in environments
// listed in ext.restrictedDbEnv.
//
// Examples:
// Get info in alpha: nom_build :db:flywayInfo --dbServer=alpha
// Deploy schema to a local test instance and override the database name:
// nom_build :db:flywayMigrate --dbServer=localhost:5432 --dbName=not-default \
// --dbUser=... --dbPassword=...
flyway {
def accessInfo = project.ext.getJdbcAccessInfo()
url = accessInfo.url
user = accessInfo.user
password = accessInfo.password
schemas = [ 'public' ]
locations = [ "classpath:sql/flyway" ]
}
dependencies {
def deps = rootProject.dependencyMap
implementation deps['org.flywaydb:flyway-core']
runtimeOnly deps['com.google.cloud.sql:postgres-socket-factory']
runtimeOnly deps['org.postgresql:postgresql']
testImplementation deps['com.google.flogger:flogger']
testRuntimeOnly deps['com.google.flogger:flogger-system-backend']
testImplementation deps['com.google.guava:guava']
testImplementation deps['com.google.truth:truth']
testRuntimeOnly deps['io.github.java-diff-utils:java-diff-utils']
testImplementation deps['org.junit.jupiter:junit-jupiter-api']
testImplementation deps['org.junit.jupiter:junit-jupiter-engine']
testImplementation deps['org.testcontainers:postgresql']
testImplementation deps['org.testcontainers:testcontainers']
testImplementation deps['org.testcontainers:junit-jupiter']
testImplementation deps['org.testcontainers:postgresql']
testImplementation project(path: ':common', configuration: 'testing')
}
task generateFlywayIndex {
def flywayBase = "$projectDir/src/main/resources/sql/flyway"
def filenamePattern = /V(\d+)__.*\.sql/
def getSeqNum = { file ->
def match = file.getName() =~ filenamePattern
if (match.size() != 1) {
throw new IllegalArgumentException("Bad Flyway filename: $file")
}
return match[0][1] as int
}
doLast {
def files = new File(flywayBase).listFiles()
def indexFile = new File("${flywayBase}.txt")
indexFile.write ''
for (def file : files.sort{a, b -> getSeqNum(a) <=> getSeqNum(b)}) {
indexFile << "${file.name}\n"
}
}
}
flywayInfo.dependsOn('buildNeeded')
flywayValidate.dependsOn('buildNeeded')
if (ext.isRestricted()) {
// Disable dangerous Flyway tasks in sandbox and production. Only allow info and validate.
tasks.findAll { task -> task.group.equals('Flyway')}.each {
if (it.name == 'flywayMigrate') {
it.doFirst {
throw new UnsupportedOperationException(
""" \
FlywayMigrate is disabled. See README.md for schema deployment
instructions.""".stripIndent())
}
} else if (it.name != 'flywayInfo' && it.name != 'flywayValidate') {
it.doFirst {
throw new UnsupportedOperationException(
"${it.name} from commandline is not allowed.")
}
}
}
}
if (project.baseSchemaTag != '') {
repositories {
maven {
url project.publish_repo
}
}
dependencies {
integration "google.registry:schema:${project.baseSchemaTag}"
}
// Checks if Flyway scripts can be deployed to an existing database with
// an older release. Please refer to SchemaTest.java for more information.
task schemaIncrementalDeployTest(dependsOn: processResources, type: Test) {
useJUnitPlatform()
include 'google/registry/sql/flyway/SchemaTest.*'
classpath = configurations.testRuntimeClasspath
.plus(configurations.integration)
.plus(files(sourceSets.test.output.classesDirs))
.plus(files(sourceSets.test.output.resourcesDir))
.plus(files(sourceSets.main.output.classesDirs))
// Declare test-runtime dependency on Flyway scripts in the resources dir.
// They are not on classpath since they conflict with the base schema.
inputs.dir sourceSets.main.output.resourcesDir
// Specifies which test to run using the following property
systemProperty 'deploy_to_existing_db', 'true'
}
}