mirror of
https://github.com/corda/corda.git
synced 2025-02-02 09:18:13 +00:00
Added new integration test for the IRSDemo and refactored the demo to
run in integration tests.
This commit is contained in:
parent
9639768069
commit
507d9ea4ae
@ -52,7 +52,7 @@ class ConfigurationException(message: String) : Exception(message)
|
|||||||
* Listed clientAPI classes are assumed to have to take a single APIServer constructor parameter
|
* Listed clientAPI classes are assumed to have to take a single APIServer constructor parameter
|
||||||
* @param clock The clock used within the node and by all protocols etc
|
* @param clock The clock used within the node and by all protocols etc
|
||||||
*/
|
*/
|
||||||
class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration,
|
open class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration,
|
||||||
networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>,
|
networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>,
|
||||||
clock: Clock = NodeClock(),
|
clock: Clock = NodeClock(),
|
||||||
val clientAPIs: List<Class<*>> = listOf()) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) {
|
val clientAPIs: List<Class<*>> = listOf()) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) {
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.net.HostAndPort
|
|||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.logElapsedTime
|
import com.r3corda.core.logElapsedTime
|
||||||
|
import com.r3corda.core.messaging.MessagingService
|
||||||
import com.r3corda.node.internal.Node
|
import com.r3corda.node.internal.Node
|
||||||
import com.r3corda.node.services.config.NodeConfiguration
|
import com.r3corda.node.services.config.NodeConfiguration
|
||||||
import com.r3corda.node.services.config.NodeConfigurationFromConfig
|
import com.r3corda.node.services.config.NodeConfigurationFromConfig
|
||||||
@ -26,6 +27,7 @@ import com.r3corda.node.services.transactions.SimpleNotaryService
|
|||||||
import joptsimple.OptionParser
|
import joptsimple.OptionParser
|
||||||
import joptsimple.OptionSet
|
import joptsimple.OptionSet
|
||||||
import joptsimple.OptionSpec
|
import joptsimple.OptionSpec
|
||||||
|
import joptsimple.OptionSpecBuilder
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
@ -33,6 +35,7 @@ import java.net.URL
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import java.time.Clock
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.concurrent.fixedRateTimer
|
import kotlin.concurrent.fixedRateTimer
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
@ -83,7 +86,28 @@ private class NotSetupException: Throwable {
|
|||||||
constructor(message: String): super(message) {}
|
constructor(message: String): super(message) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val messageNetwork = InMemoryMessagingNetwork()
|
||||||
|
|
||||||
|
class DemoNode(messagingService: MessagingService, dir: Path, p2pAddr: HostAndPort, config: NodeConfiguration,
|
||||||
|
networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>,
|
||||||
|
clock: Clock, clientAPIs: List<Class<*>> = listOf())
|
||||||
|
: Node(dir, p2pAddr, config, networkMapAddress, advertisedServices, clock, clientAPIs) {
|
||||||
|
|
||||||
|
val messagingService = messagingService
|
||||||
|
override fun makeMessagingService(): MessagingService {
|
||||||
|
return messagingService
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun startMessagingService() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
exitProcess(runIRSDemo(args))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runIRSDemo(args: Array<String>, useInMemoryMessaging: Boolean = false): Int {
|
||||||
val parser = OptionParser()
|
val parser = OptionParser()
|
||||||
val demoArgs = setupArgs(parser)
|
val demoArgs = setupArgs(parser)
|
||||||
val options = try {
|
val options = try {
|
||||||
@ -91,7 +115,7 @@ fun main(args: Array<String>) {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(e.message)
|
println(e.message)
|
||||||
printHelp()
|
printHelp()
|
||||||
exitProcess(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suppress the Artemis MQ noise, and activate the demo logging.
|
// Suppress the Artemis MQ noise, and activate the demo logging.
|
||||||
@ -114,14 +138,12 @@ fun main(args: Array<String>) {
|
|||||||
"http://localhost:" + (Node.DEFAULT_PORT + 1)
|
"http://localhost:" + (Node.DEFAULT_PORT + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runTrade(tradeId, host)) {
|
if (!runTrade(tradeId, host)) {
|
||||||
exitProcess(0)
|
return 1
|
||||||
} else {
|
|
||||||
exitProcess(1)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println("Please provide a trade ID")
|
println("Please provide a trade ID")
|
||||||
exitProcess(1)
|
return 1
|
||||||
}
|
}
|
||||||
} else if(role == IRSDemoRole.Date) {
|
} else if(role == IRSDemoRole.Date) {
|
||||||
val dateStrArgs = options.valuesOf(demoArgs.nonOptions)
|
val dateStrArgs = options.valuesOf(demoArgs.nonOptions)
|
||||||
@ -133,10 +155,12 @@ fun main(args: Array<String>) {
|
|||||||
"http://localhost:" + (Node.DEFAULT_PORT + 1)
|
"http://localhost:" + (Node.DEFAULT_PORT + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
runDateChange(dateStr, host)
|
if(!runDateChange(dateStr)) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
println("Please provide a date")
|
println("Please provide a date")
|
||||||
exitProcess(1)
|
return 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If these directory and identity file arguments aren't specified then we can assume a default setup and
|
// If these directory and identity file arguments aren't specified then we can assume a default setup and
|
||||||
@ -147,14 +171,14 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runNode(configureNodeParams(role, demoArgs, options))
|
runNode(configureNodeParams(role, demoArgs, options), useInMemoryMessaging)
|
||||||
} catch (e: NotSetupException) {
|
} catch (e: NotSetupException) {
|
||||||
println(e.message)
|
println(e.message)
|
||||||
exitProcess(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
exitProcess(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupArgs(parser: OptionParser): DemoArgs {
|
private fun setupArgs(parser: OptionParser): DemoArgs {
|
||||||
@ -233,8 +257,11 @@ private fun configureNodeParams(role: IRSDemoRole, args: DemoArgs, options: Opti
|
|||||||
return nodeParams
|
return nodeParams
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runNode(nodeParams : NodeParams) : Unit {
|
private fun runNode(nodeParams : NodeParams, useInMemoryMessaging: Boolean) : Unit {
|
||||||
val node = startNode(nodeParams)
|
val node = when(useInMemoryMessaging) {
|
||||||
|
true -> startDemoNode(nodeParams)
|
||||||
|
false -> startNode(nodeParams)
|
||||||
|
}
|
||||||
// Register handlers for the demo
|
// Register handlers for the demo
|
||||||
AutoOfferProtocol.Handler.register(node)
|
AutoOfferProtocol.Handler.register(node)
|
||||||
UpdateBusinessDayProtocol.Handler.register(node)
|
UpdateBusinessDayProtocol.Handler.register(node)
|
||||||
@ -417,6 +444,36 @@ private fun startNode(params : NodeParams) : Node {
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun startDemoNode(params : NodeParams) : Node {
|
||||||
|
val config = createNodeConfig(params)
|
||||||
|
val advertisedServices: Set<ServiceType>
|
||||||
|
val myNetAddr = HostAndPort.fromString(params.address).withDefaultPort(Node.DEFAULT_PORT)
|
||||||
|
val networkMapId = if (params.mapAddress.equals(params.address)) {
|
||||||
|
// This node provides network map and notary services
|
||||||
|
advertisedServices = setOf(NetworkMapService.Type, NotaryService.Type)
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
advertisedServices = setOf(NodeInterestRates.Type)
|
||||||
|
|
||||||
|
val handle = InMemoryMessagingNetwork.Handle(createNodeAParams().id, params.defaultLegalName)
|
||||||
|
nodeInfo(handle, params.identityFile, setOf(NetworkMapService.Type, NotaryService.Type))
|
||||||
|
}
|
||||||
|
|
||||||
|
val messageService = messageNetwork.createNodeWithID(false, params.id).start().get()
|
||||||
|
val node = logElapsedTime("Node startup") { DemoNode(messageService, params.dir, myNetAddr, config, networkMapId,
|
||||||
|
advertisedServices, DemoClock(),
|
||||||
|
listOf(InterestRateSwapAPI::class.java)).setup().start() }
|
||||||
|
|
||||||
|
// TODO: This should all be replaced by the identity service being updated
|
||||||
|
// as the network map changes.
|
||||||
|
val identityFile = params.tradeWithIdentities[0]
|
||||||
|
val handle = InMemoryMessagingNetwork.Handle(1 - params.id, "Other Node")
|
||||||
|
val peerId = nodeInfo(handle, identityFile)
|
||||||
|
node.services.identityService.registerIdentity(peerId.identity)
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
private fun getRoleDir(role: IRSDemoRole) : Path {
|
private fun getRoleDir(role: IRSDemoRole) : Path {
|
||||||
when(role) {
|
when(role) {
|
||||||
IRSDemoRole.NodeA -> return Paths.get("nodeA")
|
IRSDemoRole.NodeA -> return Paths.get("nodeA")
|
||||||
|
66
src/test/kotlin/com/r3corda/core/testing/IRSDemoTest.kt
Normal file
66
src/test/kotlin/com/r3corda/core/testing/IRSDemoTest.kt
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package com.r3corda.core.testing
|
||||||
|
|
||||||
|
import com.r3corda.demos.runIRSDemo
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
|
||||||
|
class IRSDemoTest {
|
||||||
|
@Test fun `runs IRS demo`() {
|
||||||
|
val dirA = Paths.get("./nodeA")
|
||||||
|
val dirB = Paths.get("./nodeB")
|
||||||
|
try {
|
||||||
|
setupNodeA(dirA)
|
||||||
|
setupNodeB(dirB)
|
||||||
|
startNodeA(dirA)
|
||||||
|
startNodeB(dirB)
|
||||||
|
runTrade()
|
||||||
|
runDateChange()
|
||||||
|
stopNodeA()
|
||||||
|
stopNodeB()
|
||||||
|
} finally {
|
||||||
|
cleanup(dirA)
|
||||||
|
cleanup(dirB)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupNodeA(dir: Path) {
|
||||||
|
runIRSDemo(arrayOf("--role", "SetupNodeA", "--dir", dir.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupNodeB(dir: Path) {
|
||||||
|
runIRSDemo(arrayOf("--role", "SetupNodeB", "--dir", dir.toString()))
|
||||||
|
}
|
||||||
|
private fun startNodeA(dir: Path) {
|
||||||
|
thread(true, false, null, "NodeA", -1, { runIRSDemo(arrayOf("--role", "NodeA", "--dir", dir.toString()), true) })
|
||||||
|
Thread.sleep(15000)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startNodeB(dir: Path) {
|
||||||
|
thread(true, false, null, "NodeB", -1, { runIRSDemo(arrayOf("--role", "NodeB", "--dir", dir.toString()), true) })
|
||||||
|
Thread.sleep(15000)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopNodeA() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopNodeB() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runTrade() {
|
||||||
|
assertEquals(runIRSDemo(arrayOf("--role", "Trade", "trade1")), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runDateChange() {
|
||||||
|
assertEquals(runIRSDemo(arrayOf("--role", "Date", "2017-01-02")), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cleanup(dir: Path) {
|
||||||
|
println("Erasing: " + dir.toString())
|
||||||
|
dir.toFile().deleteRecursively()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user