From 08577510afcb762de21a195648c74b9a9925b9b4 Mon Sep 17 00:00:00 2001 From: "rick.parker" Date: Tue, 14 Nov 2017 13:48:35 +0000 Subject: [PATCH] Clean up, renaming etc --- .../r3/corda/jmeter/FlowSampler.kt} | 36 ++-- .../kotlin/com/r3/corda/jmeter/Launcher.kt | 10 - .../main/kotlin/com/r3/corda/jmeter/Ssh.kt | 7 +- .../main/kotlin/net/corda/jmeter/Launcher.kt | 65 ------- .../src/main/kotlin/net/corda/jmeter/Ssh.kt | 113 ----------- .../net/corda/jmeter/TraderDemoPlugins.kt | 46 ----- .../main/resources/Example Flow Request.jmx | 2 +- .../src/main/resources/Java Request.jmx | 177 ------------------ 8 files changed, 23 insertions(+), 433 deletions(-) rename tools/jmeter/src/main/kotlin/{net/corda/jmeter/CordaRPCSampler.kt => com/r3/corda/jmeter/FlowSampler.kt} (71%) delete mode 100644 tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt delete mode 100644 tools/jmeter/src/main/kotlin/net/corda/jmeter/Ssh.kt delete mode 100644 tools/jmeter/src/main/kotlin/net/corda/jmeter/TraderDemoPlugins.kt delete mode 100644 tools/jmeter/src/main/resources/Java Request.jmx 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/com/r3/corda/jmeter/Launcher.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt index f4695cebfa..b45302471f 100644 --- a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt @@ -8,11 +8,6 @@ import java.nio.file.Files import java.nio.file.Paths import kotlin.streams.asSequence -/** - * A wrapper around JMeter to make it run without having a JMeter download installed locally. One mode is used for - * running on a remote cluster using an all-in-one bundle JAR using Capsule. The other is just used to run based on current - * classpath, but with optional SSH tunnelling logic automatically invoked. - */ class Launcher { companion object { @JvmStatic @@ -50,16 +45,11 @@ class Launcher { } jmeter.start(arrayOf("-s", "-p", (capsuleDirPath / "jmeter.properties").toString()) + extraArgs + args) } else { - val searchPath = Files.readAllLines(Paths.get(System.getProperty("search_paths_file"))).first() - logger.info("search_paths = $searchPath") - System.setProperty("search_paths", searchPath) jmeter.start(maybeOpenSshTunnels(args)) } } private fun maybeOpenSshTunnels(args: Array): Array { - // We trim the args at the point "-Xssh" appears in the array of args. Anything after that is a host to - // SSH tunnel to. var index = 0 for (arg in args) { if (arg == "-Xssh") { diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt index 93cc88cd7c..3c4a38391a 100644 --- a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt @@ -10,9 +10,7 @@ import java.io.BufferedReader import java.io.InputStreamReader import java.util.* -/** - * Creates SSH tunnels for remote controlling SSH servers/agents from the local host (via UI or headless). - */ + class Ssh { companion object { val log = LoggerFactory.getLogger(this::class.java) @@ -30,7 +28,7 @@ class Ssh { val jmeterProps = loadProps("/jmeter.properties") // The port the JMeter remote agents call back to on this client host. val clientRmiLocalPort = jmeterProps.getProperty("client.rmi.localport").toInt() - // Remote RMI registry port. + // TODO: Where is this value used? Just on the remote agent to set up the RMI registry? val serverRmiPort = jmeterProps.getProperty("server.rmi.port", "1099").toInt() // Where JMeter driver will try to connect for remote agents (should all be localhost so can ssh tunnel). @@ -49,6 +47,7 @@ class Ssh { val session = connectToHost(jsch, remoteHost, userName) sessions += session + // TODO: maybe check the local host is actually "localhost"? // For tunnelling the RMI registry on the remote agent // ssh ${remoteHostAndPort.host} -L 0.0.0.0:${localHostAndPort.port}:localhost:$serverRmiPort -N createOutboundTunnel(session, NetworkHostAndPort("0.0.0.0", localHostAndPort.port), NetworkHostAndPort("localhost", serverRmiPort)) diff --git a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt b/tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt deleted file mode 100644 index 827e76cef4..0000000000 --- a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Launcher.kt +++ /dev/null @@ -1,65 +0,0 @@ -package net.corda.jmeter - -import net.corda.core.internal.div -import org.apache.jmeter.JMeter -import org.slf4j.LoggerFactory -import java.net.InetAddress -import java.nio.file.Files -import java.nio.file.Paths -import kotlin.streams.asSequence - -class Launcher { - companion object { - @JvmStatic - fun main(args: Array) { - val logger = LoggerFactory.getLogger(this::class.java) - logger.info("Launcher called with ${args.toList()}") - val jmeter = JMeter() - val capsuleDir = System.getProperty("capsule.dir") - if (capsuleDir != null) { - // We are running under Capsule, so assume we want a JMeter slave server to be controlled from - // elsewhere. - logger.info("Starting JMeter in server mode from $capsuleDir") - val capsuleDirPath = Paths.get(capsuleDir) - // Add all JMeter and Corda jars onto the JMeter search_paths - val searchPath = Files.list(capsuleDirPath).asSequence().filter { - val filename = it.fileName.toString() - filename.endsWith(".jar") && (filename.contains("corda") || filename.contains("jmeter", true)) - }.joinToString(";") - logger.info("search_paths = $searchPath") - System.setProperty("search_paths", searchPath) - // Set the JMeter home as a property rather than command line arg, due to inconsistent code in JMeter. - System.setProperty("jmeter.home", capsuleDir) - // Create two dirs that JMeter expects, if they don't already exist. - Files.createDirectories(capsuleDirPath / "lib" / "ext") - Files.createDirectories(capsuleDirPath / "lib" / "junit") - // Now see if we have a hostname specific property file, and if so, add it. - val hostName = InetAddress.getLocalHost().hostName - val hostSpecificConfigFile = capsuleDirPath / "$hostName.properties" - logger.info("Attempting to use host-specific properties file $hostSpecificConfigFile") - val extraArgs = if (Files.exists(hostSpecificConfigFile)) { - logger.info("Found host-specific properties file") - arrayOf("-q", hostSpecificConfigFile.toString()) - } else { - emptyArray() - } - jmeter.start(arrayOf("-s", "-p", (capsuleDirPath / "jmeter.properties").toString()) + extraArgs + args) - } else { - jmeter.start(maybeOpenSshTunnels(args)) - } - } - - private fun maybeOpenSshTunnels(args: Array): Array { - var index = 0 - for (arg in args) { - if (arg == "-Xssh") { - // start ssh - Ssh.main(args.copyOfRange(index + 1, args.size), false) - return if (index == 0) emptyArray() else args.copyOfRange(0, index) - } - index++ - } - return args - } - } -} \ 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/net/corda/jmeter/Ssh.kt deleted file mode 100644 index 47060966ca..0000000000 --- a/tools/jmeter/src/main/kotlin/net/corda/jmeter/Ssh.kt +++ /dev/null @@ -1,113 +0,0 @@ -package net.corda.jmeter - -import com.jcraft.jsch.JSch -import com.jcraft.jsch.Session -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.loadtest.setupJSchWithSshAgent -import net.corda.nodeapi.internal.addShutdownHook -import org.slf4j.LoggerFactory -import java.io.BufferedReader -import java.io.InputStreamReader -import java.util.* - - -class Ssh { - companion object { - val log = LoggerFactory.getLogger(this::class.java) - - @JvmStatic - @JvmOverloads - fun main(args: Array, wait: Boolean = true) { - val userName = System.getProperty("user.name") - val jsch = setupJSchWithSshAgent() - val sessions = mutableListOf() - - // Read jmeter.properties - // For each host:port combo, map them to hosts from command line - - val jmeterProps = loadProps("/jmeter.properties") - // The port the JMeter remote agents call back to on this client host. - val clientRmiLocalPort = jmeterProps.getProperty("client.rmi.localport").toInt() - // TODO: Where is this value used? Just on the remote agent to set up the RMI registry? - val serverRmiPort = jmeterProps.getProperty("server.rmi.port", "1099").toInt() - - // Where JMeter driver will try to connect for remote agents (should all be localhost so can ssh tunnel). - val localHostsAndPorts = jmeterProps.getProperty("remote_hosts", "").split(',').map { it.trim() } - args.zip(localHostsAndPorts) { remoteHost, localHostAndPortString -> - // Actual remote host and port we will tunnel to. - log.info("Creating tunnels for $remoteHost") - val localHostAndPort = NetworkHostAndPort.parse(localHostAndPortString) - - // For the remote host, load their specific property file, since it specifies remote RMI server port - val unqualifiedHostName = remoteHost.substringBefore('.') - val hostProps = loadProps("/$unqualifiedHostName.properties") - - val serverRmiLocalPort = hostProps.getProperty("server.rmi.localport", jmeterProps.getProperty("server.rmi.localport")).toInt() - - val session = connectToHost(jsch, remoteHost, userName) - sessions += session - - // TODO: maybe check the local host is actually "localhost"? - // For tunnelling the RMI registry on the remote agent - // ssh ${remoteHostAndPort.host} -L 0.0.0.0:${localHostAndPort.port}:localhost:$serverRmiPort -N - createOutboundTunnel(session, NetworkHostAndPort("0.0.0.0", localHostAndPort.port), NetworkHostAndPort("localhost", serverRmiPort)) - - // For tunnelling the actual connection to the remote agent - // ssh ${remoteHostAndPort.host} -L 0.0.0.0:$serverRmiLocalPort:localhost:$serverRmiLocalPort -N - createOutboundTunnel(session, NetworkHostAndPort("0.0.0.0", serverRmiLocalPort), NetworkHostAndPort("localhost", serverRmiLocalPort)) - - // For returning results to the client - // ssh ${remoteHostAndPort.host} -R 0.0.0.0:clientRmiLocalPort:localhost:clientRmiLocalPort -N - createInboundTunnel(session, NetworkHostAndPort("0.0.0.0", clientRmiLocalPort), NetworkHostAndPort("localhost", clientRmiLocalPort)) - } - - if (wait) { - val input = BufferedReader(InputStreamReader(System.`in`)) - do { - log.info("Type 'quit' to exit cleanly.") - } while (input.readLine() != "quit") - sessions.forEach { - log.info("Closing tunnels for ${it.host}") - it.disconnect() - } - } else { - addShutdownHook { - sessions.forEach { - log.info("Closing tunnels for ${it.host}") - it.disconnect() - } - } - } - } - - private fun loadProps(filename: String): Properties { - val props = Properties() - this::class.java.getResourceAsStream(filename).use { - props.load(it) - } - return props - } - - fun connectToHost(jSch: JSch, remoteHost: String, remoteUserName: String): Session { - val session = jSch.getSession(remoteUserName, remoteHost, 22) - // We don't check the host fingerprints because they may change often - session.setConfig("StrictHostKeyChecking", "no") - log.info("Connecting to $remoteHost...") - session.connect() - log.info("Connected to $remoteHost!") - return session - } - - fun createOutboundTunnel(session: Session, local: NetworkHostAndPort, remote: NetworkHostAndPort) { - log.info("Creating outbound tunnel from $local to $remote with ${session.host}...") - session.setPortForwardingL(local.host, local.port, remote.host, remote.port) - log.info("Tunnel created!") - } - - fun createInboundTunnel(session: Session, local: NetworkHostAndPort, remote: NetworkHostAndPort) { - log.info("Creating inbound tunnel from $remote to $local on ${session.host}...") - session.setPortForwardingR(remote.host, remote.port, local.host, local.port) - log.info("Tunnel created!") - } - } -} \ No newline at end of file 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/Example Flow Request.jmx b/tools/jmeter/src/main/resources/Example Flow Request.jmx index 6a2d25cfcf..257573d05e 100644 --- a/tools/jmeter/src/main/resources/Example Flow Request.jmx +++ b/tools/jmeter/src/main/resources/Example Flow Request.jmx @@ -46,7 +46,7 @@ password - Password Here + corda_is_awesome = diff --git a/tools/jmeter/src/main/resources/Java Request.jmx b/tools/jmeter/src/main/resources/Java Request.jmx deleted file mode 100644 index e0718d0211..0000000000 --- a/tools/jmeter/src/main/resources/Java Request.jmx +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - false - false - - - - - - - - continue - - false - 10 - - 3 - - 1509455820000 - 1509455820000 - false - - - - - - - - - host - localhost - = - - - port - 10012 - = - - - username - demo - = - - - password - demo - = - - - pluginClassName - net.corda.jmeter.CashIssuerPlugin - = - - - - net.corda.jmeter.CordaRPCSampler - - - - - 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 - - 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 - - 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 - - - -