mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
Refactoring related to BFT notary demo (#680)
* Fix: Add missing @StartableByRPC to fix the Raft notary demo * Make loadConfig take a Config object, for cordformation Node * Unduplicate User.toMap * Unduplicate WHITESPACE regex, choose possessive form * Use slash to make a Path * Remove Companion where redundant * Remove unused code
This commit is contained in:
parent
42d0a3c638
commit
d3bb040355
@ -46,9 +46,3 @@ class NodeConfig(
|
||||
return if (obj == null) config else body(config, obj).atPath(path)
|
||||
}
|
||||
}
|
||||
|
||||
private fun User.toMap(): Map<String, Any> = mapOf(
|
||||
"username" to username,
|
||||
"password" to password,
|
||||
"permissions" to permissions
|
||||
)
|
||||
|
@ -136,7 +136,8 @@ fun <A> ListenableFuture<out A>.toObservable(): Observable<A> {
|
||||
}
|
||||
|
||||
/** Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform separator problems. */
|
||||
operator fun Path.div(other: String): Path = resolve(other)
|
||||
operator fun Path.div(other: String) = resolve(other)
|
||||
operator fun String.div(other: String) = Paths.get(this) / other
|
||||
|
||||
fun Path.createDirectory(vararg attrs: FileAttribute<*>): Path = Files.createDirectory(this, *attrs)
|
||||
fun Path.createDirectories(vararg attrs: FileAttribute<*>): Path = Files.createDirectories(this, *attrs)
|
||||
|
@ -24,12 +24,14 @@ fun validateLegalName(normalizedLegalName: String) {
|
||||
rules.forEach { it.validate(normalizedLegalName) }
|
||||
}
|
||||
|
||||
val WHITESPACE = "\\s++".toRegex()
|
||||
|
||||
/**
|
||||
* The normalize function will trim the input string, replace any multiple spaces with a single space,
|
||||
* and normalize the string according to NFKC normalization form.
|
||||
*/
|
||||
fun normaliseLegalName(legalName: String): String {
|
||||
val trimmedLegalName = legalName.trim().replace(Regex("\\s+"), " ")
|
||||
val trimmedLegalName = legalName.trim().replace(WHITESPACE, " ")
|
||||
return Normalizer.normalize(trimmedLegalName, Normalizer.Form.NFKC)
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class PartialMerkleTreeTest {
|
||||
|
||||
@Test
|
||||
fun `building Merkle tree - no hashes`() {
|
||||
assertFailsWith<MerkleTreeException> { MerkleTree.Companion.getMerkleTree(emptyList()) }
|
||||
assertFailsWith<MerkleTreeException> { MerkleTree.getMerkleTree(emptyList()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -71,7 +71,7 @@ class SecureHashGenerator : Generator<SecureHash>(SecureHash::class.java) {
|
||||
|
||||
class StateRefGenerator : Generator<StateRef>(StateRef::class.java) {
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): StateRef {
|
||||
return StateRef(SecureHash.Companion.sha256(random.nextBytes(16)), random.nextInt(0, 10))
|
||||
return StateRef(SecureHash.sha256(random.nextBytes(16)), random.nextInt(0, 10))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ class ObligationTests {
|
||||
val defaultRef = OpaqueBytes(ByteArray(1, { 1 }))
|
||||
val defaultIssuer = MEGA_CORP.ref(defaultRef)
|
||||
val oneMillionDollars = 1000000.DOLLARS `issued by` defaultIssuer
|
||||
val trustedCashContract = nonEmptySetOf(SecureHash.Companion.randomSHA256() as SecureHash)
|
||||
val trustedCashContract = nonEmptySetOf(SecureHash.randomSHA256() as SecureHash)
|
||||
val megaIssuedDollars = nonEmptySetOf(Issued(defaultIssuer, USD))
|
||||
val megaIssuedPounds = nonEmptySetOf(Issued(defaultIssuer, GBP))
|
||||
val fivePm = TEST_TX_TIME.truncatedTo(ChronoUnit.DAYS).plus(17, ChronoUnit.HOURS)
|
||||
@ -759,7 +759,7 @@ class ObligationTests {
|
||||
|
||||
// States must not be nettable if the cash contract differs
|
||||
assertNotEquals(fiveKDollarsFromMegaToMega.bilateralNetState,
|
||||
fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableContracts = nonEmptySetOf(SecureHash.Companion.randomSHA256()))).bilateralNetState)
|
||||
fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableContracts = nonEmptySetOf(SecureHash.randomSHA256()))).bilateralNetState)
|
||||
|
||||
// States must not be nettable if the trusted issuers differ
|
||||
val miniCorpIssuer = nonEmptySetOf(Issued(MINI_CORP.ref(1), USD))
|
||||
|
@ -40,7 +40,7 @@ class IssuerFlowTest {
|
||||
bankClientNode = net.createPartyNode(notaryNode.info.address, MEGA_CORP.name)
|
||||
|
||||
// using default IssueTo Party Reference
|
||||
val issueToPartyAndRef = bankClientNode.info.legalIdentity.ref(OpaqueBytes.Companion.of(123))
|
||||
val issueToPartyAndRef = bankClientNode.info.legalIdentity.ref(OpaqueBytes.of(123))
|
||||
val (issuer, issuerResult) = runIssuerAndIssueRequester(bankOfCordaNode, bankClientNode, 1000000.DOLLARS, issueToPartyAndRef)
|
||||
assertEquals(issuerResult.get(), issuer.get().resultFuture.get())
|
||||
|
||||
@ -62,7 +62,7 @@ class IssuerFlowTest {
|
||||
bankOfCordaNode = net.createPartyNode(notaryNode.info.address, BOC.name)
|
||||
|
||||
// using default IssueTo Party Reference
|
||||
val issueToPartyAndRef = bankOfCordaNode.info.legalIdentity.ref(OpaqueBytes.Companion.of(123))
|
||||
val issueToPartyAndRef = bankOfCordaNode.info.legalIdentity.ref(OpaqueBytes.of(123))
|
||||
val (issuer, issuerResult) = runIssuerAndIssueRequester(bankOfCordaNode, bankOfCordaNode, 1000000.DOLLARS, issueToPartyAndRef)
|
||||
assertEquals(issuerResult.get(), issuer.get().resultFuture.get())
|
||||
|
||||
@ -80,7 +80,7 @@ class IssuerFlowTest {
|
||||
bankClientNode = net.createPartyNode(notaryNode.info.address, MEGA_CORP.name)
|
||||
|
||||
// using default IssueTo Party Reference
|
||||
val issueToPartyAndRef = bankClientNode.info.legalIdentity.ref(OpaqueBytes.Companion.of(123))
|
||||
val issueToPartyAndRef = bankClientNode.info.legalIdentity.ref(OpaqueBytes.of(123))
|
||||
|
||||
// this test exercises the Cashflow issue and move subflows to ensure consistent spending of issued states
|
||||
val amount = 10000.DOLLARS
|
||||
|
@ -18,6 +18,11 @@ data class User(
|
||||
val password: String,
|
||||
val permissions: Set<String>) {
|
||||
override fun toString(): String = "${javaClass.simpleName}($username, permissions=$permissions)"
|
||||
fun toMap() = mapOf(
|
||||
"username" to username,
|
||||
"password" to password,
|
||||
"permissions" to permissions
|
||||
)
|
||||
}
|
||||
|
||||
/** Records the protocol version in which this RPC was added. */
|
||||
|
@ -12,12 +12,10 @@ import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Test
|
||||
import java.net.URL
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.util.*
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ConfigParsingTest {
|
||||
@Test
|
||||
@ -70,7 +68,7 @@ class ConfigParsingTest {
|
||||
|
||||
@Test
|
||||
fun `Path`() {
|
||||
val path = Paths.get("tmp") / "test"
|
||||
val path = "tmp" / "test"
|
||||
testPropertyType<PathData, PathListData, Path>(path, path / "file", valuesToString = true)
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,7 @@ data class CmdLineOptions(val baseDirectory: Path,
|
||||
val isVersion: Boolean,
|
||||
val noLocalShell: Boolean,
|
||||
val sshdServer: Boolean) {
|
||||
fun loadConfig(allowMissingConfig: Boolean = false, configOverrides: Map<String, Any?> = emptyMap()): FullNodeConfiguration {
|
||||
return ConfigHelper
|
||||
.loadConfig(baseDirectory, configFile, allowMissingConfig, configOverrides)
|
||||
fun loadConfig() = ConfigHelper
|
||||
.loadConfig(baseDirectory, configFile)
|
||||
.parseAs<FullNodeConfiguration>()
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,7 @@ import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.LOGS_DIRECTORY_NAME
|
||||
import net.corda.node.services.config.ConfigHelper
|
||||
import net.corda.node.services.config.FullNodeConfiguration
|
||||
import net.corda.node.services.config.VerifierType
|
||||
import net.corda.node.services.config.*
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||
import net.corda.node.utilities.ServiceIdentityGenerator
|
||||
@ -491,9 +489,9 @@ class DriverDSL(
|
||||
val webAddress = portAllocation.nextHostAndPort()
|
||||
val debugPort = if (isDebug) debugPortAllocation.nextPort() else null
|
||||
// TODO: Derive name from the full picked name, don't just wrap the common name
|
||||
val name = providedName ?: X509Utilities.getDevX509Name("${pickA(name).commonName}-${p2pAddress.port}")
|
||||
val name = providedName ?: X509Utilities.getDevX509Name("${oneOf(names).commonName}-${p2pAddress.port}")
|
||||
val baseDirectory = driverDirectory / name.commonName
|
||||
val configOverrides = mapOf(
|
||||
val configOverrides = configOf(
|
||||
"myLegalName" to name.toString(),
|
||||
"p2pAddress" to p2pAddress.toString(),
|
||||
"rpcAddress" to rpcAddress.toString(),
|
||||
@ -511,13 +509,7 @@ class DriverDSL(
|
||||
}
|
||||
},
|
||||
"useTestClock" to useTestClock,
|
||||
"rpcUsers" to rpcUsers.map {
|
||||
mapOf(
|
||||
"username" to it.username,
|
||||
"password" to it.password,
|
||||
"permissions" to it.permissions
|
||||
)
|
||||
},
|
||||
"rpcUsers" to rpcUsers.map { it.toMap() },
|
||||
"verifierType" to verifierType.name
|
||||
) + customOverrides
|
||||
|
||||
@ -612,7 +604,7 @@ class DriverDSL(
|
||||
val config = ConfigHelper.loadConfig(
|
||||
baseDirectory = baseDirectory,
|
||||
allowMissingConfig = true,
|
||||
configOverrides = mapOf(
|
||||
configOverrides = configOf(
|
||||
"myLegalName" to dedicatedNetworkMapLegalName.toString(),
|
||||
// TODO: remove the webAddress as NMS doesn't need to run a web server. This will cause all
|
||||
// node port numbers to be shifted, so all demos and docs need to be updated accordingly.
|
||||
@ -635,13 +627,13 @@ class DriverDSL(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val name = arrayOf(
|
||||
private val names = arrayOf(
|
||||
ALICE.name,
|
||||
BOB.name,
|
||||
DUMMY_BANK_A.name
|
||||
)
|
||||
|
||||
fun <A> pickA(array: Array<A>): A = array[Math.abs(Random().nextInt()) % array.size]
|
||||
private fun <A> oneOf(array: Array<A>) = array[Random().nextInt(array.size)]
|
||||
|
||||
private fun startNode(
|
||||
executorService: ListeningScheduledExecutorService,
|
||||
|
@ -18,21 +18,23 @@ import net.corda.nodeapi.config.SSLConfiguration
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.nio.file.Path
|
||||
|
||||
fun configOf(vararg pairs: Pair<String, Any?>) = ConfigFactory.parseMap(mapOf(*pairs))
|
||||
operator fun Config.plus(overrides: Map<String, Any?>) = ConfigFactory.parseMap(overrides).withFallback(this)
|
||||
|
||||
object ConfigHelper {
|
||||
private val log = loggerFor<ConfigHelper>()
|
||||
|
||||
fun loadConfig(baseDirectory: Path,
|
||||
configFile: Path = baseDirectory / "node.conf",
|
||||
allowMissingConfig: Boolean = false,
|
||||
configOverrides: Map<String, Any?> = emptyMap()): Config {
|
||||
configOverrides: Config = ConfigFactory.empty()): Config {
|
||||
val parseOptions = ConfigParseOptions.defaults()
|
||||
val defaultConfig = ConfigFactory.parseResources("reference.conf", parseOptions.setAllowMissing(false))
|
||||
val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig))
|
||||
val overrideConfig = ConfigFactory.parseMap(configOverrides + mapOf(
|
||||
val finalConfig = configOf(
|
||||
// Add substitution values here
|
||||
"basedir" to baseDirectory.toString())
|
||||
)
|
||||
val finalConfig = overrideConfig
|
||||
.withFallback(configOverrides)
|
||||
.withFallback(appConfig)
|
||||
.withFallback(defaultConfig)
|
||||
.resolve()
|
||||
|
@ -0,0 +1,24 @@
|
||||
package net.corda.node.services.config
|
||||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import net.corda.nodeapi.config.toProperties
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ConfigOperatorTests {
|
||||
|
||||
@Test
|
||||
fun `config plus behaves the same as map plus`() {
|
||||
val config = arrayOf("x" to "y1", "a" to "b", "z" to "Z")
|
||||
val overrides = arrayOf("x" to "y2", "c" to "d", "z" to null)
|
||||
val old = ConfigFactory.parseMap(mapOf(*config) + mapOf(*overrides))
|
||||
val new = configOf(*config) + mapOf(*overrides)
|
||||
listOf(old, new).map { it.toProperties() }.forEach { c ->
|
||||
assertEquals("y2", c["x"])
|
||||
assertEquals("b", c["a"])
|
||||
assertEquals("d", c["c"])
|
||||
assertEquals(null, c["z"])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,6 @@ import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.node.driver.driver
|
||||
import net.corda.node.services.transactions.SimpleNotaryService
|
||||
import net.corda.nodeapi.User
|
||||
import java.nio.file.Paths
|
||||
|
||||
/**
|
||||
* This file is exclusively for being able to run your nodes through an IDE (as opposed to running deployNodes)
|
||||
@ -16,8 +15,8 @@ import java.nio.file.Paths
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
||||
driver(isDebug = true, driverDirectory = Paths.get("build") / "attachment-demo-nodes") {
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.Companion.type)))
|
||||
driver(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes") {
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type)))
|
||||
startNode(DUMMY_BANK_A.name, rpcUsers = demoUser)
|
||||
startNode(DUMMY_BANK_B.name, rpcUsers = demoUser)
|
||||
waitForAllNodesToFinish()
|
||||
|
@ -1,3 +1,5 @@
|
||||
import net.corda.plugins.Cordform
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'idea'
|
||||
@ -68,7 +70,7 @@ task generateNotaryIdentity(type: JavaExec, dependsOn: 'cleanNodes') {
|
||||
args = [nodeDirs, notaryType, notaryName]
|
||||
}
|
||||
|
||||
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', 'generateNotaryIdentity']) {
|
||||
task deployNodes(type: Cordform, dependsOn: ['jar', generateNotaryIdentity]) {
|
||||
directory deployTo
|
||||
networkMap "CN=Notary 1,O=R3,OU=corda,L=London,C=UK"
|
||||
node {
|
||||
@ -80,7 +82,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', 'generateN
|
||||
cordapps = []
|
||||
rpcUsers = [['username': "demo", 'password': "demo", 'permissions': [
|
||||
'StartFlow.net.corda.notarydemo.flows.DummyIssueAndMove',
|
||||
'StartFlow.net.corda.flows.NotaryFlow$Client'
|
||||
'StartFlow.net.corda.notarydemo.flows.RPCStartableNotaryFlowClient'
|
||||
]]]
|
||||
}
|
||||
node {
|
||||
@ -126,4 +128,3 @@ task notarise(type: JavaExec) {
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
main = 'net.corda.notarydemo.NotaryDemoKt'
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import net.corda.core.div
|
||||
import net.corda.core.utilities.ALICE
|
||||
import net.corda.core.utilities.BOB
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.flows.NotaryFlow
|
||||
import net.corda.node.driver.NetworkMapStartStrategy
|
||||
import net.corda.node.driver.PortAllocation
|
||||
import net.corda.node.driver.driver
|
||||
@ -14,14 +13,14 @@ import net.corda.node.services.startFlowPermission
|
||||
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||
import net.corda.nodeapi.User
|
||||
import net.corda.notarydemo.flows.DummyIssueAndMove
|
||||
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.nio.file.Paths
|
||||
|
||||
/** Creates and starts all nodes required for the demo. */
|
||||
fun main(args: Array<String>) {
|
||||
val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<DummyIssueAndMove>(), startFlowPermission<NotaryFlow.Client>())))
|
||||
val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<DummyIssueAndMove>(), startFlowPermission<RPCStartableNotaryFlowClient>())))
|
||||
val networkMap = NetworkMapStartStrategy.Nominated(DUMMY_NOTARY.name.appendToCommonName("1"), HostAndPort.fromParts("localhost", 10009))
|
||||
driver(isDebug = true, driverDirectory = Paths.get("build") / "notary-demo-nodes", networkMapStartStrategy = networkMap, portAllocation = PortAllocation.Incremental(10001)) {
|
||||
driver(isDebug = true, driverDirectory = "build" / "notary-demo-nodes", networkMapStartStrategy = networkMap, portAllocation = PortAllocation.Incremental(10001)) {
|
||||
startNode(ALICE.name, rpcUsers = demoUser)
|
||||
startNode(BOB.name)
|
||||
startNotaryCluster(X500Name("CN=Raft,O=R3,OU=corda,L=Zurich,C=CH"), clusterSize = 3, type = RaftValidatingNotaryService.type)
|
||||
|
@ -2,23 +2,16 @@ package net.corda.notarydemo
|
||||
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.google.common.util.concurrent.Futures
|
||||
import joptsimple.OptionParser
|
||||
import net.corda.client.rpc.CordaRPCClient
|
||||
import net.corda.client.rpc.notUsed
|
||||
import net.corda.core.crypto.toStringShort
|
||||
import net.corda.core.div
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.messaging.startFlow
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.BOB
|
||||
import net.corda.flows.NotaryFlow
|
||||
import net.corda.nodeapi.config.SSLConfiguration
|
||||
import net.corda.notarydemo.flows.DummyIssueAndMove
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import kotlin.system.exitProcess
|
||||
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val host = HostAndPort.fromString("localhost:10003")
|
||||
@ -85,28 +78,7 @@ private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
|
||||
private fun notariseTransactions(transactions: List<SignedTransaction>): List<String> {
|
||||
// TODO: Remove this suppress when we upgrade to kotlin 1.1 or when JetBrain fixes the bug.
|
||||
@Suppress("UNSUPPORTED_FEATURE")
|
||||
val signatureFutures = transactions.map { rpc.startFlow(NotaryFlow::Client, it).returnValue }
|
||||
val signatureFutures = transactions.map { rpc.startFlow(::RPCStartableNotaryFlowClient, it).returnValue }
|
||||
return Futures.allAsList(signatureFutures).getOrThrow().map { it.map { it.by.toStringShort() }.joinToString() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCertPath(args: Array<String>): String? {
|
||||
val parser = OptionParser()
|
||||
val certsPath = parser.accepts("certificates").withRequiredArg()
|
||||
val options = try {
|
||||
parser.parse(*args)
|
||||
} catch (e: Exception) {
|
||||
println(e.message)
|
||||
exitProcess(1)
|
||||
}
|
||||
return options.valueOf(certsPath)
|
||||
}
|
||||
|
||||
// TODO: Take this out once we have a dedicated RPC port and allow SSL on it to be optional.
|
||||
private fun sslConfigFor(nodename: String, certsPath: String?): SSLConfiguration {
|
||||
return object : SSLConfiguration {
|
||||
override val keyStorePassword: String = "cordacadevpass"
|
||||
override val trustStorePassword: String = "trustpass"
|
||||
override val certificatesDirectory: Path = if (certsPath != null) Paths.get(certsPath) else Paths.get("build") / "nodes" / nodename / "certificates"
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,11 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.DummyContract
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import java.util.*
|
||||
|
||||
@StartableByRPC
|
||||
class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: Party) : FlowLogic<SignedTransaction>() {
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
|
@ -0,0 +1,8 @@
|
||||
package net.corda.notarydemo.flows
|
||||
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.flows.NotaryFlow
|
||||
|
||||
@StartableByRPC
|
||||
class RPCStartableNotaryFlowClient(stx: SignedTransaction) : NotaryFlow.Client(stx)
|
@ -11,7 +11,6 @@ import net.corda.node.services.startFlowPermission
|
||||
import net.corda.node.services.transactions.SimpleNotaryService
|
||||
import net.corda.nodeapi.User
|
||||
import net.corda.testing.BOC
|
||||
import java.nio.file.Paths
|
||||
|
||||
/**
|
||||
* This file is exclusively for being able to run your nodes through an IDE (as opposed to running deployNodes)
|
||||
@ -22,7 +21,7 @@ fun main(args: Array<String>) {
|
||||
startFlowPermission<IssuerFlow.IssuanceRequester>(),
|
||||
startFlowPermission<net.corda.traderdemo.flow.SellerFlow>())
|
||||
val demoUser = listOf(User("demo", "demo", permissions))
|
||||
driver(driverDirectory = Paths.get("build") / "trader-demo-nodes", isDebug = true) {
|
||||
driver(driverDirectory = "build" / "trader-demo-nodes", isDebug = true) {
|
||||
val user = User("user1", "test", permissions = setOf(startFlowPermission<IssuerFlow.IssuanceRequester>()))
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type)))
|
||||
startNode(DUMMY_BANK_A.name, rpcUsers = demoUser)
|
||||
|
@ -12,6 +12,8 @@ import net.corda.node.driver.addressMustNotBeBound
|
||||
import net.corda.node.internal.Node
|
||||
import net.corda.node.services.config.ConfigHelper
|
||||
import net.corda.node.services.config.FullNodeConfiguration
|
||||
import net.corda.node.services.config.configOf
|
||||
import net.corda.node.services.config.plus
|
||||
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||
import net.corda.node.utilities.ServiceIdentityGenerator
|
||||
import net.corda.nodeapi.User
|
||||
@ -141,18 +143,12 @@ abstract class NodeBasedTest {
|
||||
val config = ConfigHelper.loadConfig(
|
||||
baseDirectory = baseDirectory,
|
||||
allowMissingConfig = true,
|
||||
configOverrides = mapOf(
|
||||
configOverrides = configOf(
|
||||
"myLegalName" to legalName.toString(),
|
||||
"p2pAddress" to localPort[0].toString(),
|
||||
"rpcAddress" to localPort[1].toString(),
|
||||
"extraAdvertisedServiceIds" to advertisedServices.map { it.toString() },
|
||||
"rpcUsers" to rpcUsers.map {
|
||||
mapOf(
|
||||
"username" to it.username,
|
||||
"password" to it.password,
|
||||
"permissions" to it.permissions
|
||||
)
|
||||
}
|
||||
"rpcUsers" to rpcUsers.map { it.toMap() }
|
||||
) + configOverrides
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.corda.demobench.model
|
||||
|
||||
import net.corda.core.crypto.commonName
|
||||
import net.corda.core.utilities.WHITESPACE
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
|
||||
open class NetworkMapConfig(val legalName: X500Name, val p2pPort: Int) {
|
||||
@ -9,7 +10,5 @@ open class NetworkMapConfig(val legalName: X500Name, val p2pPort: Int) {
|
||||
|
||||
}
|
||||
|
||||
private val WHITESPACE = "\\s++".toRegex()
|
||||
|
||||
fun String.stripWhitespace() = this.replace(WHITESPACE, "")
|
||||
fun String.toKey() = this.stripWhitespace().toLowerCase()
|
||||
fun String.stripWhitespace() = replace(WHITESPACE, "")
|
||||
fun String.toKey() = stripWhitespace().toLowerCase()
|
||||
|
@ -5,12 +5,6 @@ package net.corda.demobench.model
|
||||
import net.corda.nodeapi.User
|
||||
import java.util.*
|
||||
|
||||
fun User.toMap(): Map<String, Any> = mapOf(
|
||||
"username" to username,
|
||||
"password" to password,
|
||||
"permissions" to permissions
|
||||
)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun toUser(map: Map<String, Any>) = User(
|
||||
map.getOrElse("username", { "none" }) as String,
|
||||
|
Loading…
Reference in New Issue
Block a user