CORDA-2491: Ability to specify Java package namespace from Cordform (#5075)

Add entry point with generic extra configuration options. Move configuration verification code to avoid circular dependencies.
This commit is contained in:
rui-r3 2019-05-09 17:25:21 +01:00 committed by Shams Asari
parent f0c75448b4
commit 9e3a0a64ac
5 changed files with 55 additions and 12 deletions

View File

@ -14,6 +14,9 @@ Version 4.2
of a contract without having to manually install that version, provided a newer version is installed. Similarly, non-contract attachments
are whitelisted if another attachment is present on the node that is signed by the same public key.
* :doc:`design/data-model-upgrades/package-namespace-ownership` configurations can be now be set as described in
:ref:`node_package_namespace_ownership`, when using the Cordformation plugin version 4.0.43.
.. _changelog_v4.0:
Version 4.0

View File

@ -143,6 +143,29 @@ To copy the same file to all nodes `ext.drivers` can be defined in the top level
}
}
.. _node_package_namespace_ownership:
Package namespace ownership
^^^^^^^^^^^^^^^^^^^^^^^^^^^
To specify :doc:`design/data-model-upgrades/package-namespace-ownership` configuration, the optional ``networkParameterOverrides`` and ``packageOwnership`` blocks can be used, similar to the configuration file used in :doc:`network-bootstrapper`:
.. sourcecode:: groovy
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
[...]
networkParameterOverrides {
packageOwnership {
"com.mypackagename" {
keystore = "_teststore"
keystorePassword = "MyStorePassword"
keystoreAlias = "MyKeyAlias"
}
}
}
[...]
}
Signing Cordapp JARs
^^^^^^^^^^^^^^^^^^^^
The default behaviour of Cordform is to deploy CorDapp JARs "as built":

View File

@ -8,6 +8,7 @@ description 'Corda node API'
dependencies {
compile project(":core")
compile project(":serialization") // TODO Remove this once the NetworkBootstrapper class is moved into the tools:bootstrapper module
compile project(':common-configuration-parsing') // TODO Remove this dependency once NetworkBootsrapper is moved into tools:bootstrapper
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

View File

@ -3,6 +3,7 @@ package net.corda.nodeapi.internal.network
import com.typesafe.config.Config
import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigFactory
import net.corda.common.configuration.parsing.internal.Configuration
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.*
@ -198,6 +199,23 @@ internal constructor(private val initSerEnv: Boolean,
bootstrap(directory, cordappJars, CopyCordapps.No, fromCordform = true)
}
/**
* Entry point for Cordform with extra configurations
* @param directory - directory on which the network will be deployed
* @param cordappJars - List of CordApps to deploy
* @param extraConfigurations - HOCON representation of extra configuration parameters
*/
fun bootstrapCordform(directory: Path, cordappJars: List<Path>, extraConfigurations: String) {
val configuration = ConfigFactory.parseString(extraConfigurations).resolve().getObject("networkParameterOverrides").toConfig().parseAsNetworkParametersConfiguration()
val networkParametersOverrides = configuration.doOnErrors(::reportErrors).optional ?: throw IllegalStateException("Invalid configuration passed.")
bootstrap(directory, cordappJars, CopyCordapps.No, fromCordform = true, networkParametersOverrides = networkParametersOverrides)
}
private fun reportErrors(errors: Set<Configuration.Validation.Error>) {
System.err.println("Error(s) found parsing the networkParameterOverrides:")
errors.forEach { System.err.println("Error parsing ${it.pathAsString}: ${it.message}") }
}
/** Entry point for the tool */
override fun bootstrap(directory: Path, copyCordapps: CopyCordapps, networkParameterOverrides: NetworkParametersOverrides) {
require(networkParameterOverrides.minimumPlatformVersion == null || networkParameterOverrides.minimumPlatformVersion <= PLATFORM_VERSION) { "Minimum platform version cannot be greater than $PLATFORM_VERSION" }

View File

@ -1,4 +1,4 @@
package net.corda.bootstrapper
package net.corda.nodeapi.internal.network
import com.typesafe.config.Config
import net.corda.common.configuration.parsing.internal.Configuration
@ -9,15 +9,13 @@ import net.corda.common.validation.internal.Validated
import net.corda.core.internal.noPackageOverlap
import net.corda.core.internal.requirePackageValid
import net.corda.nodeapi.internal.crypto.loadKeyStore
import net.corda.nodeapi.internal.network.NetworkParametersOverrides
import net.corda.nodeapi.internal.network.PackageOwner
import java.io.IOException
import java.nio.file.InvalidPathException
import java.nio.file.Path
import java.nio.file.Paths
import java.security.KeyStoreException
internal typealias Valid<TARGET> = Validated<TARGET, Configuration.Validation.Error>
typealias Valid<TARGET> = Validated<TARGET, Configuration.Validation.Error>
fun Config.parseAsNetworkParametersConfiguration(options: Configuration.Validation.Options = Configuration.Validation.Options(strict = false)):
Valid<NetworkParametersOverrides> = NetworkParameterOverridesSpec.parse(this, options)
@ -26,15 +24,15 @@ internal fun <T> badValue(msg: String): Valid<T> = Validated.invalid(sequenceOf(
internal fun <T> valid(value: T): Valid<T> = Validated.valid(value)
internal object NetworkParameterOverridesSpec : Configuration.Specification<NetworkParametersOverrides>("DefaultNetworkParameters") {
private val minimumPlatformVersion by int().mapValid(::parsePositiveInteger).optional()
private val maxMessageSize by int().mapValid(::parsePositiveInteger).optional()
private val maxTransactionSize by int().mapValid(::parsePositiveInteger).optional()
private val minimumPlatformVersion by int().mapValid(NetworkParameterOverridesSpec::parsePositiveInteger).optional()
private val maxMessageSize by int().mapValid(NetworkParameterOverridesSpec::parsePositiveInteger).optional()
private val maxTransactionSize by int().mapValid(NetworkParameterOverridesSpec::parsePositiveInteger).optional()
private val packageOwnership by nested(PackageOwnershipSpec).list().optional()
private val eventHorizon by duration().optional()
internal object PackageOwnershipSpec : Configuration.Specification<PackageOwner>("PackageOwners") {
private val packageName by string().mapValid(::toPackageName)
private val keystore by string().mapValid(::toPath)
private val packageName by string().mapValid(PackageOwnershipSpec::toPackageName)
private val keystore by string().mapValid(PackageOwnershipSpec::toPath)
private val keystorePassword by string()
private val keystoreAlias by string()
@ -54,12 +52,12 @@ internal object NetworkParameterOverridesSpec : Configuration.Specification<Netw
val publicKey = ks.getCertificate(configuration[keystoreAlias]).publicKey
valid(PackageOwner(javaPackageName, publicKey))
} catch (kse: KeyStoreException) {
badValue("Keystore has not been initialized for alias ${configuration[keystoreAlias]}")
badValue("Keystore has not been initialized for alias ${configuration[keystoreAlias]}.")
}
} catch (kse: KeyStoreException) {
badValue("Password is incorrect or the key store is damaged for keyStoreFilePath: $suppliedKeystorePath and keyStorePassword: $keystorePassword")
badValue("Password is incorrect or the key store is damaged for keyStoreFilePath: $suppliedKeystorePath.")
} catch (e: IOException) {
badValue("Error reading the key store from the file for keyStoreFilePath: $suppliedKeystorePath and keyStorePassword: $keystorePassword ${e.message}")
badValue("Error reading the key store from the file for keyStoreFilePath: $suppliedKeystorePath ${e.message}.")
}
}