diff --git a/docs/source/testing.rst b/docs/source/testing.rst index d7ed01709d..039c3af029 100644 --- a/docs/source/testing.rst +++ b/docs/source/testing.rst @@ -59,7 +59,7 @@ SQL templates files are executed at different stage of an integration test: Depends on the database providers not each SQL file is present (e.g. db-setp always deletes tabels so db-cleanp is not needed). The setup ensures that all nodes involved in a single integration test use different database users to achieve database separation. -The data source configuration files (denote by ``databaseProvider``) define user and schema by ${nodeOrganizationName} placeholder. +The data source configuration files (denote by ``databaseProvider``) define user and schema by ${custom.nodeOrganizationName} placeholder. At a runtime the node resolves the placeholder to its organization name. diff --git a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt index b1d1e0e0ff..ffb1c2257f 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt @@ -2,6 +2,8 @@ package net.corda.node.services.config import com.typesafe.config.Config import com.typesafe.config.ConfigFactory +import com.typesafe.config.ConfigFactory.systemEnvironment +import com.typesafe.config.ConfigFactory.systemProperties import com.typesafe.config.ConfigParseOptions import com.typesafe.config.ConfigRenderOptions import net.corda.core.identity.CordaX500Name @@ -10,6 +12,7 @@ import net.corda.core.internal.div import net.corda.core.internal.exists import net.corda.nodeapi.internal.* import net.corda.nodeapi.internal.config.SSLConfiguration +import net.corda.nodeapi.internal.config.toProperties import net.corda.nodeapi.internal.crypto.X509KeyStore import net.corda.nodeapi.internal.crypto.loadKeyStore import net.corda.nodeapi.internal.crypto.save @@ -20,6 +23,9 @@ fun configOf(vararg pairs: Pair): Config = ConfigFactory.parseMap( operator fun Config.plus(overrides: Map): Config = ConfigFactory.parseMap(overrides).withFallback(this) object ConfigHelper { + + const val CORDA_PROPERTY_PREFIX = "corda." + private val log = LoggerFactory.getLogger(javaClass) fun loadConfig(baseDirectory: Path, configFile: Path = baseDirectory / "node.conf", @@ -30,10 +36,13 @@ object ConfigHelper { val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig)) val databaseConfig = ConfigFactory.parseResources(System.getProperty("databaseProvider")+".conf", parseOptions.setAllowMissing(true)) + val systemOverrides = systemProperties().cordaEntriesOnly() + val environmentOverrides = systemEnvironment().cordaEntriesOnly() val finalConfig = configOverrides // Add substitution values here - .withFallback(configOf("nodeOrganizationName" to parseToDbSchemaFriendlyName(baseDirectory.fileName.toString()))) //for database integration tests - .withFallback(ConfigFactory.systemProperties()) //for database integration tests + .withFallback(configOf("custom.nodeOrganizationName" to parseToDbSchemaFriendlyName(baseDirectory.fileName.toString()))) //for database integration tests + .withFallback(systemOverrides) //for database integration tests + .withFallback(environmentOverrides) //for database integration tests .withFallback(configOf("baseDirectory" to baseDirectory.toString())) .withFallback(databaseConfig) //for database integration tests .withFallback(appConfig) @@ -42,6 +51,11 @@ object ConfigHelper { log.info("Config:\n${finalConfig.root().render(ConfigRenderOptions.defaults())}") return finalConfig } + + private fun Config.cordaEntriesOnly(): Config { + + return ConfigFactory.parseMap(toProperties().filterKeys { (it as String).startsWith(CORDA_PROPERTY_PREFIX) }.mapKeys { (it.key as String).removePrefix(CORDA_PROPERTY_PREFIX) }) + } } /** diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt index 69958cf7cf..3a3a59881c 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt @@ -311,7 +311,7 @@ fun createMockCordaService(serviceHub: MockServices, serv /** * Reads database and dataSource configuration from a file denoted by 'databaseProvider' system property, * overwitten by system properties and defaults to H2 in memory db. - * @param nodeName Reflects the "instance" of the database username/schema, the value will be used to replace ${nodeOrganizationName} placeholder + * @param nodeName Reflects the "instance" of the database username/schema, the value will be used to replace ${custom.nodeOrganizationName} placeholder * if the placeholder is present in config. * @param postfix Additional postix added to database "instance" name in case config defaults to H2 in memory database. */ @@ -330,8 +330,8 @@ fun databaseProviderDataSourceConfig(nodeName: String? = null, postfix: String? val databaseConfig = ConfigFactory.parseResources(System.getProperty("databaseProvider") + ".conf", parseOptions.setAllowMissing(true)) val fixedOverride = ConfigFactory.parseString("baseDirectory = \"\"") - //implied property nodeOrganizationName to fill the potential placeholders in db schema/ db user properties - val nodeOrganizationNameConfig = if (nodeName != null) configOf("nodeOrganizationName" to parseToDbSchemaFriendlyName(nodeName)) else ConfigFactory.empty() + //implied property custom.nodeOrganizationName to fill the potential placeholders in db schema/ db user properties + val nodeOrganizationNameConfig = if (nodeName != null) configOf("custom.nodeOrganizationName" to parseToDbSchemaFriendlyName(nodeName)) else ConfigFactory.empty() //defaults to H2 //for H2 the same db instance runs for all integration tests, so adding additional variable postfix create a unique database each time diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/internal/IntegrationTest.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/internal/IntegrationTest.kt index 66a0e691a5..4f2360c1bc 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/internal/IntegrationTest.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/internal/IntegrationTest.kt @@ -15,9 +15,9 @@ import org.junit.rules.ExternalResource abstract class IntegrationTest { // System properties set in main 'corda-project' build.gradle // Note: the database provider configuration file for integration tests should specify: - // dataSource.user = ${nodeOrganizationName} + // dataSource.user = ${custom.nodeOrganizationName} // dataSource.password = [PASSWORD] - // where [PASSWORD] must be the same for all ${nodeOrganizationName} + // where [PASSWORD] must be the same for all ${custom.nodeOrganizationName} companion object { private val DATABASE_PROVIDER = "databaseProvider" private val dbProvider = System.getProperty(DATABASE_PROVIDER, "") diff --git a/testing/test-utils/src/main/resources/integration-azure-sql.conf b/testing/test-utils/src/main/resources/integration-azure-sql.conf index 8c769a303c..aad07c97d0 100644 --- a/testing/test-utils/src/main/resources/integration-azure-sql.conf +++ b/testing/test-utils/src/main/resources/integration-azure-sql.conf @@ -1,11 +1,11 @@ dataSourceProperties = { dataSourceClassName = "com.microsoft.sqlserver.jdbc.SQLServerDataSource" dataSource.url = "jdbc:sqlserver://[HOST]:1433;databaseName=[DATABASE];encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30" - dataSource.user = ${nodeOrganizationName} + dataSource.user = ${custom.nodeOrganizationName} dataSource.password = "yourStrong(!)Password" } database = { transactionIsolationLevel = READ_COMMITTED initDatabase = true - schema = ${nodeOrganizationName} + schema = ${custom.nodeOrganizationName} } \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/integration-oracle-11.conf b/testing/test-utils/src/main/resources/integration-oracle-11.conf index a0d54dbbb3..95ab972a53 100644 --- a/testing/test-utils/src/main/resources/integration-oracle-11.conf +++ b/testing/test-utils/src/main/resources/integration-oracle-11.conf @@ -1,10 +1,10 @@ dataSourceProperties = { dataSourceClassName = "oracle.jdbc.pool.OracleDataSource" dataSource.url = "jdbc:oracle:thin:@[IP]:[PORT]:xe" - dataSource.user = ${nodeOrganizationName} + dataSource.user = ${custom.nodeOrganizationName} dataSource.password = 1234 } database = { transactionIsolationLevel = READ_COMMITTED - schema = ${nodeOrganizationName} + schema = ${custom.nodeOrganizationName} } \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/integration-oracle.conf b/testing/test-utils/src/main/resources/integration-oracle.conf index a0d54dbbb3..95ab972a53 100644 --- a/testing/test-utils/src/main/resources/integration-oracle.conf +++ b/testing/test-utils/src/main/resources/integration-oracle.conf @@ -1,10 +1,10 @@ dataSourceProperties = { dataSourceClassName = "oracle.jdbc.pool.OracleDataSource" dataSource.url = "jdbc:oracle:thin:@[IP]:[PORT]:xe" - dataSource.user = ${nodeOrganizationName} + dataSource.user = ${custom.nodeOrganizationName} dataSource.password = 1234 } database = { transactionIsolationLevel = READ_COMMITTED - schema = ${nodeOrganizationName} + schema = ${custom.nodeOrganizationName} } \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/integration-postgres.conf b/testing/test-utils/src/main/resources/integration-postgres.conf index 447fcf52fa..a17b36dcc4 100644 --- a/testing/test-utils/src/main/resources/integration-postgres.conf +++ b/testing/test-utils/src/main/resources/integration-postgres.conf @@ -1,10 +1,10 @@ dataSourceProperties = { dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource" dataSource.url = "jdbc:postgresql://[HOST]:[PORT]/postgres" - dataSource.user = ${nodeOrganizationName} + dataSource.user = ${custom.nodeOrganizationName} dataSource.password = "1234" } database = { transactionIsolationLevel = READ_COMMITTED - schema = ${nodeOrganizationName} + schema = ${custom.nodeOrganizationName} } \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/integration-sql-server.conf b/testing/test-utils/src/main/resources/integration-sql-server.conf index 454f1d4442..d77cc8e591 100644 --- a/testing/test-utils/src/main/resources/integration-sql-server.conf +++ b/testing/test-utils/src/main/resources/integration-sql-server.conf @@ -1,11 +1,11 @@ dataSourceProperties = { dataSourceClassName = "com.microsoft.sqlserver.jdbc.SQLServerDataSource" dataSource.url = "jdbc:sqlserver://[HOST]:[PORT]" - dataSource.user = ${nodeOrganizationName} + dataSource.user = ${custom.nodeOrganizationName} dataSource.password = "yourStrong(!)Password" } database = { transactionIsolationLevel = READ_COMMITTED initDatabase = true - schema = ${nodeOrganizationName} + schema = ${custom.nodeOrganizationName} }