diff --git a/build.gradle b/build.gradle index 2d258f4d8a..0f15cbaa33 100644 --- a/build.gradle +++ b/build.gradle @@ -89,6 +89,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" compile "org.jetbrains.kotlinx:kotlinx-support-jdk8:0.2" + compile 'com.squareup.okhttp3:okhttp:3.3.1' // Unit testing helpers. testCompile 'junit:junit:4.12' diff --git a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt index d3824c39e0..619287e7de 100644 --- a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt @@ -28,10 +28,7 @@ import com.typesafe.config.ConfigFactory import joptsimple.OptionParser import joptsimple.OptionSet import org.apache.commons.io.IOUtils -import java.io.DataOutputStream import java.io.File -import java.net.HttpURLConnection -import java.net.SocketTimeoutException import java.net.URL import java.nio.file.Files import java.nio.file.Path @@ -39,6 +36,7 @@ import java.nio.file.Paths import java.util.* import kotlin.concurrent.fixedRateTimer import kotlin.system.exitProcess +import com.r3corda.demos.utilities.* // IRS DEMO // @@ -264,7 +262,7 @@ fun runIRSDemo(args: Array): Int { CliParams.parse(CliParamsSpec.parser.parse(*args)) } catch (e: Exception) { println(e) - printHelp() + printHelp(CliParamsSpec.parser) return 1 } @@ -430,79 +428,6 @@ private fun runUploadRates(host: HostAndPort) { }) } -// Todo: Use a simpler library function for this and handle timeout exceptions -private fun sendJson(url: URL, data: String, method: String) : Boolean { - val connection = url.openConnection() as HttpURLConnection - connection.doOutput = true - connection.useCaches = false - connection.requestMethod = method - connection.connectTimeout = 5000 - connection.readTimeout = 60000 - connection.setRequestProperty("Connection", "Keep-Alive") - connection.setRequestProperty("Cache-Control", "no-cache") - connection.setRequestProperty("Content-Type", "application/json") - connection.setRequestProperty("Content-Length", data.length.toString()) - - try { - val outStream = DataOutputStream(connection.outputStream) - outStream.writeBytes(data) - outStream.close() - - return when (connection.responseCode) { - 200 -> true - 201 -> true - else -> { - println("Failed to " + method + " data. Status Code: " + connection.responseCode + ". Message: " + connection.responseMessage) - false - } - } - } catch(e: SocketTimeoutException) { - println("Server took too long to respond") - return false - } -} - -private fun putJson(url: URL, data: String) : Boolean { - return sendJson(url, data, "PUT") -} - -private fun postJson(url: URL, data: String) : Boolean { - return sendJson(url, data, "POST") -} - -// Todo: Use a simpler library function for this and handle timeout exceptions -private fun uploadFile(url: URL, file: String) : Boolean { - val boundary = "===" + System.currentTimeMillis() + "===" - val hyphens = "--" - val clrf = "\r\n" - - val connection = url.openConnection() as HttpURLConnection - connection.doOutput = true - connection.doInput = true - connection.useCaches = false - connection.requestMethod = "POST" - connection.connectTimeout = 5000 - connection.readTimeout = 60000 - connection.setRequestProperty("Connection", "Keep-Alive") - connection.setRequestProperty("Cache-Control", "no-cache") - connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary) - - val request = DataOutputStream(connection.outputStream) - request.writeBytes(hyphens + boundary + clrf) - request.writeBytes("Content-Disposition: form-data; name=\"rates\" filename=\"example.rates.txt\"$clrf") - request.writeBytes(clrf) - request.writeBytes(file) - request.writeBytes(clrf) - request.writeBytes(hyphens + boundary + hyphens + clrf) - - if (connection.responseCode == 200) { - return true - } else { - println("Could not upload file. Status Code: " + connection + ". Message: " + connection.responseMessage) - return false - } -} - private fun getNodeConfig(cliParams: CliParams.RunNode): NodeConfiguration { if (!Files.exists(cliParams.dir)) { throw NotSetupException("Missing config directory. Please run node setup before running the node") @@ -540,8 +465,11 @@ private fun createDefaultConfigFile(configFile: File, legalName: String) { """.trimIndent().toByteArray()) } -private fun printHelp() { +private fun printHelp(parser: OptionParser) { println(""" - Please refer to the documentation in docs/build/index.html to learn how to run the demo. + Usage: irsdemo --role [NodeA|NodeB|Trade|Date] [|] [options] + Please refer to the documentation in docs/build/index.html for more info. + """.trimIndent()) + parser.printHelpOn(System.out) } diff --git a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt index c1e6fce49c..d994281a20 100644 --- a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt @@ -71,7 +71,6 @@ fun main(args: Array) { } fun runTraderDemo(args: Array): Int { - val cashIssuerKey = generateKeyPair() val parser = OptionParser() val roleArg = parser.accepts("role").withRequiredArg().ofType(Role::class.java).required() @@ -84,7 +83,7 @@ fun runTraderDemo(args: Array): Int { parser.parse(*args) } catch (e: Exception) { println(e.message) - println("Please refer to the documentation in docs/build/index.html to learn how to run the demo.") + printHelp(parser) return 1 } @@ -377,3 +376,13 @@ private class TraderDemoProtocolSeller(val otherSide: Party, } } + +private fun printHelp(parser: OptionParser) { + println(""" + Usage: trader-demo --role [BUYER|SELLER] [options] + Please refer to the documentation in docs/build/index.html for more info. + + """.trimIndent()) + parser.printHelpOn(System.out) +} + diff --git a/src/main/kotlin/com/r3corda/demos/utilities/HttpUtils.kt b/src/main/kotlin/com/r3corda/demos/utilities/HttpUtils.kt new file mode 100644 index 0000000000..24d09b7b09 --- /dev/null +++ b/src/main/kotlin/com/r3corda/demos/utilities/HttpUtils.kt @@ -0,0 +1,41 @@ +package com.r3corda.demos.utilities + +import okhttp3.* +import java.net.URL +import java.util.concurrent.TimeUnit + +/** + * A small set of utilities for making HttpCalls, aimed at demos. + */ +private val client by lazy { + OkHttpClient.Builder() + .connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS).build(); +} + +fun putJson(url: URL, data: String) : Boolean { + val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), data) + return makeRequest(Request.Builder().url(url).put(body).build()) +} + +fun postJson(url: URL, data: String) : Boolean { + val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), data) + return makeRequest(Request.Builder().url(url).post(body).build()) +} + +fun uploadFile(url: URL, file: String) : Boolean { + val body = MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("rates", "example.rates.txt", RequestBody.create(MediaType.parse("text/plain"), file)) + .build(); + return makeRequest(Request.Builder().url(url).post(body).build()) +} + +private fun makeRequest(request: Request): Boolean { + val response = client.newCall(request).execute(); + + if (!response.isSuccessful) { + println("Could not fulfill HTTP request. Status Code: ${response.code()}. Message: ${response.body()}") + } + return response.isSuccessful +} \ No newline at end of file