Skip to content

Commit

Permalink
EG-1856: Allow users to specify Dockerform ports (#305)
Browse files Browse the repository at this point in the history
* Allow users to specify Dockerform ports
* Updated changelog
* Addressing PR comments
* Added unit tests to validate correct parsing
* Addressed PR comments

Co-authored-by: Andrei Palade <[email protected]>
  • Loading branch information
palade and palade authored May 6, 2020
1 parent 45cba09 commit b21cdae
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 6 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Version 5.0.9

* `cordformation`: Added option to deploy external databases using docker compose task
* `cordformation`: Allow users to specify ports in Dockerform
* `cordformation`: Use GNU Screen in `runnodes` on macOS to start nodes in different Screen windows. Activated when the user is already running `screen`.

* `jar-filter`: Initial support for byte-code compiled by Kotlin >= 1.4.0 (See [KT-31352](https://youtrack.jetbrains.com/issue/KT-31352)).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package net.corda.plugins

import org.gradle.api.InvalidUserDataException
import java.net.URI
import java.net.URISyntaxException

class ConfigurationUtils {

companion object {

fun parsePort(address: String): Int {
return try {
URI(null, address, null, null, null).port
} catch (ex: URISyntaxException) {
throw InvalidUserDataException("Invalid host and port syntax for RPC address, expected host:port")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ open class Dockerform @Inject constructor(objects: ObjectFactory) : Baseform(obj
"$nodeBuildDir/additional-node-infos:/opt/corda/additional-node-infos",
"$nodeBuildDir/drivers:/opt/corda/drivers"
),
"ports" to listOf(it.rpcPort, it.config.getInt("sshd.port")),
"ports" to listOf(it.rpcPort.get(), it.config.getInt("sshd.port")),
"image" to (dockerImage ?: "corda/corda-zulu-${it.runtimeVersion().toLowerCase()}")
)

Expand Down
10 changes: 6 additions & 4 deletions cordformation/src/main/kotlin/net/corda/plugins/Node.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import groovy.lang.Closure
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
Expand Down Expand Up @@ -57,9 +58,11 @@ open class Node @Inject constructor(private val project: Project) {
private var rpcSettings: RpcSettings = RpcSettings()
private var webserverJar: String? = null
private var p2pPort = 10002
internal var rpcPort = 10003
@Input get
private set
@get:Input
val rpcPort: Provider<Int> = project.objects.property(Int::class.javaObjectType).apply {
set(project.provider { rpcSettings.port })
}

internal var config = ConfigFactory.empty()
@Internal get
private set
Expand Down Expand Up @@ -186,7 +189,6 @@ open class Node @Inject constructor(private val project: Project) {
@Deprecated("Use {@link CordformNode#rpcSettings(RpcSettings)} instead. Will be removed by Corda V5.0.")
fun rpcPort(rpcPort: Int) {
rpcAddress(DEFAULT_HOST + ':'.toString() + rpcPort)
this.rpcPort = rpcPort
}

/**
Expand Down
13 changes: 13 additions & 0 deletions cordformation/src/main/kotlin/net/corda/plugins/RpcSettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package net.corda.plugins
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigValueFactory
import org.gradle.api.InvalidUserDataException
import org.gradle.api.tasks.Input
import java.net.URI
import java.net.URISyntaxException

class RpcSettings {
private var config = ConfigFactory.empty()
Expand All @@ -19,6 +22,11 @@ class RpcSettings {
* RPC address for the node.
*/
fun address(value: String) {
val parsedValue = ConfigurationUtils.parsePort(value)
port = when (parsedValue) {
-1 -> port
else -> parsedValue
}
setValue("address", value)
}

Expand All @@ -34,6 +42,11 @@ class RpcSettings {
* RPC admin address for the node (necessary if [useSsl] is false or unset).
*/
fun adminAddress(value: String) {
val parsedValue = ConfigurationUtils.parsePort(value)
adminPort = when (parsedValue) {
-1 -> adminPort
else -> parsedValue
}
setValue("adminAddress", value)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ open class BaseformTest {
fun getNodeCordappJar(nodeName: String, cordappJarName: String) = Paths.get(testProjectDir.toAbsolutePath().toString(), "build", "nodes", nodeName, "cordapps", "$cordappJarName.jar")
fun getNodeCordappConfig(nodeName: String, cordappJarName: String) = Paths.get(testProjectDir.toAbsolutePath().toString(), "build", "nodes", nodeName, "cordapps", "config", "$cordappJarName.conf")
fun getNetworkParameterOverrides(nodeName: String) = Paths.get(testProjectDir.toAbsolutePath().toString(), "build", "nodes", nodeName, "network-parameters")
fun getNodeConfig(nodeName: String) = Paths.get(testProjectDir.toAbsolutePath().toString(), "build", "nodes", nodeName, "node.conf")

class AMQPParametersSerializationScheme : AbstractAMQPSerializationScheme(emptyList()) {
override fun rpcClientSerializerFactory(context: SerializationContext) = throw UnsupportedOperationException()
Expand All @@ -66,5 +67,4 @@ open class BaseformTest {
return magic == amqpMagic && target == SerializationContext.UseCase.P2P
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.corda.plugins


import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class ConfigurationUtilsTest {

@Test
fun `check correct port value parsing`() {
assertEquals(10000, ConfigurationUtils.parsePort("localhost:10000"))
}

@Test
fun `missing port value correctly identified in valid address`() {
assertEquals(-1, ConfigurationUtils.parsePort("localhost"))
}

@Test
fun `missing port value correctly identified in invalid address`() {
assertEquals(-1, ConfigurationUtils.parsePort("localhost!"))
}
}
40 changes: 40 additions & 0 deletions cordformation/src/test/kotlin/net/corda/plugins/DockerformTest.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package net.corda.plugins

import com.typesafe.config.ConfigFactory
import org.assertj.core.api.Assertions.assertThat
import org.gradle.testkit.runner.TaskOutcome
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class DockerformTest : BaseformTest() {

Expand Down Expand Up @@ -93,4 +96,41 @@ class DockerformTest : BaseformTest() {
assertThat(getNodeCordappJar(notaryNodeName, cordaFinanceContractsJarName)).isRegularFile()
assertThat(getNetworkParameterOverrides(notaryNodeName)).isRegularFile()
}

@Test
fun `deploy two nodes with cordapp dependencies`() {
val runner = getStandardGradleRunnerFor(
"DeployTwoNodeCordappWithDocker.gradle",
"prepareDockerNodes")

val result = runner.build()

val bankOfCordaNodeName = "BankOfCorda"

assertThat(result.task(":prepareDockerNodes")!!.outcome).isEqualTo(TaskOutcome.SUCCESS)
assertThat(getNodeCordappJar(notaryNodeName, cordaFinanceWorkflowsJarName)).isRegularFile()
assertThat(getNodeCordappJar(notaryNodeName, cordaFinanceContractsJarName)).isRegularFile()
assertThat(getNetworkParameterOverrides(notaryNodeName)).isRegularFile()
assertThat(getNodeCordappJar(bankOfCordaNodeName, cordaFinanceWorkflowsJarName)).isRegularFile()
assertThat(getNodeCordappJar(bankOfCordaNodeName, cordaFinanceContractsJarName)).isRegularFile()
assertThat(getNetworkParameterOverrides(bankOfCordaNodeName)).isRegularFile()

val notaryConfigPath = getNodeConfig(notaryNodeName)
assertThat(notaryConfigPath).isRegularFile()

val notaryConfig = ConfigFactory.parseFile(notaryConfigPath.toFile())
assertTrue(notaryConfig.hasPath("rpcSettings.address"))
assertTrue(notaryConfig.hasPath("rpcSettings.adminAddress"))
assertEquals(10003, ConfigurationUtils.parsePort(notaryConfig.getString("rpcSettings.address")))
assertEquals(10043, ConfigurationUtils.parsePort(notaryConfig.getString("rpcSettings.adminAddress")))

val bankOfCordaConfigPath = getNodeConfig(bankOfCordaNodeName)
assertThat(bankOfCordaConfigPath).isRegularFile()

val bankOfCordaConfig = ConfigFactory.parseFile(bankOfCordaConfigPath.toFile())
assertTrue(bankOfCordaConfig.hasPath("rpcSettings.address"))
assertTrue(bankOfCordaConfig.hasPath("rpcSettings.adminAddress"))
assertEquals(10006, ConfigurationUtils.parsePort(bankOfCordaConfig.getString("rpcSettings.address")))
assertEquals(10046, ConfigurationUtils.parsePort(bankOfCordaConfig.getString("rpcSettings.adminAddress")))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
plugins {
id 'net.corda.plugins.cordformation'
}

apply from: 'repositories.gradle'

dependencies {
cordaRuntime "$corda_group:corda:$corda_release_version"
cordaRuntime "$corda_group:corda-node-api:$corda_release_version"
cordapp "$corda_group:corda-finance-contracts:$corda_release_version"
cordapp "$corda_group:corda-finance-workflows:$corda_release_version"
}

task prepareDockerNodes(type: net.corda.plugins.Dockerform, dependsOn: ['jar']) {
nodeDefaults {

cordapps = ["$corda_group:corda-finance-contracts:$corda_release_version",
"$corda_group:corda-finance-workflows:$corda_release_version"]

projectCordapp {
deploy false
}
}
node {
name "O=Notary Service,L=London,C=GB"
notary = [validating : false]
p2pPort 10002
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10043")
}
}
node {
name "O=BankOfCorda,L=London,C=GB"
p2pPort 10005
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10046")
}
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
}
}

0 comments on commit b21cdae

Please sign in to comment.