From f95b7434264bd8fff45e2bf4d31d676926803e67 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Wed, 8 Feb 2017 14:04:23 +0000 Subject: [PATCH] Only allow the first node to run notary services. And validate port numbers more strongly. --- .../corda/demobench/model/NodeController.kt | 22 +++++++++- .../demobench/model/ServiceController.kt | 40 +++++++++---------- .../net/corda/demobench/views/NodeTabView.kt | 11 ++++- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt index 431d137669..6f2eb0e247 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt @@ -2,17 +2,20 @@ package net.corda.demobench.model import com.typesafe.config.ConfigRenderOptions import java.lang.management.ManagementFactory -import java.nio.file.Paths import java.text.SimpleDateFormat import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicInteger import net.corda.demobench.pty.R3Pty import tornadofx.Controller +import java.io.IOException +import java.net.ServerSocket class NodeController : Controller() { private companion object Data { const val FIRST_PORT = 10000 + const val MIN_PORT = 1024 + const val MAX_PORT = 65535 } private val jvm by inject() @@ -63,12 +66,27 @@ class NodeController : Controller() { val nextPort: Int get() = port.andIncrement + fun isPortAvailable(port: Int): Boolean { + if ((port >= MIN_PORT) && (port <= MAX_PORT)) { + try { + ServerSocket(port).close() + return true + } catch (e: IOException) { + return false + } + } else { + return false + } + } + fun keyExists(key: String) = nodes.keys.contains(key) fun nameExists(name: String) = keyExists(toKey(name)) + fun hasNetworkMap(): Boolean = networkMapConfig != null + fun chooseNetworkMap(config: NodeConfig) { - if (networkMapConfig != null) { + if (hasNetworkMap()) { config.networkMap = networkMapConfig } else { networkMapConfig = config diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt index cac8530643..5a032f7838 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt @@ -7,32 +7,28 @@ import java.util.* class ServiceController : Controller() { - private var serviceSet: List - val services: List get() = serviceSet + val services: List = loadConf(javaClass.classLoader.getResource("services.conf")) - init { - /* - * Load our list of known extra Corda services. - */ - val serviceConf = javaClass.classLoader.getResource("services.conf") - serviceSet = if (serviceConf == null) { - emptyList() + val notaries: List = services.filter { it.startsWith("corda.notary.") }.toList() + + /* + * Load our list of known extra Corda services. + */ + private fun loadConf(url: URL?): List { + if (url == null) { + return emptyList() } else { - loadConf(serviceConf) - } - } + val set = TreeSet() + InputStreamReader(url.openStream()).useLines { + sq -> sq.forEach { + val service = it.trim() + set.add(service) - private fun loadConf(url: URL): List { - val set = TreeSet() - InputStreamReader(url.openStream()).useLines { - sq -> sq.forEach { - val service = it.trim() - set.add(service) - - log.info("Supports: " + service) + log.info("Supports: " + service) + } } + return set.toList() } - return set.toList() } -} \ No newline at end of file +} diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt index 6f6b50a966..b196bb1a8a 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt @@ -73,6 +73,8 @@ class NodeTabView : Fragment() { error("Port number required") } else if (it.contains(NOT_NUMBER)) { error("Invalid port number") + } else if (!nodeController.isPortAvailable(it.toInt())) { + error("Port $it is unavailable") } else { null } @@ -88,6 +90,8 @@ class NodeTabView : Fragment() { error("Port number required") } else if (it.contains(NOT_NUMBER)) { error("Invalid port number") + } else if (!nodeController.isPortAvailable(it.toInt())) { + error("Port $it is unavailable") } else { null } @@ -103,6 +107,8 @@ class NodeTabView : Fragment() { error("Port number required") } else if (it.contains(NOT_NUMBER)) { error("Invalid port number") + } else if (!nodeController.isPortAvailable(it.toInt())) { + error("Port $it is unavailable") } else { null } @@ -112,7 +118,7 @@ class NodeTabView : Fragment() { } fieldset("Services") { - listview(serviceController.services.observable()) { + listview(availableServices.observable()) { selectionModel.selectionMode = MULTIPLE model.item.extraServices.set(selectionModel.selectedItems) } @@ -131,6 +137,9 @@ class NodeTabView : Fragment() { val nodeTab = CloseableTab("New Node", root) + private val availableServices: List + get() = if (nodeController.hasNetworkMap()) serviceController.services else serviceController.notaries + fun launch() { model.commit() val config = nodeController.validate(model.item)