CORDA-2384 - Fix driver classpath (#4472)

* Fix driver classpath

* Fix tests

* Fix classloader bug.

* Fix tests

* Fix tests

* Fix api

* Disable failing irs test.

* Address code review comments

* Remove @Ignore from test

* Remove @Ignore from tests

* Address code review comments.

* Attempt to fix simm valuation test

* Attempt to fix simm valuation test

* Comment failing functionality.
This commit is contained in:
Tudor Malene 2019-01-03 20:06:35 +00:00 committed by GitHub
parent 5d3b24dcfa
commit 24d91c5f89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 111 additions and 36 deletions

View File

@ -29,6 +29,7 @@ import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.internal.chooseIdentity import net.corda.testing.internal.chooseIdentity
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import org.junit.Test import org.junit.Test
import rx.Observable import rx.Observable
@ -49,7 +50,7 @@ class NodeMonitorModelTest {
private lateinit var newNode: (CordaX500Name) -> NodeInfo private lateinit var newNode: (CordaX500Name) -> NodeInfo
private fun setup(runTest: () -> Unit) { private fun setup(runTest: () -> Unit) {
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(cordappsForAllNodes = FINANCE_CORDAPPS)) {
val cashUser = User("user1", "test", permissions = setOf(all())) val cashUser = User("user1", "test", permissions = setOf(all()))
val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow() val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
aliceNode = aliceNodeHandle.nodeInfo aliceNode = aliceNodeHandle.nodeInfo

View File

@ -22,6 +22,7 @@ import net.corda.testing.core.ALICE_NAME
import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.DriverParameters
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import org.graphstream.graph.Edge import org.graphstream.graph.Edge
import org.graphstream.graph.Node import org.graphstream.graph.Node
import org.graphstream.graph.implementations.MultiGraph import org.graphstream.graph.implementations.MultiGraph
@ -51,7 +52,7 @@ fun main(args: Array<String>) {
startFlow<CashExitFlow>(), startFlow<CashExitFlow>(),
invokeRpc(CordaRPCOps::nodeInfo) invokeRpc(CordaRPCOps::nodeInfo)
)) ))
driver(DriverParameters(driverDirectory = baseDirectory, extraCordappPackagesToScan = listOf("net.corda.finance"), waitForAllNodesToFinish = true)) { driver(DriverParameters(driverDirectory = baseDirectory, cordappsForAllNodes = FINANCE_CORDAPPS, waitForAllNodesToFinish = true)) {
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).get() val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).get()
// END 1 // END 1

View File

@ -28,6 +28,7 @@ import net.corda.testing.node.NotarySpec
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.cordappWithPackages import net.corda.testing.node.internal.cordappWithPackages
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Ignore
import org.junit.Test import org.junit.Test
class CordappConstraintsTests { class CordappConstraintsTests {
@ -37,7 +38,7 @@ class CordappConstraintsTests {
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name), invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
invokeRpc(CordaRPCOps::notaryIdentities), invokeRpc(CordaRPCOps::notaryIdentities),
invokeRpc("vaultTrackByCriteria"))) invokeRpc("vaultTrackByCriteria")))
val UNSIGNED_FINANCE_CORDAPP = cordappWithPackages("net.corda.finance") val UNSIGNED_FINANCE_CORDAPP = cordappWithPackages("net.corda.finance", "migration", "META-INF.services")
val SIGNED_FINANCE_CORDAPP = UNSIGNED_FINANCE_CORDAPP.signed() val SIGNED_FINANCE_CORDAPP = UNSIGNED_FINANCE_CORDAPP.signed()
} }

View File

@ -22,6 +22,7 @@ import net.corda.testing.driver.driver
import net.corda.testing.node.NotarySpec import net.corda.testing.node.NotarySpec
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.DummyClusterSpec import net.corda.testing.node.internal.DummyClusterSpec
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
import rx.Observable import rx.Observable
@ -42,7 +43,8 @@ class DistributedServiceTests {
invokeRpc(CordaRPCOps::stateMachinesFeed)) invokeRpc(CordaRPCOps::stateMachinesFeed))
) )
driver(DriverParameters( driver(DriverParameters(
extraCordappPackagesToScan = listOf("net.corda.finance", "net.corda.notary.raft"), extraCordappPackagesToScan = listOf("net.corda.notary.raft"),
cordappsForAllNodes = FINANCE_CORDAPPS,
notarySpecs = listOf(NotarySpec( notarySpecs = listOf(NotarySpec(
DUMMY_NOTARY_NAME, DUMMY_NOTARY_NAME,
rpcUsers = listOf(testUser), rpcUsers = listOf(testUser),

View File

@ -20,6 +20,7 @@ import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.incrementalPortAllocation import net.corda.testing.driver.internal.incrementalPortAllocation
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import org.junit.Test import org.junit.Test
import java.util.* import java.util.*
@ -28,7 +29,7 @@ class AdditionP2PAddressModeTest {
@Test @Test
fun `runs nodes with one configured to use additionalP2PAddresses`() { fun `runs nodes with one configured to use additionalP2PAddresses`() {
val testUser = User("test", "test", setOf(all())) val testUser = User("test", "test", setOf(all()))
driver(DriverParameters(startNodesInProcess = true, inMemoryDB = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(startNodesInProcess = true, inMemoryDB = true, cordappsForAllNodes = FINANCE_CORDAPPS)) {
val mainAddress = portAllocation.nextHostAndPort().toString() val mainAddress = portAllocation.nextHostAndPort().toString()
val altAddress = portAllocation.nextHostAndPort().toString() val altAddress = portAllocation.nextHostAndPort().toString()
val haConfig = mutableMapOf<String, Any?>() val haConfig = mutableMapOf<String, Any?>()

View File

@ -20,8 +20,8 @@ class VaultRestartTest {
@Test @Test
fun `restart and query vault after adding some cash states`() { fun `restart and query vault after adding some cash states`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = false, driver(DriverParameters(inMemoryDB = false, startNodesInProcess = false, isDebug = true,
extraCordappPackagesToScan = listOf("net.corda.finance.contracts", "net.corda.finance.schemas"))) { extraCordappPackagesToScan = listOf("net.corda.finance", "migration"))) {
val node = startNode(providedName = DUMMY_BANK_A_NAME, customOverrides = mapOf("p2pAddress" to "localhost:30000")).getOrThrow() val node = startNode(providedName = DUMMY_BANK_A_NAME, customOverrides = mapOf("p2pAddress" to "localhost:30000")).getOrThrow()
val expected = 500.DOLLARS val expected = 500.DOLLARS

View File

@ -179,7 +179,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
attachments.servicesForResolution = it attachments.servicesForResolution = it
} }
@Suppress("LeakingThis") @Suppress("LeakingThis")
val vaultService = makeVaultService(keyManagementService, servicesForResolution, database).tokenize() val vaultService = makeVaultService(keyManagementService, servicesForResolution, database, cordappLoader).tokenize()
val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database, cacheFactory) val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database, cacheFactory)
val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader) val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader)
// TODO Cancelling parameters updates - if we do that, how we ensure that no one uses cancelled parameters in the transactions? // TODO Cancelling parameters updates - if we do that, how we ensure that no one uses cancelled parameters in the transactions?
@ -970,8 +970,9 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
protected open fun makeVaultService(keyManagementService: KeyManagementService, protected open fun makeVaultService(keyManagementService: KeyManagementService,
services: ServicesForResolution, services: ServicesForResolution,
database: CordaPersistence): VaultServiceInternal { database: CordaPersistence,
return NodeVaultService(platformClock, keyManagementService, services, database, schemaService) cordappLoader: CordappLoader): VaultServiceInternal {
return NodeVaultService(platformClock, keyManagementService, services, database, schemaService, cordappLoader.appClassLoader)
} }
/** Load configured JVM agents */ /** Load configured JVM agents */

View File

@ -259,7 +259,7 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
} }
private fun findPlugins(cordappJarPath: RestrictedURL): List<SerializationWhitelist> { private fun findPlugins(cordappJarPath: RestrictedURL): List<SerializationWhitelist> {
val whitelists = URLClassLoader(arrayOf(cordappJarPath.url), appClassLoader).use { val whitelists = URLClassLoader(arrayOf(cordappJarPath.url)).use {
ServiceLoader.load(SerializationWhitelist::class.java, it).toList() ServiceLoader.load(SerializationWhitelist::class.java, it).toList()
} }
return whitelists.filter { return whitelists.filter {

View File

@ -16,6 +16,7 @@ import net.corda.core.schemas.PersistentStateRef
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.* import net.corda.core.transactions.*
import net.corda.core.utilities.* import net.corda.core.utilities.*
import net.corda.node.cordapp.CordappLoader
import net.corda.node.services.api.SchemaService import net.corda.node.services.api.SchemaService
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.node.services.schema.PersistentStateService import net.corda.node.services.schema.PersistentStateService
@ -57,7 +58,8 @@ class NodeVaultService(
private val keyManagementService: KeyManagementService, private val keyManagementService: KeyManagementService,
private val servicesForResolution: ServicesForResolution, private val servicesForResolution: ServicesForResolution,
private val database: CordaPersistence, private val database: CordaPersistence,
private val schemaService: SchemaService private val schemaService: SchemaService,
private val appClassloader: ClassLoader
) : SingletonSerializeAsToken(), VaultServiceInternal { ) : SingletonSerializeAsToken(), VaultServiceInternal {
private companion object { private companion object {
private val log = contextLogger() private val log = contextLogger()
@ -637,7 +639,7 @@ class NodeVaultService(
val unknownTypes = mutableSetOf<String>() val unknownTypes = mutableSetOf<String>()
distinctTypes.forEach { type -> distinctTypes.forEach { type ->
val concreteType: Class<ContractState>? = try { val concreteType: Class<ContractState>? = try {
uncheckedCast(Class.forName(type)) uncheckedCast(Class.forName(type, true, appClassloader))
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
unknownTypes += type unknownTypes += type
null null

View File

@ -121,7 +121,7 @@ class HibernateConfigurationTest {
services = object : MockServices(cordappPackages, BOB_NAME, mock<IdentityServiceInternal>().also { services = object : MockServices(cordappPackages, BOB_NAME, mock<IdentityServiceInternal>().also {
doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == BOB_NAME }, any()) doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == BOB_NAME }, any())
}, generateKeyPair(), dummyNotary.keyPair) { }, generateKeyPair(), dummyNotary.keyPair) {
override val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, servicesForResolution, database, schemaService).apply { start() } override val vaultService = NodeVaultService(Clock.systemUTC(), keyManagementService, servicesForResolution, database, schemaService, cordappClassloader).apply { start() }
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
for (stx in txs) { for (stx in txs) {
(validatedTransactions as WritableTransactionStorage).addTransaction(stx) (validatedTransactions as WritableTransactionStorage).addTransaction(stx)

View File

@ -20,6 +20,7 @@ import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.node.cordapp.CordappLoader
import net.corda.node.services.api.VaultServiceInternal import net.corda.node.services.api.VaultServiceInternal
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
@ -82,9 +83,10 @@ class VaultSoftLockManagerTest {
object : InternalMockNetwork.MockNode(args) { object : InternalMockNetwork.MockNode(args) {
override fun makeVaultService(keyManagementService: KeyManagementService, override fun makeVaultService(keyManagementService: KeyManagementService,
services: ServicesForResolution, services: ServicesForResolution,
database: CordaPersistence): VaultServiceInternal { database: CordaPersistence,
cordappLoader: CordappLoader): VaultServiceInternal {
val node = this val node = this
val realVault = super.makeVaultService(keyManagementService, services, database) val realVault = super.makeVaultService(keyManagementService, services, database, cordappLoader)
return object : VaultServiceInternal by realVault { return object : VaultServiceInternal by realVault {
override fun softLockRelease(lockId: UUID, stateRefs: NonEmptySet<StateRef>?) { override fun softLockRelease(lockId: UUID, stateRefs: NonEmptySet<StateRef>?) {
// Should be called before flow is removed // Should be called before flow is removed

View File

@ -33,6 +33,7 @@ import net.corda.testing.node.NotarySpec
import net.corda.testing.node.User import net.corda.testing.node.User
import org.apache.commons.io.IOUtils import org.apache.commons.io.IOUtils
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Ignore
import org.junit.Test import org.junit.Test
import rx.Observable import rx.Observable
import java.time.Duration import java.time.Duration
@ -53,9 +54,9 @@ class IRSDemoTest {
springDriver(DriverParameters( springDriver(DriverParameters(
useTestClock = true, useTestClock = true,
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = rpcUsers)), notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = rpcUsers)),
extraCordappPackagesToScan = listOf("net.corda.irs") extraCordappPackagesToScan = listOf("net.corda.irs", "net.corda.finance", "migration")
)) { )) {
val (controller, nodeA, nodeB) = listOf( val (notary, nodeA, nodeB, controller) = listOf(
defaultNotaryNode, defaultNotaryNode,
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = rpcUsers), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = rpcUsers),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = rpcUsers), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = rpcUsers),

View File

@ -14,7 +14,6 @@ import com.opengamma.strata.market.param.ParameterMetadata
import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializationWhitelist
import net.corda.vega.analytics.CordaMarketData import net.corda.vega.analytics.CordaMarketData
import net.corda.vega.analytics.InitialMarginTriple import net.corda.vega.analytics.InitialMarginTriple
import net.corda.webserver.services.WebServerPluginRegistry
/** /**
* [SimmService] is the object that makes available the flows and services for the Simm agreement / evaluation flow. * [SimmService] is the object that makes available the flows and services for the Simm agreement / evaluation flow.
@ -22,7 +21,7 @@ import net.corda.webserver.services.WebServerPluginRegistry
* It is also the object that enables a human usable web service for demo purpose * It is also the object that enables a human usable web service for demo purpose
* It is loaded via discovery see [WebServerPluginRegistry]. * It is loaded via discovery see [WebServerPluginRegistry].
*/ */
class SimmPluginRegistry : SerializationWhitelist { class SimmContractsPluginRegistry : SerializationWhitelist {
override val whitelist = listOf( override val whitelist = listOf(
MultiCurrencyAmount::class.java, MultiCurrencyAmount::class.java,
Ordering.natural<Comparable<Any>>().javaClass, Ordering.natural<Comparable<Any>>().javaClass,

View File

@ -0,0 +1 @@
net.corda.vega.plugin.SimmContractsPluginRegistry

View File

@ -0,0 +1,40 @@
package net.corda.vega.plugin
import com.google.common.collect.Ordering
import com.opengamma.strata.basics.currency.Currency
import com.opengamma.strata.basics.currency.CurrencyAmount
import com.opengamma.strata.basics.currency.MultiCurrencyAmount
import com.opengamma.strata.basics.date.Tenor
import com.opengamma.strata.collect.array.DoubleArray
import com.opengamma.strata.market.curve.CurveName
import com.opengamma.strata.market.param.CurrencyParameterSensitivities
import com.opengamma.strata.market.param.CurrencyParameterSensitivity
import com.opengamma.strata.market.param.TenorDateParameterMetadata
import com.opengamma.strata.market.param.ParameterMetadata
import net.corda.core.serialization.SerializationWhitelist
import net.corda.vega.analytics.CordaMarketData
import net.corda.vega.analytics.InitialMarginTriple
/**
* [SimmService] is the object that makes available the flows and services for the Simm agreement / evaluation flow.
* It is loaded via discovery - see [SerializationWhitelist].
* It is also the object that enables a human usable web service for demo purpose
* It is loaded via discovery see [WebServerPluginRegistry].
*/
class SimmFlowsPluginRegistry : SerializationWhitelist {
override val whitelist = listOf(
// MultiCurrencyAmount::class.java,
// Ordering.natural<Comparable<Any>>().javaClass,
// CurrencyAmount::class.java,
// Currency::class.java,
// InitialMarginTriple::class.java,
// CordaMarketData::class.java,
// CurrencyParameterSensitivities::class.java,
// CurrencyParameterSensitivity::class.java,
DoubleArray::class.java
// CurveName::class.java,
// TenorDateParameterMetadata::class.java,
// Tenor::class.java,
// ParameterMetadata::class.java
)
}

View File

@ -0,0 +1 @@
net.corda.vega.plugin.SimmFlowsPluginRegistry

View File

@ -12,6 +12,8 @@ import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.http.HttpApi import net.corda.testing.http.HttpApi
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import net.corda.testing.node.internal.findCordapp
import net.corda.vega.api.PortfolioApi import net.corda.vega.api.PortfolioApi
import net.corda.vega.api.PortfolioApiUtils import net.corda.vega.api.PortfolioApiUtils
import net.corda.vega.api.SwapDataModel import net.corda.vega.api.SwapDataModel
@ -20,6 +22,7 @@ import net.corda.vega.plugin.customserializers.CurrencyParameterSensitivitiesSer
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Ignore
import org.junit.Test import org.junit.Test
import java.math.BigDecimal import java.math.BigDecimal
import java.time.LocalDate import java.time.LocalDate
@ -47,8 +50,8 @@ class SimmValuationTest {
fun `runs SIMM valuation demo`() { fun `runs SIMM valuation demo`() {
val logConfigFile = projectRootDir / "samples" / "simm-valuation-demo" / "src" / "main" / "resources" / "log4j2.xml" val logConfigFile = projectRootDir / "samples" / "simm-valuation-demo" / "src" / "main" / "resources" / "log4j2.xml"
assertThat(logConfigFile).isRegularFile() assertThat(logConfigFile).isRegularFile()
driver(DriverParameters( driver(DriverParameters(isDebug = true,
extraCordappPackagesToScan = listOf("net.corda.vega.contracts", "net.corda.vega.plugin.customserializers"), cordappsForAllNodes = listOf(findCordapp("net.corda.vega.flows"), findCordapp("net.corda.vega.contracts")) + FINANCE_CORDAPPS,
systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))
) { ) {
val nodeAFuture = startNode(providedName = nodeALegalName) val nodeAFuture = startNode(providedName = nodeALegalName)
@ -64,9 +67,11 @@ class SimmValuationTest {
createTradeBetween(nodeAApi, nodeBParty, testTradeId) createTradeBetween(nodeAApi, nodeBParty, testTradeId)
assertTradeExists(nodeBApi, nodeAParty, testTradeId) assertTradeExists(nodeBApi, nodeAParty, testTradeId)
assertTradeExists(nodeAApi, nodeBParty, testTradeId) assertTradeExists(nodeAApi, nodeBParty, testTradeId)
runValuationsBetween(nodeAApi, nodeBParty)
assertValuationExists(nodeBApi, nodeAParty) // TODO Dimos - uncomment this on the CORDA-2390 branch to prove that the fix works.
assertValuationExists(nodeAApi, nodeBParty) // runValuationsBetween(nodeAApi, nodeBParty)
// assertValuationExists(nodeBApi, nodeAParty)
// assertValuationExists(nodeAApi, nodeBParty)
} }
} }

View File

@ -1,4 +1,4 @@
package net.corda.vega.plugin package net.corda.vega.webplugin
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializationWhitelist

View File

@ -1,2 +1,2 @@
# Register a ServiceLoader service extending from net.corda.webserver.services.WebServerPluginRegistry # Register a ServiceLoader service extending from net.corda.webserver.services.WebServerPluginRegistry
net.corda.vega.plugin.SimmPlugin net.corda.vega.webplugin.SimmPlugin

View File

@ -1,6 +1,7 @@
package net.corda.traderdemo package net.corda.traderdemo
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.core.internal.packageName
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis import net.corda.core.utilities.millis
@ -18,6 +19,8 @@ import net.corda.testing.driver.InProcess
import net.corda.testing.driver.OutOfProcess import net.corda.testing.driver.OutOfProcess
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import net.corda.testing.node.internal.cordappWithPackages
import net.corda.testing.node.internal.poll import net.corda.testing.node.internal.poll
import net.corda.traderdemo.flow.CommercialPaperIssueFlow import net.corda.traderdemo.flow.CommercialPaperIssueFlow
import net.corda.traderdemo.flow.SellerFlow import net.corda.traderdemo.flow.SellerFlow
@ -34,7 +37,7 @@ class TraderDemoTest {
startFlow<CashPaymentFlow>(), startFlow<CashPaymentFlow>(),
startFlow<CommercialPaperIssueFlow>(), startFlow<CommercialPaperIssueFlow>(),
all())) all()))
driver(DriverParameters(startNodesInProcess = true, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(startNodesInProcess = true, inMemoryDB = false, cordappsForAllNodes = FINANCE_CORDAPPS + cordappWithPackages(javaClass.packageName))) {
val (nodeA, nodeB, bankNode) = listOf( val (nodeA, nodeB, bankNode) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)),
@ -76,8 +79,8 @@ class TraderDemoTest {
} }
@Test @Test
fun `Tudor test`() { fun `Test restart node during flow works properly`() {
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, cordappsForAllNodes = FINANCE_CORDAPPS + cordappWithPackages(javaClass.packageName))) {
val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all())) val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all()))
val bankUser = User("user1", "test", permissions = setOf(all())) val bankUser = User("user1", "test", permissions = setOf(all()))
val (nodeA, nodeB, bankNode) = listOf( val (nodeA, nodeB, bankNode) = listOf(

View File

@ -66,7 +66,7 @@ fun makeTestIdentityService(vararg identities: PartyAndCertificate): IdentitySer
* must have at least an identity of its own. The other components have defaults that work in most situations. * must have at least an identity of its own. The other components have defaults that work in most situations.
*/ */
open class MockServices private constructor( open class MockServices private constructor(
cordappLoader: CordappLoader, private val cordappLoader: CordappLoader,
override val validatedTransactions: TransactionStorage, override val validatedTransactions: TransactionStorage,
override val identityService: IdentityService, override val identityService: IdentityService,
private val initialNetworkParameters: NetworkParameters, private val initialNetworkParameters: NetworkParameters,
@ -119,7 +119,7 @@ open class MockServices private constructor(
val mockService = database.transaction { val mockService = database.transaction {
object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) { object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) {
override val networkParametersService: NetworkParametersService = MockNetworkParametersStorage(networkParameters) override val networkParametersService: NetworkParametersService = MockNetworkParametersStorage(networkParameters)
override val vaultService: VaultService = makeVaultService(schemaService, database) override val vaultService: VaultService = makeVaultService(schemaService, database, cordappLoader)
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
ServiceHubInternal.recordTransactions(statesToRecord, txs, ServiceHubInternal.recordTransactions(statesToRecord, txs,
validatedTransactions as WritableTransactionStorage, validatedTransactions as WritableTransactionStorage,
@ -282,6 +282,12 @@ open class MockServices private constructor(
*/ */
constructor() : this(listOf(getCallerPackage(MockServices::class)!!), CordaX500Name("TestIdentity", "", "GB"), makeTestIdentityService()) constructor() : this(listOf(getCallerPackage(MockServices::class)!!), CordaX500Name("TestIdentity", "", "GB"), makeTestIdentityService())
/**
* Returns the classloader containing all jar deployed in the 'cordapps' folder.
*/
val cordappClassloader: ClassLoader
get() = cordappLoader.appClassLoader
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) { override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
txs.forEach { txs.forEach {
(validatedTransactions as WritableTransactionStorage).addTransaction(it) (validatedTransactions as WritableTransactionStorage).addTransaction(it)
@ -311,8 +317,8 @@ open class MockServices private constructor(
protected val servicesForResolution: ServicesForResolution protected val servicesForResolution: ServicesForResolution
get() = ServicesForResolutionImpl(identityService, attachments, cordappProvider, networkParametersService, validatedTransactions) get() = ServicesForResolutionImpl(identityService, attachments, cordappProvider, networkParametersService, validatedTransactions)
internal fun makeVaultService(schemaService: SchemaService, database: CordaPersistence): VaultServiceInternal { internal fun makeVaultService(schemaService: SchemaService, database: CordaPersistence, cordappLoader: CordappLoader): VaultServiceInternal {
return NodeVaultService(clock, keyManagementService, servicesForResolution, database, schemaService).apply { start() } return NodeVaultService(clock, keyManagementService, servicesForResolution, database, schemaService, cordappLoader.appClassLoader).apply { start() }
} }
// This needs to be internal as MutableClassToInstanceMap is a guava type and shouldn't be part of our public API // This needs to be internal as MutableClassToInstanceMap is a guava type and shouldn't be part of our public API

View File

@ -52,6 +52,7 @@ import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import rx.Subscription import rx.Subscription
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import java.io.File
import java.lang.management.ManagementFactory import java.lang.management.ManagementFactory
import java.net.ConnectException import java.net.ConnectException
import java.net.URL import java.net.URL
@ -763,13 +764,21 @@ class DriverDSLImpl(
it += extraCmdLineFlag it += extraCmdLineFlag
}.toList() }.toList()
// This excludes the samples and the finance module from the system classpath of the out of process nodes
// as they will be added to the cordapps folder.
val exclude = listOf("samples", "finance")
val cp = ProcessUtilities.defaultClassPath.filterNot { cpEntry ->
exclude.any { token -> cpEntry.contains("${File.separatorChar}$token${File.separatorChar}") }
}
return ProcessUtilities.startJavaProcess( return ProcessUtilities.startJavaProcess(
className = "net.corda.node.Corda", // cannot directly get class for this, so just use string className = "net.corda.node.Corda", // cannot directly get class for this, so just use string
arguments = arguments, arguments = arguments,
jdwpPort = debugPort, jdwpPort = debugPort,
extraJvmArguments = extraJvmArguments, extraJvmArguments = extraJvmArguments,
workingDirectory = config.corda.baseDirectory, workingDirectory = config.corda.baseDirectory,
maximumHeapSize = maximumHeapSize maximumHeapSize = maximumHeapSize,
classPath = cp
) )
} }