Skip to content

Commit

Permalink
sandbox: Upgrade Flyway from v5 to v6. (digital-asset#4207)
Browse files Browse the repository at this point in the history
* sandbox: Ensure that the Flyway tests actually pick up the SQL files.

* sandbox: Upgrade Flyway from v5 to v6.

CHANGELOG_BEGIN
- [Sandbox] Upgrade the Flyway database migrations library from v5 to v6.
CHANGELOG_END
  • Loading branch information
SamirTalwar authored Jan 24, 2020
1 parent 243746d commit 2737303
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 50 deletions.
2 changes: 1 addition & 1 deletion bazel-java-deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def install_java_deps():
"org.apache.commons:commons-text:1.4",
"org.awaitility:awaitility:3.1.6",
"org.checkerframework:checker:2.5.4",
"org.flywaydb:flyway-core:5.2.4",
"org.flywaydb:flyway-core:6.2.0",
"org.freemarker:freemarker-gae:2.3.28",
"org.gnieh:diffson-spray-json_2.12:3.1.0",
"org.hamcrest:hamcrest-all:1.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,84 @@
package com.digitalasset.platform.sandbox.stores.ledger.sql.migration

import java.math.BigInteger
import java.nio.charset.Charset
import java.security.MessageDigest

import com.digitalasset.platform.sandbox.stores.ledger.sql.dao.DbType
import com.digitalasset.platform.sandbox.stores.ledger.sql.migration.FlywayMigrations.configurationBase
import com.digitalasset.platform.sandbox.stores.ledger.sql.migration.FlywayMigrationsSpec._
import org.apache.commons.io.IOUtils
import org.flywaydb.core.api.configuration.FluentConfiguration
import org.flywaydb.core.api.migration.JavaMigration
import org.flywaydb.core.internal.resource.LoadableResource
import org.flywaydb.core.internal.scanner.Scanner
import org.scalatest.{Matchers, WordSpec}
import org.flywaydb.core.internal.scanner.{ResourceNameCache, Scanner}
import org.scalatest.Matchers._
import org.scalatest.WordSpec

import scala.collection.JavaConverters._

// SQL MIGRATION AND THEIR DIGEST FILES SHOULD BE CREATED ONLY ONCE AND NEVER CHANGED AGAIN,
// OTHERWISE MIGRATIONS BREAK ON EXISTING DEPLOYMENTS!
@SuppressWarnings(Array("org.wartremover.warts.Any", "org.wartremover.warts.StringPlusAny"))
class FlywayMigrationsSpec extends WordSpec with Matchers {

private val digester = MessageDigest.getInstance("SHA-256")
private def scannerOfDbType(dbType: DbType) = {
val config = configurationBase(dbType)
new Scanner(config.getLocations.toList.asJava, getClass.getClassLoader, config.getEncoding)
}
class FlywayMigrationsSpec extends WordSpec {

"Postgres flyway migration files" should {
"always have a valid SHA-256 digest file accompanied" in assertFlywayMigrationFileHashes(
DbType.Postgres)
"always have a valid SHA-256 digest file accompanied" in {
assertFlywayMigrationFileHashes(DbType.Postgres)
}
}

"H2 database flyway migration files" should {
"always have a valid SHA-256 digest file accompanied" in assertFlywayMigrationFileHashes(
DbType.H2Database)
"always have a valid SHA-256 digest file accompanied" in {
assertFlywayMigrationFileHashes(DbType.H2Database)
}
}

private def assertFlywayMigrationFileHashes(dbType: DbType) = {
val resourceScanner = scannerOfDbType(dbType)

resourceScanner
.getResources("", ".sql")
.asScala
.map { res =>
val fileName = res.getFilename
val expectedDigest =
getExpectedDigest(fileName, fileName.dropRight(4) + ".sha256", resourceScanner)
val currentDigest = getCurrentDigest(res)

assert(
currentDigest == expectedDigest,
s"Digest of migration file $fileName has changed! It is NOT allowed to change neither existing sql migrations files nor their digests!"
)
}
}

object FlywayMigrationsSpec {

private val digester = MessageDigest.getInstance("SHA-256")

private def assertFlywayMigrationFileHashes(dbType: DbType): Unit = {
val config = configurationBase(dbType)
val resourceScanner = scanner(config)
val resources = resourceScanner.getResources("", ".sql").asScala.toSeq
resources.size should be > 10

resources.foreach { res =>
val fileName = res.getFilename
val expectedDigest =
getExpectedDigest(fileName, fileName.dropRight(4) + ".sha256", resourceScanner)
val currentDigest = getCurrentDigest(res, config.getEncoding)

assert(
currentDigest == expectedDigest,
s"Digest of migration file $fileName has changed! It is NOT allowed to change neither existing sql migrations files nor their digests!"
)
}
}

private def getExpectedDigest(sourceFile: String, digestFile: String, resourceScanner: Scanner) =
new String(Option(resourceScanner.getResource(digestFile))
private def scanner(config: FluentConfiguration) =
new Scanner(
classOf[JavaMigration],
config.getLocations.toList.asJava,
getClass.getClassLoader,
config.getEncoding,
new ResourceNameCache,
)

private def getExpectedDigest(
sourceFile: String,
digestFile: String,
resourceScanner: Scanner[_],
) =
IOUtils.toString(Option(resourceScanner.getResource(digestFile))
.getOrElse(sys.error(
s"Missing sha-256 file $digestFile! Are you introducing a new Flyway migration step? You need to create a sha-256 digest file by running this under the db/migration folder: shasum -a 256 $sourceFile | awk '{print $$1}' > $digestFile"))
.loadAsBytes())
.read())

private def getCurrentDigest(res: LoadableResource) = {
val digest = digester.digest(res.loadAsBytes())
val bi = new BigInteger(1, digest)
(String.format("%0" + (digest.length << 1) + "X", bi) + "\n").toLowerCase
private def getCurrentDigest(res: LoadableResource, encoding: Charset) = {
val digest = digester.digest(IOUtils.toByteArray(res.read(), encoding))
String.format(s"%0${digest.length * 2}x\n", new BigInteger(1, digest))
}
}
22 changes: 11 additions & 11 deletions maven_install.json
Original file line number Diff line number Diff line change
Expand Up @@ -6520,26 +6520,26 @@
"sha256": "d5c170159010067f13053bf619a8f90ba18a6377020ea69f05bb521644ba817e"
},
{
"coord": "org.flywaydb:flyway-core:5.2.4",
"file": "v1/https/repo1.maven.org/maven2/org/flywaydb/flyway-core/5.2.4/flyway-core-5.2.4.jar",
"coord": "org.flywaydb:flyway-core:6.2.0",
"file": "v1/https/repo1.maven.org/maven2/org/flywaydb/flyway-core/6.2.0/flyway-core-6.2.0.jar",
"directDependencies": [],
"dependencies": [],
"url": "https://repo1.maven.org/maven2/org/flywaydb/flyway-core/5.2.4/flyway-core-5.2.4.jar",
"url": "https://repo1.maven.org/maven2/org/flywaydb/flyway-core/6.2.0/flyway-core-6.2.0.jar",
"mirror_urls": [
"https://repo1.maven.org/maven2/org/flywaydb/flyway-core/5.2.4/flyway-core-5.2.4.jar"
"https://repo1.maven.org/maven2/org/flywaydb/flyway-core/6.2.0/flyway-core-6.2.0.jar"
],
"sha256": "acfb5d8df20f85f11d215d625841fadc8b0b7fdb7729c3c5e5f4db4d5621a82e"
"sha256": "548390b6627c206e5a8a60475beeb75a5e957e075514ae1a29cf58f7510c2013"
},
{
"coord": "org.flywaydb:flyway-core:jar:sources:5.2.4",
"file": "v1/https/repo1.maven.org/maven2/org/flywaydb/flyway-core/5.2.4/flyway-core-5.2.4-sources.jar",
"coord": "org.flywaydb:flyway-core:jar:sources:6.2.0",
"file": "v1/https/repo1.maven.org/maven2/org/flywaydb/flyway-core/6.2.0/flyway-core-6.2.0-sources.jar",
"directDependencies": [],
"dependencies": [],
"url": "https://repo1.maven.org/maven2/org/flywaydb/flyway-core/5.2.4/flyway-core-5.2.4-sources.jar",
"url": "https://repo1.maven.org/maven2/org/flywaydb/flyway-core/6.2.0/flyway-core-6.2.0-sources.jar",
"mirror_urls": [
"https://repo1.maven.org/maven2/org/flywaydb/flyway-core/5.2.4/flyway-core-5.2.4-sources.jar"
"https://repo1.maven.org/maven2/org/flywaydb/flyway-core/6.2.0/flyway-core-6.2.0-sources.jar"
],
"sha256": "38ce692e4d6e180a530182fa28edd57291c6bb0587c72765b2c39798daa5161c"
"sha256": "5190889c0a06fe978e2c2fe10960ec6518d575bdc5159878939b9dc593a02c2e"
},
{
"coord": "org.freemarker:freemarker-gae:2.3.28",
Expand Down Expand Up @@ -14688,6 +14688,6 @@
}
],
"version": "0.1.0",
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": 1501980171
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": 112364939
}
}

0 comments on commit 2737303

Please sign in to comment.