Added port argument for IRS demo to allow web servers to not have binding collisions during testing and to allow more granular control over demos.

This commit is contained in:
Clinton Alexander 2016-06-22 16:21:44 +01:00 committed by Andras Slemmer
parent 4900c7eb26
commit ffa9ad1bc9
4 changed files with 38 additions and 16 deletions

View File

@ -71,6 +71,9 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration
// when our process shuts down, but we try in stop() anyway just to be nice. // when our process shuts down, but we try in stop() anyway just to be nice.
private var nodeFileLock: FileLock? = null private var nodeFileLock: FileLock? = null
// Todo: Move to node config file
private var webServerPort: Int = p2pAddr.port + 1
override fun makeMessagingService(): MessagingService = ArtemisMessagingService(dir, p2pAddr, serverThread) override fun makeMessagingService(): MessagingService = ArtemisMessagingService(dir, p2pAddr, serverThread)
override fun startMessagingService() { override fun startMessagingService() {
@ -78,11 +81,14 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration
(net as ArtemisMessagingService).start() (net as ArtemisMessagingService).start()
} }
fun setWebServerPort(port: Int): Node {
webServerPort = port
return this
}
private fun initWebServer(): Server { private fun initWebServer(): Server {
// Note that the web server handlers will all run concurrently, and not on the node thread. // Note that the web server handlers will all run concurrently, and not on the node thread.
val server = Server(webServerPort)
val port = p2pAddr.port + 1 // TODO: Move this into the node config file.
val server = Server(port)
val handlerCollection = HandlerCollection() val handlerCollection = HandlerCollection()

View File

@ -10,7 +10,8 @@ import java.nio.file.Paths
class IRSDemoTest { class IRSDemoTest {
@Test fun `runs IRS demo`() { @Test fun `runs IRS demo`() {
val nodeAddrA = freeLocalHostAndPort() val nodeAddrA = freeLocalHostAndPort()
val apiAddrA = HostAndPort.fromString("${nodeAddrA.hostText}:${nodeAddrA.port + 1}") val apiAddrA = freeLocalHostAndPort()
val apiAddrB = freeLocalHostAndPort()
val dirA = Paths.get("./nodeA") val dirA = Paths.get("./nodeA")
val dirB = Paths.get("./nodeB") val dirB = Paths.get("./nodeB")
var procA: Process? = null var procA: Process? = null
@ -18,8 +19,8 @@ class IRSDemoTest {
try { try {
setupNode(dirA, "NodeA") setupNode(dirA, "NodeA")
setupNode(dirB, "NodeB") setupNode(dirB, "NodeB")
procA = startNode(dirA, "NodeA", nodeAddrA, nodeAddrA) procA = startNode(dirA, "NodeA", nodeAddrA, nodeAddrA, apiAddrA)
procB = startNode(dirB, "NodeB", freeLocalHostAndPort(), nodeAddrA) procB = startNode(dirB, "NodeB", freeLocalHostAndPort(), nodeAddrA, apiAddrB)
runTrade(apiAddrA) runTrade(apiAddrA)
runDateChange(apiAddrA) runDateChange(apiAddrA)
} finally { } finally {
@ -38,16 +39,21 @@ private fun setupNode(dir: Path, nodeType: String) {
assertEquals(proc.exitValue(), 0) assertEquals(proc.exitValue(), 0)
} }
private fun startNode(dir: Path, nodeType: String, nodeAddr: HostAndPort, networkMapAddr: HostAndPort): Process { private fun startNode(dir: Path,
nodeType: String,
nodeAddr: HostAndPort,
networkMapAddr: HostAndPort,
apiAddr: HostAndPort): Process {
println("Running node $nodeType") println("Running node $nodeType")
println("Node addr: ${nodeAddr.toString()}") println("Node addr: ${nodeAddr.toString()}")
val args = listOf( val args = listOf(
"--role", nodeType, "--role", nodeType,
"--dir", dir.toString(), "--dir", dir.toString(),
"--network-address", nodeAddr.toString(), "--network-address", nodeAddr.toString(),
"--network-map-address", networkMapAddr.toString()) "--network-map-address", networkMapAddr.toString(),
"--api-address", apiAddr.port.toString())
val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemo$nodeType") val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemo$nodeType")
ensureNodeStartsOrKill(proc, nodeAddr) ensureNodeStartsOrKill(proc, apiAddr)
return proc return proc
} }

View File

@ -25,7 +25,7 @@ fun ensureNodeStartsOrKill(proc: Process, nodeAddr: HostAndPort) {
} }
private fun waitForNodeStartup(nodeAddr: HostAndPort) { private fun waitForNodeStartup(nodeAddr: HostAndPort) {
val url = URL("http://${nodeAddr.hostText}:${nodeAddr.port + 1}/api/status") val url = URL("http://${nodeAddr.toString()}/api/status")
var retries = 0 var retries = 0
var respCode: Int var respCode: Int
do { do {

View File

@ -63,6 +63,7 @@ private class NodeParams() {
var dir : Path = Paths.get("") var dir : Path = Paths.get("")
var address : HostAndPort = HostAndPort.fromString("localhost").withDefaultPort(Node.DEFAULT_PORT) var address : HostAndPort = HostAndPort.fromString("localhost").withDefaultPort(Node.DEFAULT_PORT)
var mapAddress: String = "" var mapAddress: String = ""
var apiPort : Int = Node.DEFAULT_PORT + 1
var identityFile: Path = Paths.get("") var identityFile: Path = Paths.get("")
var tradeWithAddrs: List<String> = listOf() var tradeWithAddrs: List<String> = listOf()
var tradeWithIdentities: List<Path> = listOf() var tradeWithIdentities: List<Path> = listOf()
@ -73,6 +74,7 @@ private class NodeParams() {
private class DemoArgs() { private class DemoArgs() {
lateinit var roleArg: OptionSpec<IRSDemoRole> lateinit var roleArg: OptionSpec<IRSDemoRole>
lateinit var networkAddressArg: OptionSpec<String> lateinit var networkAddressArg: OptionSpec<String>
lateinit var apiPort: OptionSpec<Int>
lateinit var dirArg: OptionSpec<String> lateinit var dirArg: OptionSpec<String>
lateinit var networkMapIdentityFile: OptionSpec<String> lateinit var networkMapIdentityFile: OptionSpec<String>
lateinit var networkMapNetAddr: OptionSpec<String> lateinit var networkMapNetAddr: OptionSpec<String>
@ -179,6 +181,7 @@ private fun setupArgs(parser: OptionParser): DemoArgs {
args.roleArg = parser.accepts("role").withRequiredArg().ofType(IRSDemoRole::class.java).required() args.roleArg = parser.accepts("role").withRequiredArg().ofType(IRSDemoRole::class.java).required()
args.networkAddressArg = parser.accepts("network-address").withOptionalArg() args.networkAddressArg = parser.accepts("network-address").withOptionalArg()
args.apiPort = parser.accepts("api-address").withOptionalArg().ofType(Int::class.java)
args.dirArg = parser.accepts("directory").withOptionalArg() args.dirArg = parser.accepts("directory").withOptionalArg()
args.networkMapIdentityFile = parser.accepts("network-map-identity-file").withOptionalArg() args.networkMapIdentityFile = parser.accepts("network-map-identity-file").withOptionalArg()
args.networkMapNetAddr = parser.accepts("network-map-address").withRequiredArg().defaultsTo("localhost") args.networkMapNetAddr = parser.accepts("network-map-address").withRequiredArg().defaultsTo("localhost")
@ -237,6 +240,12 @@ private fun configureNodeParams(role: IRSDemoRole, args: DemoArgs, options: Opti
if (options.has(args.networkAddressArg)) { if (options.has(args.networkAddressArg)) {
nodeParams.address = HostAndPort.fromString(options.valueOf(args.networkAddressArg)).withDefaultPort(Node.DEFAULT_PORT) nodeParams.address = HostAndPort.fromString(options.valueOf(args.networkAddressArg)).withDefaultPort(Node.DEFAULT_PORT)
} }
if(options.has(args.apiPort)) {
nodeParams.apiPort = options.valueOf(args.apiPort)
} else if(options.has(args.networkAddressArg)) {
nodeParams.apiPort = nodeParams.address.port + 1
}
nodeParams.identityFile = if (options.has(args.networkMapIdentityFile)) { nodeParams.identityFile = if (options.has(args.networkMapIdentityFile)) {
Paths.get(options.valueOf(args.networkMapIdentityFile)) Paths.get(options.valueOf(args.networkMapIdentityFile))
} else { } else {
@ -265,8 +274,7 @@ private fun runNode(nodeParams: NodeParams) : Unit {
ExitServerProtocol.Handler.register(node) ExitServerProtocol.Handler.register(node)
if(nodeParams.uploadRates) { if(nodeParams.uploadRates) {
val apiAddr = "http://${nodeParams.address.hostText}:${nodeParams.address.port + 1}"; runUploadRates(HostAndPort.fromString("localhost:${nodeParams.apiPort}"))
runUploadRates(apiAddr)
} }
try { try {
@ -295,7 +303,7 @@ private fun startNode(params : NodeParams, networkMap: SingleMessageRecipient, r
val node = logElapsedTime("Node startup") { Node(params.dir, params.address, config, networkMapId, val node = logElapsedTime("Node startup") { Node(params.dir, params.address, config, networkMapId,
advertisedServices, DemoClock(), advertisedServices, DemoClock(),
listOf(InterestRateSwapAPI::class.java)).start() } listOf(InterestRateSwapAPI::class.java)).setWebServerPort(params.apiPort).start() }
// TODO: This should all be replaced by the identity service being updated // TODO: This should all be replaced by the identity service being updated
// as the network map changes. // as the network map changes.
@ -321,12 +329,12 @@ private fun nodeInfo(recipient: SingleMessageRecipient, identityFile: Path, adve
} }
} }
private fun runUploadRates(host: String) { private fun runUploadRates(host: HostAndPort) {
val fileContents = IOUtils.toString(NodeParams::class.java.getResource("example.rates.txt")) val fileContents = IOUtils.toString(NodeParams::class.java.getResource("example.rates.txt"))
var timer : Timer? = null var timer : Timer? = null
timer = fixedRateTimer("upload-rates", false, 0, 5000, { timer = fixedRateTimer("upload-rates", false, 0, 5000, {
try { try {
val url = URL(host + "/upload/interest-rates") val url = URL("http://${host.toString()}/upload/interest-rates")
if(uploadFile(url, fileContents)) { if(uploadFile(url, fileContents)) {
timer!!.cancel() timer!!.cancel()
println("Rates uploaded successfully") println("Rates uploaded successfully")
@ -415,7 +423,8 @@ private fun uploadFile(url: URL, file: String) : Boolean {
private fun createNodeAParams() : NodeParams { private fun createNodeAParams() : NodeParams {
val params = NodeParams() val params = NodeParams()
params.dir = Paths.get("nodeA") params.dir = Paths.get("nodeA")
params.address = HostAndPort.fromString("localhost") params.address = HostAndPort.fromString("localhost").withDefaultPort(Node.DEFAULT_PORT)
params.apiPort = Node.DEFAULT_PORT + 1
params.tradeWithAddrs = listOf("localhost:31340") params.tradeWithAddrs = listOf("localhost:31340")
params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeB).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME)) params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeB).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))
params.defaultLegalName = "Bank A" params.defaultLegalName = "Bank A"
@ -426,6 +435,7 @@ private fun createNodeBParams() : NodeParams {
val params = NodeParams() val params = NodeParams()
params.dir = Paths.get("nodeB") params.dir = Paths.get("nodeB")
params.address = HostAndPort.fromString("localhost:31340") params.address = HostAndPort.fromString("localhost:31340")
params.apiPort = 31341
params.tradeWithAddrs = listOf("localhost") params.tradeWithAddrs = listOf("localhost")
params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeA).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME)) params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeA).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))
params.defaultLegalName = "Bank B" params.defaultLegalName = "Bank B"