mirror of
https://github.com/corda/corda.git
synced 2024-12-20 05:28:21 +00:00
IRS demo to now has roles for NodeA/NodeB and most options are now~ optional. NodeA can be run without the shell script.
This commit is contained in:
parent
2365f9bca5
commit
9a619cc4ae
@ -20,9 +20,7 @@ if [[ "$mode" == "nodeA" ]]; then
|
|||||||
RC=83
|
RC=83
|
||||||
while [ $RC -eq 83 ]
|
while [ $RC -eq 83 ]
|
||||||
do
|
do
|
||||||
build/install/r3prototyping/bin/irsdemo --dir=nodeA --network-address=localhost \
|
build/install/r3prototyping/bin/irsdemo --role=NodeA
|
||||||
--fake-trade-with-address=localhost:31340 --fake-trade-with-identity=nodeB/identity-public \
|
|
||||||
--network-map-identity-file=nodeA/identity-public --network-map-address=localhost
|
|
||||||
RC=$?
|
RC=$?
|
||||||
done
|
done
|
||||||
elif [[ "$mode" == "nodeB" ]]; then
|
elif [[ "$mode" == "nodeB" ]]; then
|
||||||
@ -37,9 +35,7 @@ elif [[ "$mode" == "nodeB" ]]; then
|
|||||||
RC=83
|
RC=83
|
||||||
while [ $RC -eq 83 ]
|
while [ $RC -eq 83 ]
|
||||||
do
|
do
|
||||||
build/install/r3prototyping/bin/irsdemo --dir=nodeB --network-address=localhost:31340 \
|
build/install/r3prototyping/bin/irsdemo --role=NodeB &
|
||||||
--fake-trade-with-address=localhost --fake-trade-with-identity=nodeA/identity-public \
|
|
||||||
--network-map-identity-file=nodeA/identity-public --network-map-address=localhost &
|
|
||||||
while ! curl -F rates=@scripts/example.rates.txt http://localhost:31341/upload/interest-rates; do
|
while ! curl -F rates=@scripts/example.rates.txt http://localhost:31341/upload/interest-rates; do
|
||||||
echo "Retry to upload interest rates to oracle after 5 seconds"
|
echo "Retry to upload interest rates to oracle after 5 seconds"
|
||||||
sleep 5
|
sleep 5
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
package com.r3corda.demos
|
package com.r3corda.demos
|
||||||
|
|
||||||
import com.google.common.net.HostAndPort
|
import com.google.common.net.HostAndPort
|
||||||
|
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.node.internal.Node
|
||||||
|
import com.r3corda.node.services.config.NodeConfiguration
|
||||||
|
import com.r3corda.node.services.config.NodeConfigurationFromConfig
|
||||||
import com.r3corda.core.node.NodeInfo
|
import com.r3corda.core.node.NodeInfo
|
||||||
|
import com.r3corda.node.services.network.NetworkMapService
|
||||||
|
import com.r3corda.node.services.clientapi.NodeInterestRates
|
||||||
|
import com.r3corda.node.services.transactions.NotaryService
|
||||||
import com.r3corda.core.node.services.ServiceType
|
import com.r3corda.core.node.services.ServiceType
|
||||||
|
import com.r3corda.node.services.messaging.ArtemisMessagingService
|
||||||
import com.r3corda.core.serialization.deserialize
|
import com.r3corda.core.serialization.deserialize
|
||||||
import com.r3corda.core.utilities.BriefLogFormatter
|
import com.r3corda.core.utilities.BriefLogFormatter
|
||||||
import com.r3corda.demos.api.InterestRateSwapAPI
|
import com.r3corda.demos.api.InterestRateSwapAPI
|
||||||
import com.r3corda.demos.protocols.AutoOfferProtocol
|
import com.r3corda.demos.protocols.AutoOfferProtocol
|
||||||
import com.r3corda.demos.protocols.ExitServerProtocol
|
import com.r3corda.demos.protocols.ExitServerProtocol
|
||||||
import com.r3corda.demos.protocols.UpdateBusinessDayProtocol
|
import com.r3corda.demos.protocols.UpdateBusinessDayProtocol
|
||||||
import com.r3corda.node.internal.Node
|
|
||||||
import com.r3corda.node.services.clientapi.NodeInterestRates
|
|
||||||
import com.r3corda.node.services.config.NodeConfiguration
|
|
||||||
import com.r3corda.node.services.config.NodeConfigurationFromConfig
|
|
||||||
import com.r3corda.node.services.messaging.ArtemisMessagingService
|
|
||||||
import com.r3corda.node.services.network.NetworkMapService
|
|
||||||
import com.r3corda.node.services.transactions.SimpleNotaryService
|
|
||||||
import com.typesafe.config.ConfigFactory
|
|
||||||
import joptsimple.OptionParser
|
import joptsimple.OptionParser
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -29,17 +29,34 @@ import kotlin.system.exitProcess
|
|||||||
//
|
//
|
||||||
// TODO: Please see TBD
|
// TODO: Please see TBD
|
||||||
|
|
||||||
|
enum class IRSDemoRole {
|
||||||
|
NodeA,
|
||||||
|
NodeB
|
||||||
|
}
|
||||||
|
|
||||||
|
class NodeParams() {
|
||||||
|
public var dir : Path = Paths.get("")
|
||||||
|
public var address : String = ""
|
||||||
|
public var mapAddress: String = ""
|
||||||
|
public var identityFile: Path = Paths.get("")
|
||||||
|
public var tradeWithAddrs: List<String> = listOf()
|
||||||
|
public var tradeWithIdentities: List<Path> = listOf()
|
||||||
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val parser = OptionParser()
|
val parser = OptionParser()
|
||||||
val networkAddressArg = parser.accepts("network-address").withRequiredArg().required()
|
|
||||||
val dirArg = parser.accepts("directory").withRequiredArg().defaultsTo("nodedata")
|
|
||||||
|
|
||||||
val networkMapIdentityFile = parser.accepts("network-map-identity-file").withRequiredArg()
|
val roleArg = parser.accepts("role").withRequiredArg().ofType(IRSDemoRole::class.java).required()
|
||||||
val networkMapNetAddr = parser.accepts("network-map-address").requiredIf(networkMapIdentityFile).withRequiredArg()
|
|
||||||
|
val networkAddressArg = parser.accepts("network-address").withOptionalArg()
|
||||||
|
val dirArg = parser.accepts("directory").withOptionalArg()
|
||||||
|
|
||||||
|
val networkMapIdentityFile = parser.accepts("network-map-identity-file").withOptionalArg()
|
||||||
|
val networkMapNetAddr = parser.accepts("network-map-address").withRequiredArg().defaultsTo("localhost")
|
||||||
|
|
||||||
// Use these to list one or more peers (again, will be superseded by discovery implementation)
|
// Use these to list one or more peers (again, will be superseded by discovery implementation)
|
||||||
val fakeTradeWithAddr = parser.accepts("fake-trade-with-address").withRequiredArg().required()
|
val fakeTradeWithAddr = parser.accepts("fake-trade-with-address").withOptionalArg()
|
||||||
val fakeTradeWithIdentityFile = parser.accepts("fake-trade-with-identity-file").withRequiredArg().required()
|
val fakeTradeWithIdentityFile = parser.accepts("fake-trade-with-identity-file").withOptionalArg()
|
||||||
|
|
||||||
val options = try {
|
val options = try {
|
||||||
parser.parse(*args)
|
parser.parse(*args)
|
||||||
@ -52,50 +69,37 @@ fun main(args: Array<String>) {
|
|||||||
// Suppress the Artemis MQ noise, and activate the demo logging.
|
// Suppress the Artemis MQ noise, and activate the demo logging.
|
||||||
BriefLogFormatter.initVerbose("+demo.irsdemo", "+api-call", "+platform.deal", "-org.apache.activemq")
|
BriefLogFormatter.initVerbose("+demo.irsdemo", "+api-call", "+platform.deal", "-org.apache.activemq")
|
||||||
|
|
||||||
val dir = Paths.get(options.valueOf(dirArg))
|
val role = options.valueOf(roleArg)!!
|
||||||
val configFile = dir.resolve("config")
|
val nodeParams = when(role) {
|
||||||
|
IRSDemoRole.NodeA -> createNodeAParams()
|
||||||
if (!Files.exists(dir)) {
|
IRSDemoRole.NodeB -> createNodeBParams()
|
||||||
Files.createDirectory(dir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val config = loadConfigFile(configFile)
|
nodeParams.mapAddress = options.valueOf(networkMapNetAddr)
|
||||||
val advertisedServices: Set<ServiceType>
|
if(options.has(dirArg)) {
|
||||||
val myNetAddr = HostAndPort.fromString(options.valueOf(networkAddressArg)).withDefaultPort(Node.DEFAULT_PORT)
|
nodeParams.dir = Paths.get(options.valueOf(dirArg))
|
||||||
|
}
|
||||||
val networkMapId = if (options.valueOf(networkMapNetAddr).equals(options.valueOf(networkAddressArg))) {
|
if(options.has(networkAddressArg)) {
|
||||||
// This node provides network map and notary services
|
nodeParams.address = options.valueOf(networkAddressArg)
|
||||||
advertisedServices = setOf(NetworkMapService.Type, SimpleNotaryService.Type)
|
}
|
||||||
null
|
nodeParams.identityFile = if(options.has(networkMapIdentityFile)) {
|
||||||
|
Paths.get(options.valueOf(networkMapIdentityFile))
|
||||||
} else {
|
} else {
|
||||||
advertisedServices = setOf(NodeInterestRates.Type)
|
nodeParams.dir.resolve("identity-public")
|
||||||
try {
|
}
|
||||||
nodeInfo(options.valueOf(networkMapNetAddr), options.valueOf(networkMapIdentityFile), setOf(NetworkMapService.Type, SimpleNotaryService.Type))
|
if(options.has(fakeTradeWithIdentityFile)) {
|
||||||
} catch (e: Exception) {
|
nodeParams.tradeWithIdentities = options.valuesOf(fakeTradeWithIdentityFile).map { Paths.get(it) }
|
||||||
null
|
}
|
||||||
}
|
if(options.has(fakeTradeWithAddr)) {
|
||||||
|
nodeParams.tradeWithAddrs = options.valuesOf(fakeTradeWithAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
val node = logElapsedTime("Node startup") { Node(dir, myNetAddr, config, networkMapId,
|
runNode(nodeParams)
|
||||||
advertisedServices, DemoClock(),
|
exitProcess(0)
|
||||||
listOf(InterestRateSwapAPI::class.java)).start() }
|
}
|
||||||
|
|
||||||
// TODO: This should all be replaced by the identity service being updated
|
|
||||||
// as the network map changes.
|
|
||||||
val hostAndPortStrings = options.valuesOf(fakeTradeWithAddr)
|
|
||||||
val identityFiles = options.valuesOf(fakeTradeWithIdentityFile)
|
|
||||||
if (hostAndPortStrings.size != identityFiles.size) {
|
|
||||||
throw IllegalArgumentException("Different number of peer addresses (${hostAndPortStrings.size}) and identities (${identityFiles.size})")
|
|
||||||
}
|
|
||||||
for ((hostAndPortString, identityFile) in hostAndPortStrings.zip(identityFiles)) {
|
|
||||||
try {
|
|
||||||
val peerId = nodeInfo(hostAndPortString, identityFile)
|
|
||||||
node.services.identityService.registerIdentity(peerId.identity)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
println("Could not load peer identity file \"$identityFile\".")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fun runNode(nodeParams : NodeParams) : Unit {
|
||||||
|
val node = 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)
|
||||||
@ -106,13 +110,84 @@ fun main(args: Array<String>) {
|
|||||||
} catch(e: InterruptedException) {
|
} catch(e: InterruptedException) {
|
||||||
node.stop()
|
node.stop()
|
||||||
}
|
}
|
||||||
exitProcess(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nodeInfo(hostAndPortString: String, identityFile: String, advertisedServices: Set<ServiceType> = emptySet()): NodeInfo {
|
fun createNodeAParams() : NodeParams {
|
||||||
|
val params = NodeParams()
|
||||||
|
params.dir = Paths.get("nodeA")
|
||||||
|
params.address = "localhost"
|
||||||
|
params.tradeWithAddrs = listOf("localhost:31340")
|
||||||
|
params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeB).resolve("identity-public"))
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createNodeBParams() : NodeParams {
|
||||||
|
val params = NodeParams()
|
||||||
|
params.dir = Paths.get("nodeB")
|
||||||
|
params.address = "localhost:31340"
|
||||||
|
params.tradeWithAddrs = listOf("localhost")
|
||||||
|
params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeA).resolve("identity-public"))
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startNode(params : NodeParams) : Node {
|
||||||
|
if (!Files.exists(params.dir)) {
|
||||||
|
Files.createDirectory(params.dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val configFile = params.dir.resolve("config")
|
||||||
|
val config = loadConfigFile(configFile)
|
||||||
|
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)
|
||||||
|
|
||||||
|
try {
|
||||||
|
nodeInfo(params.mapAddress, params.identityFile, setOf(NetworkMapService.Type, SimpleNotaryService.Type))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val node = logElapsedTime("Node startup") { Node(params.dir, myNetAddr, config, networkMapId,
|
||||||
|
advertisedServices, DemoClock(),
|
||||||
|
listOf(InterestRateSwapAPI::class.java)).start() }
|
||||||
|
|
||||||
|
// TODO: This should all be replaced by the identity service being updated
|
||||||
|
// as the network map changes.
|
||||||
|
if (params.tradeWithAddrs.size != params.tradeWithIdentities.size) {
|
||||||
|
throw IllegalArgumentException("Different number of peer addresses (${params.tradeWithAddrs.size}) and identities (${params.tradeWithIdentities.size})")
|
||||||
|
}
|
||||||
|
for ((hostAndPortString, identityFile) in params.tradeWithAddrs.zip(params.tradeWithIdentities)) {
|
||||||
|
try {
|
||||||
|
val peerId = nodeInfo(hostAndPortString, identityFile)
|
||||||
|
node.services.identityService.registerIdentity(peerId.identity)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println("Could not load peer identity file \"$identityFile\".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRoleDir(role: IRSDemoRole) : Path {
|
||||||
|
when(role) {
|
||||||
|
IRSDemoRole.NodeA -> return Paths.get("nodeA")
|
||||||
|
IRSDemoRole.NodeB -> return Paths.get("nodeB")
|
||||||
|
else -> {
|
||||||
|
return Paths.get("nodedata")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nodeInfo(hostAndPortString: String, identityFile: Path, advertisedServices: Set<ServiceType> = emptySet()): NodeInfo {
|
||||||
try {
|
try {
|
||||||
val addr = HostAndPort.fromString(hostAndPortString).withDefaultPort(Node.DEFAULT_PORT)
|
val addr = HostAndPort.fromString(hostAndPortString).withDefaultPort(Node.DEFAULT_PORT)
|
||||||
val path = Paths.get(identityFile)
|
val path = identityFile
|
||||||
val party = Files.readAllBytes(path).deserialize<Party>()
|
val party = Files.readAllBytes(path).deserialize<Party>()
|
||||||
return NodeInfo(ArtemisMessagingService.makeRecipient(addr), party, advertisedServices)
|
return NodeInfo(ArtemisMessagingService.makeRecipient(addr), party, advertisedServices)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Loading…
Reference in New Issue
Block a user