mirror of
https://github.com/corda/corda.git
synced 2025-05-31 22:50:53 +00:00
Tweak the simulation so that the startup sequence of the network (with map registration etc) can be observed.
This commit is contained in:
parent
474054411d
commit
5de2ba4ef9
@ -28,7 +28,7 @@ class IRSSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwork
|
|||||||
|
|
||||||
private val executeOnNextIteration = Collections.synchronizedList(LinkedList<() -> Unit>())
|
private val executeOnNextIteration = Collections.synchronizedList(LinkedList<() -> Unit>())
|
||||||
|
|
||||||
override fun start() {
|
override fun startMainSimulation() {
|
||||||
startIRSDealBetween(0, 1).success {
|
startIRSDealBetween(0, 1).success {
|
||||||
// Next iteration is a pause.
|
// Next iteration is a pause.
|
||||||
executeOnNextIteration.add {}
|
executeOnNextIteration.add {}
|
||||||
|
@ -99,12 +99,13 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
val place: PhysicalLocation get() = info.physicalLocation!!
|
// This does not indirect through the NodeInfo object so it can be called before the node is started.
|
||||||
|
val place: PhysicalLocation get() = findMyLocation()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a started node, optionally created by the passed factory method */
|
/** Returns a node, optionally created by the passed factory method. */
|
||||||
fun createNode(networkMapAddress: NodeInfo? = null, forcedID: Int = -1, nodeFactory: Factory = defaultFactory,
|
fun createNode(networkMapAddress: NodeInfo? = null, forcedID: Int = -1, nodeFactory: Factory = defaultFactory,
|
||||||
legalName: String? = null, keyPair: KeyPair? = null, vararg advertisedServices: ServiceType): MockNode {
|
start: Boolean = true, legalName: String? = null, keyPair: KeyPair? = null, vararg advertisedServices: ServiceType): MockNode {
|
||||||
val newNode = forcedID == -1
|
val newNode = forcedID == -1
|
||||||
val id = if (newNode) counter++ else forcedID
|
val id = if (newNode) counter++ else forcedID
|
||||||
|
|
||||||
@ -116,7 +117,8 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
|||||||
override val exportJMXto: String = ""
|
override val exportJMXto: String = ""
|
||||||
override val nearestCity: String = "Atlantis"
|
override val nearestCity: String = "Atlantis"
|
||||||
}
|
}
|
||||||
val node = nodeFactory.create(path, config, this, networkMapAddress, advertisedServices.toSet(), id, keyPair).start()
|
val node = nodeFactory.create(path, config, this, networkMapAddress, advertisedServices.toSet(), id, keyPair)
|
||||||
|
if (start) node.start()
|
||||||
_nodes.add(node)
|
_nodes.add(node)
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
@ -143,13 +145,23 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
|||||||
fun createTwoNodes(nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = null): Pair<MockNode, MockNode> {
|
fun createTwoNodes(nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = null): Pair<MockNode, MockNode> {
|
||||||
require(nodes.isEmpty())
|
require(nodes.isEmpty())
|
||||||
return Pair(
|
return Pair(
|
||||||
createNode(null, -1, nodeFactory, null, notaryKeyPair, NetworkMapService.Type, NotaryService.Type),
|
createNode(null, -1, nodeFactory, true, null, notaryKeyPair, NetworkMapService.Type, NotaryService.Type),
|
||||||
createNode(nodes[0].info, -1, nodeFactory, null)
|
createNode(nodes[0].info, -1, nodeFactory, true, null)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createNotaryNode(legalName: String? = null, keyPair: KeyPair? = null) = createNode(null, -1, defaultFactory, legalName, keyPair, NetworkMapService.Type, NotaryService.Type)
|
fun createNotaryNode(legalName: String? = null, keyPair: KeyPair? = null) = createNode(null, -1, defaultFactory, true, legalName, keyPair, NetworkMapService.Type, NotaryService.Type)
|
||||||
fun createPartyNode(networkMapAddr: NodeInfo, legalName: String? = null, keyPair: KeyPair? = null) = createNode(networkMapAddr, -1, defaultFactory, legalName, keyPair)
|
fun createPartyNode(networkMapAddr: NodeInfo, legalName: String? = null, keyPair: KeyPair? = null) = createNode(networkMapAddr, -1, defaultFactory, true, legalName, keyPair)
|
||||||
|
|
||||||
fun addressToNode(address: SingleMessageRecipient): MockNode = nodes.single { it.net.myAddress == address }
|
fun addressToNode(address: SingleMessageRecipient): MockNode = nodes.single { it.net.myAddress == address }
|
||||||
|
|
||||||
|
fun startNodes() {
|
||||||
|
require(nodes.isNotEmpty())
|
||||||
|
nodes.forEach { if (!it.started) it.start() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopNodes() {
|
||||||
|
require(nodes.isNotEmpty())
|
||||||
|
nodes.forEach { if (it.started) it.stop() }
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package core.testing
|
package core.testing
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.Futures
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import core.node.CityDatabase
|
import core.node.CityDatabase
|
||||||
import core.node.NodeConfiguration
|
import core.node.NodeConfiguration
|
||||||
@ -58,7 +59,7 @@ abstract class Simulation(val runAsync: Boolean,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createAll(): List<SimulatedNode> = bankLocations.
|
fun createAll(): List<SimulatedNode> = bankLocations.
|
||||||
map { network.createNode(networkMap.info, nodeFactory = this) as SimulatedNode }
|
map { network.createNode(networkMap.info, start = false, nodeFactory = this) as SimulatedNode }
|
||||||
}
|
}
|
||||||
|
|
||||||
val bankFactory = BankFactory()
|
val bankFactory = BankFactory()
|
||||||
@ -128,26 +129,19 @@ abstract class Simulation(val runAsync: Boolean,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val network = MockNetwork(false)
|
val network = MockNetwork(false)
|
||||||
|
// This one must come first.
|
||||||
val regulators: List<SimulatedNode> = listOf(network.createNode(null, nodeFactory = RegulatorFactory) as SimulatedNode)
|
|
||||||
val networkMap: SimulatedNode
|
val networkMap: SimulatedNode
|
||||||
= network.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = NetworkMapService.Type) as SimulatedNode
|
= network.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = NetworkMapService.Type) as SimulatedNode
|
||||||
val notary: SimulatedNode
|
val notary: SimulatedNode
|
||||||
= network.createNode(null, nodeFactory = NotaryNodeFactory, advertisedServices = NotaryService.Type) as SimulatedNode
|
= network.createNode(networkMap.info, nodeFactory = NotaryNodeFactory, advertisedServices = NotaryService.Type) as SimulatedNode
|
||||||
|
val regulators: List<SimulatedNode> = listOf(network.createNode(networkMap.info, start = false, nodeFactory = RegulatorFactory) as SimulatedNode)
|
||||||
val ratesOracle: SimulatedNode
|
val ratesOracle: SimulatedNode
|
||||||
= network.createNode(null, nodeFactory = RatesOracleFactory, advertisedServices = NodeInterestRates.Type) as SimulatedNode
|
= network.createNode(networkMap.info, start = false, nodeFactory = RatesOracleFactory, advertisedServices = NodeInterestRates.Type) as SimulatedNode
|
||||||
|
|
||||||
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
|
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
|
||||||
val serviceProviders: List<SimulatedNode> = listOf(notary, ratesOracle, networkMap)
|
val serviceProviders: List<SimulatedNode> = listOf(notary, ratesOracle, networkMap)
|
||||||
val banks: List<SimulatedNode> = bankFactory.createAll()
|
val banks: List<SimulatedNode> = bankFactory.createAll()
|
||||||
|
|
||||||
init {
|
|
||||||
// Now wire up the network maps for each node.
|
|
||||||
for (node in regulators + serviceProviders + banks) {
|
|
||||||
node.services.networkMapCache.addNode(node.info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _allProtocolSteps = PublishSubject.create<Pair<SimulatedNode, ProgressTracker.Change>>()
|
private val _allProtocolSteps = PublishSubject.create<Pair<SimulatedNode, ProgressTracker.Change>>()
|
||||||
private val _doneSteps = PublishSubject.create<Collection<SimulatedNode>>()
|
private val _doneSteps = PublishSubject.create<Collection<SimulatedNode>>()
|
||||||
val allProtocolSteps: Observable<Pair<SimulatedNode, ProgressTracker.Change>> = _allProtocolSteps
|
val allProtocolSteps: Observable<Pair<SimulatedNode, ProgressTracker.Change>> = _allProtocolSteps
|
||||||
@ -214,11 +208,23 @@ abstract class Simulation(val runAsync: Boolean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun start() {
|
fun start() {
|
||||||
|
network.startNodes()
|
||||||
|
// Wait for all the nodes to have finished registering with the network map service.
|
||||||
|
Futures.allAsList(network.nodes.map { it.networkMapRegistrationFuture }).then {
|
||||||
|
startMainSimulation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sub-classes should override this to trigger whatever they want to simulate. This method will be invoked once the
|
||||||
|
* network bringup has been simulated.
|
||||||
|
*/
|
||||||
|
protected open fun startMainSimulation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
network.nodes.forEach { it.stop() }
|
network.stopNodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +16,7 @@ import java.time.Instant
|
|||||||
* then B and C trade with each other, then C and A etc).
|
* then B and C trade with each other, then C and A etc).
|
||||||
*/
|
*/
|
||||||
class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) : Simulation(runAsync, latencyInjector) {
|
class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) : Simulation(runAsync, latencyInjector) {
|
||||||
override fun start() {
|
override fun startMainSimulation() {
|
||||||
BriefLogFormatter.loggingOn("bank", "core.contract.TransactionGroup", "recordingmap")
|
BriefLogFormatter.loggingOn("bank", "core.contract.TransactionGroup", "recordingmap")
|
||||||
startTradingCircle { i, j -> tradeBetween(i, j) }
|
startTradingCircle { i, j -> tradeBetween(i, j) }
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ class AttachmentTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, null, null, NetworkMapService.Type, NotaryService.Type)
|
}, true, null, null, NetworkMapService.Type, NotaryService.Type)
|
||||||
val n1 = network.createNode(n0.info)
|
val n1 = network.createNode(n0.info)
|
||||||
|
|
||||||
// Insert an attachment into node zero's store directly.
|
// Insert an attachment into node zero's store directly.
|
||||||
|
@ -180,7 +180,7 @@ class TwoPartyTradeProtocolTests {
|
|||||||
advertisedServices: Set<ServiceType>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
|
advertisedServices: Set<ServiceType>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
|
||||||
return MockNetwork.MockNode(dir, config, network, networkMapAddr, advertisedServices, bobAddr.id, BOB_KEY)
|
return MockNetwork.MockNode(dir, config, network, networkMapAddr, advertisedServices, bobAddr.id, BOB_KEY)
|
||||||
}
|
}
|
||||||
}, BOB.name, BOB_KEY)
|
}, true, BOB.name, BOB_KEY)
|
||||||
|
|
||||||
// TODO: remove once validated transactions are persisted to disk
|
// TODO: remove once validated transactions are persisted to disk
|
||||||
bobNode.storage.validatedTransactions.putAll(recordedTransactions)
|
bobNode.storage.validatedTransactions.putAll(recordedTransactions)
|
||||||
@ -213,7 +213,7 @@ class TwoPartyTradeProtocolTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, name, keyPair)
|
}, true, name, keyPair)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user