diff --git a/tools/jmeter/build.gradle b/tools/jmeter/build.gradle index 216fb9a25f..0f43927b39 100644 --- a/tools/jmeter/build.gradle +++ b/tools/jmeter/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'kotlin' apply plugin: 'us.kirchmeier.capsule' apply plugin: 'application' -mainClassName = 'net.corda.jmeter.Launcher' +mainClassName = 'com.r3.corda.jmeter.Launcher' dependencies { compile project(':client:rpc') @@ -33,7 +33,7 @@ dependencies { task(runServer, dependsOn: 'classes', type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = 'net.corda.jmeter.Launcher' + main = 'com.r3.corda.jmeter.Launcher' systemProperty "search_paths", project(':tools:jmeter').configurations.runtime.files.join(";") systemProperty "java.rmi.server.hostname", "0.0.0.0" systemProperty "jmeter.home", sourceSets.main.resources.getSrcDirs().first().getPath() @@ -45,7 +45,7 @@ task(runServer, dependsOn: 'classes', type: JavaExec) { task(runSsh, dependsOn: 'classes', type: JavaExec) { classpath = sourceSets.main.runtimeClasspath - main = 'net.corda.jmeter.Ssh' + main = 'com.r3.corda.jmeter.Ssh' if ( project.hasProperty("jmeterHosts") ) { args Eval.me(jmeterHosts) } @@ -79,7 +79,7 @@ jar { // Run with: java -jar corda-jmeter-.jar // No additional args required but will be passed if specified. task buildJMeterJAR(type: FatCapsule, dependsOn: 'jar') { - applicationClass 'net.corda.jmeter.Launcher' + applicationClass 'com.r3.corda.jmeter.Launcher' archiveName "jmeter-corda-${corda_release_version}.jar" applicationSource = files( project(':tools:jmeter').jar diff --git a/tools/jmeter/src/main/kotlin/net/corda/jmeter/CordaRPCSampler.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/FlowSampler.kt similarity index 71% rename from tools/jmeter/src/main/kotlin/net/corda/jmeter/CordaRPCSampler.kt rename to tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/FlowSampler.kt index b6d385fec1..206937da97 100644 --- a/tools/jmeter/src/main/kotlin/net/corda/jmeter/CordaRPCSampler.kt +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/FlowSampler.kt @@ -1,4 +1,4 @@ -package net.corda.jmeter +package com.r3.corda.jmeter import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCConnection @@ -12,25 +12,30 @@ import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext import org.apache.jmeter.samplers.SampleResult -class CordaRPCSampler() : AbstractJavaSamplerClient() { +abstract class FlowSampler() : AbstractJavaSamplerClient() { companion object { val host = Argument("host", "localhost", "", "The remote network address (hostname or IP address) to connect to for RPC.") val port = Argument("port", "10000", "", "The remote port to connect to for RPC.") val username = Argument("username", "corda", "", "The RPC user to connect to connect as.") val password = Argument("password", "corda_is_awesome", "", "The password for the RPC user.") - val className = Argument("pluginClassName", "", "", "The class name of the implementation of ${CordaRPCSampler.Plugin::class.java}.") - val allArgs = setOf(host, port, username, password, className) + val allArgs = setOf(host, port, username, password) } var rpcClient: CordaRPCClient? = null var rpcConnection: CordaRPCConnection? = null var rpcProxy: CordaRPCOps? = null - var plugin: Plugin? = null override fun getDefaultParameters(): Arguments { // Add copies of all args, since they seem to be mutable. - return Arguments().apply { for(arg in allArgs) { addArgument(arg.clone() as Argument) } } + return Arguments().apply { + for (arg in allArgs) { + addArgument(arg.clone() as Argument) + } + for (arg in additionalArgs) { + addArgument(arg.clone() as Argument) + } + } } override fun setupTest(context: JavaSamplerContext) { @@ -38,12 +43,11 @@ class CordaRPCSampler() : AbstractJavaSamplerClient() { rpcClient = CordaRPCClient(NetworkHostAndPort(context.getParameter(host.name), context.getIntParameter(port.name))) rpcConnection = rpcClient!!.start(context.getParameter(username.name), context.getParameter(password.name)) rpcProxy = rpcConnection!!.proxy - plugin = Class.forName(context.getParameter(className.name)).newInstance() as Plugin - plugin!!.setupTest(rpcProxy!!, context) + setupTest(rpcProxy!!, context) } override fun runTest(context: JavaSamplerContext): SampleResult { - val flowInvoke = plugin!!.createFlowInvoke(rpcProxy!!, context) + val flowInvoke = createFlowInvoke(rpcProxy!!, context) val result = SampleResult() result.sampleStart() val handle = rpcProxy!!.startFlowDynamic(flowInvoke!!.flowLogicClass, *(flowInvoke!!.args)) @@ -55,7 +59,7 @@ class CordaRPCSampler() : AbstractJavaSamplerClient() { return result.apply { isSuccessful = true } - } catch(e: Exception) { + } catch (e: Exception) { result.sampleEnd() return result.apply { isSuccessful = false @@ -64,8 +68,7 @@ class CordaRPCSampler() : AbstractJavaSamplerClient() { } override fun teardownTest(context: JavaSamplerContext) { - plugin!!.teardownTest(rpcProxy!!, context) - plugin = null + teardownTest(rpcProxy!!, context) rpcProxy = null rpcConnection!!.close() rpcConnection = null @@ -73,11 +76,10 @@ class CordaRPCSampler() : AbstractJavaSamplerClient() { super.teardownTest(context) } - interface Plugin { - fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) - fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke<*> - fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) - } + abstract val additionalArgs: Set + abstract fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) + abstract fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke<*> + abstract fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) class FlowInvoke>(val flowLogicClass: Class, val args: Array) } \ No newline at end of file diff --git a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt similarity index 99% rename from tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt rename to tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt index 827e76cef4..b45302471f 100644 --- a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt @@ -1,4 +1,4 @@ -package net.corda.jmeter +package com.r3.corda.jmeter import net.corda.core.internal.div import org.apache.jmeter.JMeter diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt new file mode 100644 index 0000000000..e5fc610e2f --- /dev/null +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt @@ -0,0 +1,44 @@ +package com.r3.corda.jmeter + +import net.corda.core.identity.CordaX500Name +import net.corda.core.identity.Party +import net.corda.core.messaging.CordaRPCOps +import net.corda.core.utilities.OpaqueBytes +import net.corda.finance.DOLLARS +import net.corda.finance.flows.CashIssueFlow +import org.apache.jmeter.config.Argument +import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext + + +abstract class AbstractSampler : FlowSampler() { + lateinit var notaryIdentity: Party + + companion object JMeterProperties { + val notary = Argument("notaryName", "", "", "The X500 name of the notary.") + } + + protected fun getIdentities(rpc: CordaRPCOps, testContext: JavaSamplerContext) { + if (!testContext.containsParameter(notary.name)) { + throw IllegalStateException("You must specify the '${notary.name}' property.") + } + val notaryName = CordaX500Name.parse(testContext.getParameter(notary.name)) + notaryIdentity = rpc.wellKnownPartyFromX500Name(notaryName) ?: throw IllegalStateException("Don't know $notaryName") + } +} + +class CashIssueSampler : AbstractSampler() { + override val additionalArgs: Set = setOf(notary) + + override fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) { + getIdentities(rpcProxy, testContext) + } + + override fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) { + } + + override fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke { + val amount = 1_100_000_000_000.DOLLARS + return FlowInvoke(CashIssueFlow::class.java, arrayOf(amount, OpaqueBytes.of(1), notaryIdentity)) + } + +} \ No newline at end of file diff --git a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Ssh.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt similarity index 99% rename from tools/jmeter/src/main/kotlin/net/corda/jmeter/Ssh.kt rename to tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt index 47060966ca..3c4a38391a 100644 --- a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Ssh.kt +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt @@ -1,4 +1,4 @@ -package net.corda.jmeter +package com.r3.corda.jmeter import com.jcraft.jsch.JSch import com.jcraft.jsch.Session diff --git a/tools/jmeter/src/main/kotlin/net/corda/jmeter/TraderDemoPlugins.kt b/tools/jmeter/src/main/kotlin/net/corda/jmeter/TraderDemoPlugins.kt deleted file mode 100644 index 357a1067f0..0000000000 --- a/tools/jmeter/src/main/kotlin/net/corda/jmeter/TraderDemoPlugins.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.corda.jmeter - -import net.corda.core.identity.CordaX500Name -import net.corda.core.identity.Party -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.utilities.OpaqueBytes -import net.corda.finance.DOLLARS -import net.corda.finance.flows.CashIssueFlow -import net.corda.jmeter.CordaRPCSampler.FlowInvoke -import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext - - -abstract class AsbtractTraderDemoPlugin : CordaRPCSampler.Plugin { - - //lateinit var buyer: Party - //lateinit var seller: Party - lateinit var notary: Party - - //val bankA = CordaX500Name(organisation = "Bank A", locality = "London", country = "GB") - //val bankB = CordaX500Name(organisation = "Bank B", locality = "New York", country = "US") - val node1 = CordaX500Name(commonName = null, state = null, organisation = "Perf-10.155.0.4", organisationUnit = "Corda", locality = "London", country = "GB") - - protected fun getIdentities(rpc: CordaRPCOps) { - //buyer = rpc.wellKnownPartyFromX500Name(bankA) ?: throw IllegalStateException("Don't know $bankA") - //seller = rpc.wellKnownPartyFromX500Name(bankB) ?: throw IllegalStateException("Don't know $bankB") - //notary = rpc.notaryIdentities().first() - notary = rpc.wellKnownPartyFromX500Name(node1) ?: throw IllegalStateException("Don't know $node1") - } -} - -class CashIssuerPlugin : AsbtractTraderDemoPlugin() { - override fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) { - getIdentities(rpcProxy) - } - - override fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) { - } - - override fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke { - val amount = 1_100_000_000_000.DOLLARS - //val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random()) - //rpc.startFlow(net.corda.finance.flows::CashIssueFlow, amount, OpaqueBytes.of(1), notary).returnValue.getOrThrow() - return FlowInvoke(CashIssueFlow::class.java, arrayOf(amount, OpaqueBytes.of(1), notary)) - } - -} \ No newline at end of file diff --git a/tools/jmeter/src/main/resources/Java Request.jmx b/tools/jmeter/src/main/resources/Example Flow Request.jmx similarity index 92% rename from tools/jmeter/src/main/resources/Java Request.jmx rename to tools/jmeter/src/main/resources/Example Flow Request.jmx index e0718d0211..257573d05e 100644 --- a/tools/jmeter/src/main/resources/Java Request.jmx +++ b/tools/jmeter/src/main/resources/Example Flow Request.jmx @@ -15,7 +15,7 @@ continue false - 10 + 1000 3 @@ -26,7 +26,7 @@ - + @@ -36,66 +36,30 @@ port - 10012 + 10003 = username - demo + corda = password - demo + corda_is_awesome = - - pluginClassName - net.corda.jmeter.CashIssuerPlugin + + notaryName + O=Perf-10.155.0.4, OU=Corda, L=London, C=GB = - net.corda.jmeter.CordaRPCSampler + com.r3.corda.jmeter.CashIssueSampler - - false - - saveConfig - - - true - true - true - - true - true - true - true - false - true - true - false - false - false - true - false - false - false - true - 0 - true - true - true - true - true - - - - - false @@ -168,6 +132,42 @@ + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + + + + + true diff --git a/tools/jmeter/src/main/resources/jmeter.properties b/tools/jmeter/src/main/resources/jmeter.properties index c4d001f71d..e4463eb2f7 100644 --- a/tools/jmeter/src/main/resources/jmeter.properties +++ b/tools/jmeter/src/main/resources/jmeter.properties @@ -238,7 +238,7 @@ gui.quick_9=ViewResultsFullVisualizer #--------------------------------------------------------------------------- # Remote Hosts - comma delimited -remote_hosts=127.0.0.1:20099 +remote_hosts=127.0.0.1:20100,127.0.0.1:20101,127.0.0.1:20102,127.0.0.1:20103,127.0.0.1:20104 #remote_hosts=localhost:1099,localhost:2010 # RMI port to be used by the server (must start rmiregistry with same port)