Skip to content

Commit

Permalink
feat(sql): Support multiple root liquibase changesets (spinnaker#2421)
Browse files Browse the repository at this point in the history
  • Loading branch information
robzienert authored Sep 20, 2018
1 parent 377e26a commit de29fcc
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.orca.sql.JooqSqlCommentAppender
import com.netflix.spinnaker.orca.sql.JooqToSpringExceptionTransformer
import com.netflix.spinnaker.orca.sql.SpringLiquibaseProxy
import com.netflix.spinnaker.orca.sql.SqlHealthIndicator
import com.netflix.spinnaker.orca.sql.SqlHealthcheckActivator
import com.netflix.spinnaker.orca.sql.config.DataSourceConfiguration
Expand All @@ -39,7 +40,6 @@ import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.jdbc.datasource.SingleConnectionDataSource
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
import sun.net.InetAddressCachePolicy
import java.lang.reflect.Field
Expand All @@ -63,20 +63,7 @@ class SqlConfiguration {
}

@Bean fun liquibase(properties: SqlProperties): SpringLiquibase =
properties.migration
.run {
val ds = SingleConnectionDataSource(jdbcUrl, user, password, false)
if (driver != null) {
ds.setDriverClassName(driver)
}
ds
}
.let { ds ->
SpringLiquibase().apply {
changeLog = "classpath:db/changelog-master.yml"
dataSource = ds
}
}
SpringLiquibaseProxy(properties)

@Bean fun transactionManager(dataSource: DataSource): DataSourceTransactionManager =
DataSourceTransactionManager(dataSource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ data class MigrationProperties(
var jdbcUrl: String = "jdbc:mysql://localhost/orca",
var user: String? = null,
var password: String? = null,
var driver: String? = null
var driver: String? = null,
var additionalChangeLogs: List<String> = listOf()
)

data class ConnectionPoolProperties(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2018 Netflix, 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.
*/
package com.netflix.spinnaker.orca.sql

import com.netflix.spinnaker.config.SqlProperties
import liquibase.integration.spring.SpringLiquibase
import org.springframework.jdbc.datasource.SingleConnectionDataSource
import javax.sql.DataSource

/**
* Proxies Spring's Liquibase bean to allow multiple, independent Liquibase
* changesets to be used within a single Orca application.
*
* The use case behind this is to allow private extensions to make additional
* database schema changes atop OSS.
*
* IMPORTANT: While using this, ensure that you do not make any changes to any
* OSS schemas, and namespace tables that you've created so not to collide with
* potential future Orca changes. Spinnaker's OSS schema cannot and will not
* make considerations for custom integrations layered atop its schema.
*/
class SpringLiquibaseProxy(
private val sqlProperties: SqlProperties
) : SpringLiquibase() {

init {
changeLog = "classpath:db/changelog-master.yml"
dataSource = createDataSource()
}

/**
* Everything has to be done in afterPropertiesSet, because that's how Spring
* expects things to be done for cleanup purposes, etc.
*/
override fun afterPropertiesSet() {
// First do the OSS migrations
super.afterPropertiesSet()

// Then if anything else has been defined, do that afterwards
sqlProperties.migration.additionalChangeLogs
.map {
SpringLiquibase().apply {
changeLog = "classpath:$it"
dataSource = createDataSource()
resourceLoader = this@SpringLiquibaseProxy.resourceLoader
}
}
.forEach {
it.afterPropertiesSet()
}
}

private fun createDataSource(): DataSource =
sqlProperties.migration.run {
val ds = SingleConnectionDataSource(jdbcUrl, user, password, true)
if (driver != null) {
ds.setDriverClassName(driver)
}
ds
}
}

0 comments on commit de29fcc

Please sign in to comment.