Introducing versioning of flows using the FlowVersion annotation.

Core flows, which are baked into the platform, are also versioned using the platform version of the node. Several core flows, such as the data vending ones, which were provided via plugins are now instead baked into the node.
This commit is contained in:
Shams Asari
2017-04-27 12:29:41 +01:00
parent 3d401d1dcb
commit cfe5786d2d
33 changed files with 363 additions and 265 deletions

View File

@ -145,9 +145,9 @@ fun getFreeLocalPorts(hostName: String, numberToAlloc: Int): List<HostAndPort> {
*/
inline fun <reified P : FlowLogic<*>> AbstractNode.initiateSingleShotFlow(
clientFlowClass: KClass<out FlowLogic<*>>,
noinline flowFactory: (Party) -> P): ListenableFuture<P> {
noinline serviceFlowFactory: (Party) -> P): ListenableFuture<P> {
val future = smm.changes.filter { it is StateMachineManager.Change.Add && it.logic is P }.map { it.logic as P }.toFuture()
services.registerServiceFlow(clientFlowClass.java, flowFactory)
services.registerServiceFlow(clientFlowClass.java, serviceFlowFactory)
return future
}

View File

@ -272,12 +272,20 @@ class InMemoryMessagingNetwork(
}
@CordaSerializable
private data class InMemoryMessage(override val topicSession: TopicSession, override val data: ByteArray, override val uniqueMessageId: UUID, override val debugTimestamp: Instant = Instant.now()) : Message {
private data class InMemoryMessage(override val topicSession: TopicSession,
override val data: ByteArray,
override val uniqueMessageId: UUID,
override val debugTimestamp: Instant = Instant.now()) : Message {
override fun toString() = "$topicSession#${String(data)}"
}
@CordaSerializable
private data class InMemoryReceivedMessage(override val topicSession: TopicSession, override val data: ByteArray, override val uniqueMessageId: UUID, override val debugTimestamp: Instant, override val peer: X500Name) : ReceivedMessage
private data class InMemoryReceivedMessage(override val topicSession: TopicSession,
override val data: ByteArray,
override val platformVersion: Int,
override val uniqueMessageId: UUID,
override val debugTimestamp: Instant,
override val peer: X500Name) : ReceivedMessage
/**
* An [InMemoryMessaging] provides a [MessagingService] that isn't backed by any kind of network or disk storage
@ -453,6 +461,9 @@ class InMemoryMessagingNetwork(
private fun MessageTransfer.toReceivedMessage(): ReceivedMessage = InMemoryReceivedMessage(
message.topicSession,
message.data.copyOf(), // Kryo messes with the buffer so give each client a unique copy
message.uniqueMessageId, message.debugTimestamp, X509Utilities.getDevX509Name(sender.description))
1,
message.uniqueMessageId,
message.debugTimestamp,
X509Utilities.getDevX509Name(sender.description))
}
}

View File

@ -1,5 +1,6 @@
package net.corda.testing.node
import com.google.common.annotations.VisibleForTesting
import com.google.common.jimfs.Configuration.unix
import com.google.common.jimfs.Jimfs
import com.google.common.util.concurrent.Futures
@ -7,6 +8,7 @@ import com.google.common.util.concurrent.ListenableFuture
import net.corda.core.*
import net.corda.core.crypto.Party
import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.flows.FlowLogic
import net.corda.core.messaging.RPCOps
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.CordaPluginRegistry
@ -16,11 +18,13 @@ import net.corda.core.node.services.*
import net.corda.core.utilities.DUMMY_NOTARY_KEY
import net.corda.core.utilities.loggerFor
import net.corda.node.internal.AbstractNode
import net.corda.node.internal.ServiceFlowInfo
import net.corda.node.services.api.MessagingServiceInternal
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.keys.E2ETestKeyManagementService
import net.corda.node.services.network.InMemoryNetworkMapService
import net.corda.node.services.network.NetworkMapService
import net.corda.node.services.statemachine.flowVersion
import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.services.transactions.InMemoryUniquenessProvider
import net.corda.node.services.transactions.SimpleNotaryService
@ -38,6 +42,7 @@ import java.security.KeyPair
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import kotlin.reflect.KClass
/**
* A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing.
@ -224,6 +229,13 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
// It is used from the network visualiser tool.
@Suppress("unused") val place: PhysicalLocation get() = findMyLocation()!!
@VisibleForTesting
fun registerServiceFlow(clientFlowClass: KClass<out FlowLogic<*>>,
flowVersion: Int = clientFlowClass.java.flowVersion,
serviceFlowFactory: (Party) -> FlowLogic<*>) {
serviceFlowFactories[clientFlowClass.java] = ServiceFlowInfo.CorDapp(flowVersion, serviceFlowFactory)
}
fun pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? {
return (net as InMemoryMessagingNetwork.InMemoryMessaging).pumpReceive(block)
}

View File

@ -60,21 +60,24 @@ abstract class NodeBasedTest {
* will automatically be started with the default parameters.
*/
fun startNetworkMapNode(legalName: String = DUMMY_MAP.name,
platformVersion: Int = 1,
advertisedServices: Set<ServiceInfo> = emptySet(),
rpcUsers: List<User> = emptyList(),
configOverrides: Map<String, Any> = emptyMap()): Node {
check(_networkMapNode == null)
return startNodeInternal(legalName, advertisedServices, rpcUsers, configOverrides).apply {
return startNodeInternal(legalName, platformVersion, advertisedServices, rpcUsers, configOverrides).apply {
_networkMapNode = this
}
}
fun startNode(legalName: String,
platformVersion: Int = 1,
advertisedServices: Set<ServiceInfo> = emptySet(),
rpcUsers: List<User> = emptyList(),
configOverrides: Map<String, Any> = emptyMap()): ListenableFuture<Node> {
val node = startNodeInternal(
legalName,
platformVersion,
advertisedServices,
rpcUsers,
mapOf(
@ -118,6 +121,7 @@ abstract class NodeBasedTest {
}
private fun startNodeInternal(legalName: String,
platformVersion: Int,
advertisedServices: Set<ServiceInfo>,
rpcUsers: List<User>,
configOverrides: Map<String, Any>): Node {
@ -141,7 +145,7 @@ abstract class NodeBasedTest {
) + configOverrides
)
val node = config.parseAs<FullNodeConfiguration>().createNode(MOCK_VERSION_INFO)
val node = config.parseAs<FullNodeConfiguration>().createNode(MOCK_VERSION_INFO.copy(platformVersion = platformVersion))
node.start()
nodes += node
thread(name = legalName) {