From c32e3a9e267c44d9a995354dc88464c036eedf33 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Tue, 11 Jun 2019 16:27:48 +0100 Subject: [PATCH] Removed experimental/behave (#5212) The behave framework is in its own repo. This code is no longer used. --- experimental/behave/README.md | 58 --- experimental/behave/build.gradle | 104 ------ experimental/behave/deps/.gitignore | 1 - experimental/behave/deps/drivers/.gitkeep | 0 experimental/behave/deps/drivers/README.md | 4 - experimental/behave/prepare.sh | 35 -- .../main/kotlin/net/corda/behave/Utilities.kt | 10 - .../database/DatabaseConfigurationTemplate.kt | 12 - .../behave/database/DatabaseConnection.kt | 85 ----- .../corda/behave/database/DatabaseSettings.kt | 66 ---- .../net/corda/behave/database/DatabaseType.kt | 48 --- .../configuration/H2ConfigurationTemplate.kt | 17 - .../PostgresConfigurationTemplate.kt | 25 -- .../net/corda/behave/file/FileUtilities.kt | 11 - .../kotlin/net/corda/behave/file/LogSource.kt | 46 --- .../behave/monitoring/ConjunctiveWatch.kt | 23 -- .../behave/monitoring/DisjunctiveWatch.kt | 24 -- .../corda/behave/monitoring/PatternWatch.kt | 24 -- .../net/corda/behave/monitoring/Watch.kt | 52 --- .../net/corda/behave/network/Network.kt | 291 --------------- .../net/corda/behave/node/Distribution.kt | 136 ------- .../main/kotlin/net/corda/behave/node/Node.kt | 347 ------------------ .../node/configuration/Configuration.kt | 58 --- .../configuration/ConfigurationTemplate.kt | 8 - .../configuration/CordappConfiguration.kt | 29 -- .../configuration/CurrencyConfiguration.kt | 23 -- .../configuration/DatabaseConfiguration.kt | 16 - .../node/configuration/NetworkInterface.kt | 62 ---- .../node/configuration/NotaryConfiguration.kt | 15 - .../behave/node/configuration/NotaryType.kt | 17 - .../node/configuration/UserConfiguration.kt | 36 -- .../net/corda/behave/process/Command.kt | 156 -------- .../net/corda/behave/process/JarCommand.kt | 32 -- .../behave/process/output/OutputListener.kt | 8 - .../corda/behave/service/ContainerService.kt | 117 ------ .../net/corda/behave/service/Service.kt | 71 ---- .../corda/behave/service/ServiceInitiator.kt | 5 - .../corda/behave/service/ServiceSettings.kt | 12 - .../behave/service/database/H2Service.kt | 16 - .../service/database/PostgreSQLService.kt | 50 --- .../corda/behave/ssh/MonitoringSSHClient.kt | 66 ---- .../kotlin/net/corda/behave/ssh/SSHClient.kt | 161 -------- .../behave/src/scenario/kotlin/Scenarios.kt | 11 - .../corda/behave/scenarios/ScenarioRunner.kt | 60 --- .../corda/behave/scenarios/ScenarioState.kt | 85 ----- .../corda/behave/scenarios/StepsContainer.kt | 53 --- .../corda/behave/scenarios/api/StepsBlock.kt | 16 - .../behave/scenarios/api/StepsProvider.kt | 6 - .../corda/behave/scenarios/helpers/Cash.kt | 65 ---- .../behave/scenarios/helpers/Database.kt | 22 -- .../net/corda/behave/scenarios/helpers/Ssh.kt | 42 --- .../corda/behave/scenarios/helpers/Startup.kt | 113 ------ .../behave/scenarios/helpers/Substeps.kt | 22 -- .../corda/behave/scenarios/helpers/Vault.kt | 21 -- .../corda/behave/scenarios/steps/CashSteps.kt | 37 -- .../scenarios/steps/ConfigurationSteps.kt | 65 ---- .../behave/scenarios/steps/DatabaseSteps.kt | 18 - .../behave/scenarios/steps/NetworkSteps.kt | 18 - .../corda/behave/scenarios/steps/RpcSteps.kt | 15 - .../corda/behave/scenarios/steps/SshSteps.kt | 18 - .../behave/scenarios/steps/StartupSteps.kt | 66 ---- .../behave/scenarios/steps/VaultSteps.kt | 45 --- .../scenarios/tests/StepsProviderTests.kt | 32 -- .../features/cash/currencies.feature | 35 -- .../features/database/connection.feature | 16 - .../features/startup/logging.feature | 34 -- .../behave/src/scenario/resources/log4j2.xml | 14 - .../resources/scripts/run-behave-features.sh | 26 -- .../behave/monitoring/MonitoringTests.kt | 63 ---- .../net/corda/behave/network/NetworkTests.kt | 41 --- .../net/corda/behave/process/CommandTests.kt | 31 -- .../behave/service/PostreSQLServiceTests.kt | 18 - .../behave/src/test/resources/log4j2.xml | 14 - settings.gradle | 1 - 74 files changed, 3500 deletions(-) delete mode 100644 experimental/behave/README.md delete mode 100644 experimental/behave/build.gradle delete mode 100644 experimental/behave/deps/.gitignore delete mode 100644 experimental/behave/deps/drivers/.gitkeep delete mode 100644 experimental/behave/deps/drivers/README.md delete mode 100755 experimental/behave/prepare.sh delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConfigurationTemplate.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConnection.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseSettings.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseType.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/H2ConfigurationTemplate.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/PostgresConfigurationTemplate.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/monitoring/ConjunctiveWatch.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/monitoring/DisjunctiveWatch.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/monitoring/PatternWatch.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/monitoring/Watch.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/ConfigurationTemplate.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CordappConfiguration.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CurrencyConfiguration.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/DatabaseConfiguration.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NetworkInterface.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryConfiguration.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryType.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/UserConfiguration.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/process/output/OutputListener.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/service/ContainerService.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/service/Service.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceInitiator.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceSettings.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/service/database/H2Service.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/service/database/PostgreSQLService.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/ssh/MonitoringSSHClient.kt delete mode 100644 experimental/behave/src/main/kotlin/net/corda/behave/ssh/SSHClient.kt delete mode 100644 experimental/behave/src/scenario/kotlin/Scenarios.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioRunner.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/StepsContainer.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsBlock.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsProvider.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Cash.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Database.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Ssh.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Vault.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/CashSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/ConfigurationSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/DatabaseSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/NetworkSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/RpcSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/SshSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/StartupSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/VaultSteps.kt delete mode 100644 experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/tests/StepsProviderTests.kt delete mode 100644 experimental/behave/src/scenario/resources/features/cash/currencies.feature delete mode 100644 experimental/behave/src/scenario/resources/features/database/connection.feature delete mode 100644 experimental/behave/src/scenario/resources/features/startup/logging.feature delete mode 100644 experimental/behave/src/scenario/resources/log4j2.xml delete mode 100755 experimental/behave/src/scenario/resources/scripts/run-behave-features.sh delete mode 100644 experimental/behave/src/test/kotlin/net/corda/behave/monitoring/MonitoringTests.kt delete mode 100644 experimental/behave/src/test/kotlin/net/corda/behave/network/NetworkTests.kt delete mode 100644 experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt delete mode 100644 experimental/behave/src/test/kotlin/net/corda/behave/service/PostreSQLServiceTests.kt delete mode 100644 experimental/behave/src/test/resources/log4j2.xml diff --git a/experimental/behave/README.md b/experimental/behave/README.md deleted file mode 100644 index 9f5d32a2d2..0000000000 --- a/experimental/behave/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Introduction - -This project illustrates how one can use Cucumber / BDD to drive -and test homogeneous and heterogeneous Corda networks on a local -machine. The framework has built-in support for Dockerised node -dependencies so that you easily can spin up a Corda node locally -that, for instance, uses a 3rd party database provider such as -Postgres. - -# Structure - -The project is split into three pieces: - - * **Testing Library** (main) - This library contains auxiliary - functions that help in configuring and bootstrapping Corda - networks on a local machine. The purpose of the library is to - aid in black-box testing and automation. - - * **Unit Tests** (test) - These are various tests for the - library described above. Note that there's only limited - coverage for now. - - * **BDD Framework** (scenario) - This module shows how to use - BDD-style frameworks to control the testing of Corda networks; - more specifically, using [Cucumber](cucumber.io). - -# Setup - -To get started, please follow the instructions below: - - * Go up to the root directory and build the capsule JAR. - - ```bash - $ cd ../../ - $ ./gradlew install - ``` - - * Come back to this folder and run: - - ```bash - $ cd experimental/behave - $ ./prepare.sh - ``` - -This script will download necessary database drivers and set up -the dependencies directory with copies of the Corda fat-JAR and -the network bootstrapping tool. - -# Selective Runs - -If you only want to run tests of a specific tag, you can append -the following parameter to the Gradle command: - -```bash -$ ../../gradlew scenario -Ptags="@cash" -# or -$ ../../gradlew scenario -Ptags="@cash,@logging" -``` \ No newline at end of file diff --git a/experimental/behave/build.gradle b/experimental/behave/build.gradle deleted file mode 100644 index 1a310bbcfa..0000000000 --- a/experimental/behave/build.gradle +++ /dev/null @@ -1,104 +0,0 @@ -ext { - commonsio_version = '2.6' - cucumber_version = '1.2.5' - crash_version = 'cce5a00f114343c1145c1d7756e1dd6df3ea984e' - docker_client_version = '8.11.0' -} - -group 'net.corda.behave' - -apply plugin: 'kotlin' - -sourceSets { - behave { - java { - compileClasspath += main.output - runtimeClasspath += main.output - srcDirs = ["src/main/kotlin", "src/scenario/kotlin"] - } - resources.srcDir file('src/scenario/resources') - } -} - -configurations { - behaveCompile.extendsFrom testCompile - behaveRuntime.extendsFrom testRuntime -} - -dependencies { - - // Library - - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - - compile("com.github.corda.crash:crash.shell:$crash_version") { - exclude group: "org.slf4j", module: "slf4j-jdk14" - exclude group: "org.bouncycastle" - } - - compile("com.github.corda.crash:crash.connectors.ssh:$crash_version") { - exclude group: "org.slf4j", module: "slf4j-jdk14" - exclude group: "org.bouncycastle" - } - - compile "org.slf4j:log4j-over-slf4j:$slf4j_version" - compile "org.slf4j:jul-to-slf4j:$slf4j_version" - compile "org.slf4j:jcl-over-slf4j:$slf4j_version" - compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version" - compile "org.apache.logging.log4j:log4j-core:$log4j_version" - - // JOptSimple: command line option parsing - compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version" - - // ClassGraph: classpath scanning - compile "io.github.classgraph:classgraph:$class_graph_version" - - compile "commons-io:commons-io:$commonsio_version" - compile "com.spotify:docker-client:$docker_client_version" - compile "io.reactivex:rxjava:$rxjava_version" - - compile project(':finance:contracts') - compile project(':finance:workflows') - compile project(':node-api') - compile project(':client:rpc') - - // Unit Tests - testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}" - testImplementation "junit:junit:$junit_version" - - testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}" - testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}" - - testCompile "org.assertj:assertj-core:$assertj_version" - - // Scenarios / End-to-End Tests - - behaveCompile "info.cukes:cucumber-java8:$cucumber_version" - behaveCompile "info.cukes:cucumber-junit:$cucumber_version" - behaveCompile "info.cukes:cucumber-picocontainer:$cucumber_version" -} - -test { - testLogging.showStandardStreams = true -} - -task behaveJar(type: Jar) { - baseName "corda-behave" - from sourceSets.behave.output - from { - configurations.behaveCompile.collect { - it.isDirectory() ? it : zipTree(it) - } - } - zip64 true - exclude("features/**") - exclude("scripts/**") - exclude("META-INF/*.DSA") - exclude("META-INF/*.RSA") - exclude("META-INF/*.SF") - manifest { - attributes 'Main-Class': 'net.corda.behave.scenarios.ScenarioRunner' - } -} diff --git a/experimental/behave/deps/.gitignore b/experimental/behave/deps/.gitignore deleted file mode 100644 index d392f0e82c..0000000000 --- a/experimental/behave/deps/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.jar diff --git a/experimental/behave/deps/drivers/.gitkeep b/experimental/behave/deps/drivers/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/experimental/behave/deps/drivers/README.md b/experimental/behave/deps/drivers/README.md deleted file mode 100644 index 6ca2db42d6..0000000000 --- a/experimental/behave/deps/drivers/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Download and store database drivers here; for example: - - h2-1.4.196.jar - - postgresql-42.1.4.jar - \ No newline at end of file diff --git a/experimental/behave/prepare.sh b/experimental/behave/prepare.sh deleted file mode 100755 index 1d78595971..0000000000 --- a/experimental/behave/prepare.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -set -x - -# Please ensure you run this script using source code (eg. GitHub master, branch or TAG) that reflects the version label defined below -# For example: -# corda-master => git clone https://github.com/corda/corda -# r3corda-master => git clone https://github.com/corda/enterprise -VERSION=corda-master -STAGING_DIR=~/staging -CORDA_DIR=${STAGING_DIR}/corda/${VERSION} -CORDAPP_DIR=${CORDA_DIR}/apps -DRIVERS_DIR=${STAGING_DIR}/drivers - -# Set up directories -mkdir -p ${STAGING_DIR} -mkdir -p ${CORDA_DIR} -mkdir -p ${CORDAPP_DIR} -mkdir -p ${DRIVERS_DIR} - -# Copy Corda capsule into deps -cd ../.. -./gradlew clean :node:capsule:buildCordaJar :finance:jar -cp -v $(ls node/capsule/build/libs/corda-*.jar | tail -n1) ${CORDA_DIR}/corda.jar - -# Copy finance library -cp -v $(ls finance/build/libs/corda-finance-*.jar | tail -n1) ${CORDAPP_DIR} - -# Download database drivers -curl "https://search.maven.org/remotecontent?filepath=com/h2database/h2/1.4.196/h2-1.4.196.jar" > ${DRIVERS_DIR}/h2-1.4.196.jar -curl -L "http://central.maven.org/maven2/org/postgresql/postgresql/42.1.4/postgresql-42.1.4.jar" > ${DRIVERS_DIR}/postgresql-42.1.4.jar - -# Build Network Bootstrapper -./gradlew tools:bootstrapper:jar -cp -v $(ls tools/bootstrapper/build/libs/*.jar | tail -n1) ${CORDA_DIR}/network-bootstrapper.jar diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt b/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt deleted file mode 100644 index 18b11273e6..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt +++ /dev/null @@ -1,10 +0,0 @@ -package net.corda.behave - -import java.time.Duration -import java.util.concurrent.CountDownLatch - -fun CountDownLatch.await(duration: Duration) = - this.await(duration.toMillis(), java.util.concurrent.TimeUnit.MILLISECONDS) - -fun Process.waitFor(duration: Duration) = - this.waitFor(duration.toMillis(), java.util.concurrent.TimeUnit.MILLISECONDS) diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConfigurationTemplate.kt b/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConfigurationTemplate.kt deleted file mode 100644 index fc0830dac1..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConfigurationTemplate.kt +++ /dev/null @@ -1,12 +0,0 @@ -package net.corda.behave.database - -import net.corda.behave.node.configuration.DatabaseConfiguration - -open class DatabaseConfigurationTemplate { - - open val connectionString: (DatabaseConfiguration) -> String = { "" } - - protected open val config: (DatabaseConfiguration) -> String = { "" } - - fun generate(config: DatabaseConfiguration) = config(config).trimMargin() -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConnection.kt b/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConnection.kt deleted file mode 100644 index 9133d0473c..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseConnection.kt +++ /dev/null @@ -1,85 +0,0 @@ -package net.corda.behave.database - -import net.corda.behave.node.configuration.DatabaseConfiguration -import java.io.Closeable -import java.sql.* -import java.util.* - -class DatabaseConnection( - private val config: DatabaseConfiguration, - template: DatabaseConfigurationTemplate -) : Closeable { - - private val connectionString = template.connectionString(config) - - private var conn: Connection? = null - - fun open(): Connection { - try { - val connectionProps = Properties() - connectionProps["user"] = config.username - connectionProps["password"] = config.password - retry (5) { - conn = DriverManager.getConnection(connectionString, connectionProps) - } - return conn ?: throw Exception("Unable to open connection") - } catch (ex: SQLException) { - throw Exception("An error occurred whilst connecting to \"$connectionString\". " + - "Maybe the user and/or password is invalid?", ex) - } - } - - override fun close() { - val connection = conn - if (connection != null) { - try { - conn = null - connection.close() - } catch (ex: SQLException) { - throw Exception("Failed to close database connection to \"$connectionString\"", ex) - } - } - } - - private fun query(conn: Connection?, stmt: String? = null) { - var statement: Statement? = null - val resultset: ResultSet? - try { - statement = conn?.prepareStatement(stmt - ?: "SELECT name FROM sys.tables WHERE name = ?") - statement?.setString(1, "Test") - resultset = statement?.executeQuery() - - try { - while (resultset?.next() == true) { - val name = resultset.getString("name") - println(name) - } - } catch (e: Exception) { - e.printStackTrace() - } finally { - resultset?.close() - } - } catch (e: Exception) { - e.printStackTrace() - } finally { - statement?.close() - } - } - - private fun retry(numberOfTimes: Int, action: () -> Unit) { - var i = numberOfTimes - while (numberOfTimes > 0) { - Thread.sleep(2000) - try { - action() - } catch (ex: Exception) { - if (i == 1) { - throw ex - } - } - i -= 1 - } - } - -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseSettings.kt b/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseSettings.kt deleted file mode 100644 index 51891fc9fa..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseSettings.kt +++ /dev/null @@ -1,66 +0,0 @@ -package net.corda.behave.database - -import net.corda.behave.node.configuration.Configuration -import net.corda.behave.node.configuration.DatabaseConfiguration -import net.corda.behave.service.Service -import net.corda.behave.service.ServiceInitiator - -class DatabaseSettings { - - var databaseName: String = "node" - private set - - var schemaName: String = "dbo" - private set - - var userName: String = "sa" - private set - - var driverJar: String? = null - private set - - private var databaseConfigTemplate: DatabaseConfigurationTemplate = DatabaseConfigurationTemplate() - - private val serviceInitiators = mutableListOf() - - fun withDatabase(name: String): DatabaseSettings { - databaseName = name - return this - } - - fun withSchema(name: String): DatabaseSettings { - schemaName = name - return this - } - - fun withDriver(name: String): DatabaseSettings { - driverJar = name - return this - } - - fun withUser(name: String): DatabaseSettings { - userName = name - return this - } - - fun withServiceInitiator(initiator: ServiceInitiator): DatabaseSettings { - serviceInitiators.add(initiator) - return this - } - - fun withConfigTemplate(configTemplate: DatabaseConfigurationTemplate): DatabaseSettings { - databaseConfigTemplate = configTemplate - return this - } - - fun config(config: DatabaseConfiguration): String { - return databaseConfigTemplate.generate(config) - } - - fun dependencies(config: Configuration): List { - return serviceInitiators.map { it(config) } - } - - val template: DatabaseConfigurationTemplate - get() = databaseConfigTemplate -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseType.kt b/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseType.kt deleted file mode 100644 index 4fb39c0944..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/database/DatabaseType.kt +++ /dev/null @@ -1,48 +0,0 @@ -package net.corda.behave.database - -import net.corda.behave.database.configuration.H2ConfigurationTemplate -import net.corda.behave.database.configuration.PostgresConfigurationTemplate -import net.corda.behave.node.configuration.Configuration -import net.corda.behave.node.configuration.DatabaseConfiguration -import net.corda.behave.service.database.H2Service -import net.corda.behave.service.database.PostgreSQLService - -enum class DatabaseType(val settings: DatabaseSettings) { - - H2(DatabaseSettings() - .withDatabase(H2Service.database) - .withSchema(H2Service.schema) - .withUser(H2Service.username) - .withConfigTemplate(H2ConfigurationTemplate()) - .withServiceInitiator { - H2Service("h2-${it.name}", it.database.port) - } - ), - - POSTGRES(DatabaseSettings() - .withDatabase(PostgreSQLService.database) - .withDriver(PostgreSQLService.driver) - .withSchema(PostgreSQLService.schema) - .withUser(PostgreSQLService.username) - .withConfigTemplate(PostgresConfigurationTemplate()) - .withServiceInitiator { - PostgreSQLService("postgres-${it.name}", it.database.port, it.database.password) - } - ); - - val driverJar = settings.driverJar - - fun dependencies(config: Configuration) = settings.dependencies(config) - - fun connection(config: DatabaseConfiguration) = DatabaseConnection(config, settings.template) - - companion object { - - fun fromName(name: String): DatabaseType? = when (name.toLowerCase()) { - "h2" -> H2 - "postgres" -> POSTGRES - "postgresql" -> POSTGRES - else -> null - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/H2ConfigurationTemplate.kt b/experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/H2ConfigurationTemplate.kt deleted file mode 100644 index 8042812bf4..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/H2ConfigurationTemplate.kt +++ /dev/null @@ -1,17 +0,0 @@ -package net.corda.behave.database.configuration - -import net.corda.behave.database.DatabaseConfigurationTemplate -import net.corda.behave.node.configuration.DatabaseConfiguration - -class H2ConfigurationTemplate : DatabaseConfigurationTemplate() { - - override val connectionString: (DatabaseConfiguration) -> String - get() = { "jdbc:h2:tcp://${it.host}:${it.port}/${it.database}" } - - override val config: (DatabaseConfiguration) -> String - get() = { - """ - |h2port=${it.port} - """ - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/PostgresConfigurationTemplate.kt b/experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/PostgresConfigurationTemplate.kt deleted file mode 100644 index e521bd1ee2..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/database/configuration/PostgresConfigurationTemplate.kt +++ /dev/null @@ -1,25 +0,0 @@ -package net.corda.behave.database.configuration - -import net.corda.behave.database.DatabaseConfigurationTemplate -import net.corda.behave.node.configuration.DatabaseConfiguration - -class PostgresConfigurationTemplate : DatabaseConfigurationTemplate() { - - override val connectionString: (DatabaseConfiguration) -> String - get() = { "jdbc:postgresql://${it.host}:${it.port}/${it.database}" } - - override val config: (DatabaseConfiguration) -> String - get() = { - """ - |dataSourceProperties = { - | dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource" - | dataSource.url = "${connectionString(it)}" - | dataSource.user = "${it.username}" - | dataSource.password = "${it.password}" - |} - |database = { - | transactionIsolationLevel = READ_COMMITTED - |} - """ - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt b/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt deleted file mode 100644 index 85855ae5d5..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt +++ /dev/null @@ -1,11 +0,0 @@ -package net.corda.behave.file - -import java.nio.file.Path -import java.nio.file.Paths - -val currentDirectory: Path - get() = Paths.get(System.getProperty("user.dir")) - -// location of Corda distributions and Drivers dependencies -val stagingRoot: Path - get() = System.getProperty("STAGING_ROOT")?.let { Paths.get(it) } ?: currentDirectory diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt b/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt deleted file mode 100644 index 320b3226da..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.corda.behave.file - -import net.corda.core.internal.list -import net.corda.core.internal.readText -import java.nio.file.Path -import kotlin.streams.toList - -class LogSource( - private val directory: Path, - filePattern: String? = ".*\\.log", - private val filePatternUsedForExclusion: Boolean = false -) { - - private val fileRegex = Regex(filePattern ?: ".*") - - data class MatchedLogContent( - val filename: Path, - val contents: String - ) - - fun find(pattern: String? = null): List { - val regex = if (pattern != null) { - Regex(pattern) - } else { - null - } - val logFiles = directory.list { - it.filter { - (!filePatternUsedForExclusion && it.fileName.toString().matches(fileRegex)) || - (filePatternUsedForExclusion && !it.fileName.toString().matches(fileRegex)) - }.toList() - } - val result = mutableListOf() - for (file in logFiles) { - val contents = file.readText() - if (regex != null) { - result.addAll(regex.findAll(contents).map { match -> - MatchedLogContent(file, match.value) - }) - } else { - result.add(MatchedLogContent(file, contents)) - } - } - return result - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/ConjunctiveWatch.kt b/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/ConjunctiveWatch.kt deleted file mode 100644 index ba91151edc..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/ConjunctiveWatch.kt +++ /dev/null @@ -1,23 +0,0 @@ -package net.corda.behave.monitoring - -import net.corda.behave.await -import java.time.Duration -import java.util.concurrent.CountDownLatch - -class ConjunctiveWatch( - private val left: Watch, - private val right: Watch -) : Watch { - - override fun ready() = left.ready() && right.ready() - - override fun await(timeout: Duration): Boolean { - val countDownLatch = CountDownLatch(2) - listOf(left, right).parallelStream().forEach { - if (it.await(timeout)) { - countDownLatch.countDown() - } - } - return countDownLatch.await(timeout) - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/DisjunctiveWatch.kt b/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/DisjunctiveWatch.kt deleted file mode 100644 index b4609bc151..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/DisjunctiveWatch.kt +++ /dev/null @@ -1,24 +0,0 @@ -package net.corda.behave.monitoring - -import net.corda.behave.await -import java.time.Duration -import java.util.concurrent.CountDownLatch - -class DisjunctiveWatch( - private val left: Watch, - private val right: Watch -) : Watch { - - override fun ready() = left.ready() || right.ready() - - override fun await(timeout: Duration): Boolean { - val countDownLatch = CountDownLatch(1) - listOf(left, right).parallelStream().forEach { - if (it.await(timeout)) { - countDownLatch.countDown() - } - } - return countDownLatch.await(timeout) - } -} - diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/PatternWatch.kt b/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/PatternWatch.kt deleted file mode 100644 index bd62ee786e..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/PatternWatch.kt +++ /dev/null @@ -1,24 +0,0 @@ -package net.corda.behave.monitoring - -import rx.Observable - -class PatternWatch( - observable: Observable, - pattern: String, - ignoreCase: Boolean = false -) : AbstractWatch(observable, false) { - - private val regularExpression: Regex = if (ignoreCase) { - Regex("^.*$pattern.*$", RegexOption.IGNORE_CASE) - } else { - Regex("^.*$pattern.*$") - } - - init { - run() - } - - override fun match(data: String): Boolean { - return regularExpression.matches(data.trim()) - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/Watch.kt b/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/Watch.kt deleted file mode 100644 index 389eff44ac..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/monitoring/Watch.kt +++ /dev/null @@ -1,52 +0,0 @@ -package net.corda.behave.monitoring - -import net.corda.behave.await -import net.corda.core.utilities.seconds -import rx.Observable -import java.time.Duration -import java.util.concurrent.CountDownLatch - -interface Watch { - fun await(timeout: Duration = 10.seconds): Boolean - fun ready(): Boolean - - operator fun times(other: Watch): Watch { - return ConjunctiveWatch(this, other) - } - - operator fun div(other: Watch): Watch { - return DisjunctiveWatch(this, other) - } -} - -/** - * @param [observable] refers to an observable stream of events - * @param [autostart] is true starting of Watch can be deferred - it helps in case of initialization - * order problems (like match()) using fields from subclass which won't get initialized before superclass - * constructor finishes. It is the responsibility of the subclass to manually call the run method - * if autostart is false. - */ -abstract class AbstractWatch(val observable: Observable, autostart: Boolean = true) : Watch { - - private val latch = CountDownLatch(1) - - init { - if (autostart) { - run() - } - } - - fun run() { - observable.exists { match(it) }.filter { it }.subscribe { - latch.countDown() - } - } - - override fun await(timeout: Duration): Boolean { - return latch.await(timeout) - } - - override fun ready(): Boolean = latch.count == 0L - - open fun match(data: T): Boolean = false -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt b/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt deleted file mode 100644 index a787b3ac8e..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt +++ /dev/null @@ -1,291 +0,0 @@ -package net.corda.behave.network - -import net.corda.behave.database.DatabaseType -import net.corda.behave.file.LogSource -import net.corda.behave.file.currentDirectory -import net.corda.behave.file.stagingRoot -import net.corda.behave.node.Distribution -import net.corda.behave.node.Node -import net.corda.behave.node.configuration.NotaryType -import net.corda.behave.process.JarCommand -import net.corda.core.CordaException -import net.corda.core.internal.* -import net.corda.core.utilities.contextLogger -import net.corda.core.utilities.minutes -import org.apache.commons.io.FileUtils -import java.io.Closeable -import java.nio.file.Path -import java.time.Duration -import java.time.Instant -import java.time.ZoneOffset.UTC -import java.time.format.DateTimeFormatter -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit - -class Network private constructor( - private val nodes: Map, - private val targetDirectory: Path, - private val timeout: Duration = 2.minutes -) : Closeable, Iterable { - - private val latch = CountDownLatch(1) - - private var isRunning = false - - private var isStopped = false - - private var hasError = false - - init { - targetDirectory.createDirectories() - } - - class Builder internal constructor( - private val timeout: Duration - ) { - - private val nodes = mutableMapOf() - - private val startTime = DateTimeFormatter - .ofPattern("yyyyMMdd-HHmmss") - .withZone(UTC) - .format(Instant.now()) - - private val directory = currentDirectory / "build" / "runs" / startTime - - fun addNode( - name: String, - distribution: Distribution = Distribution.MASTER, - databaseType: DatabaseType = DatabaseType.H2, - notaryType: NotaryType = NotaryType.NONE, - issuableCurrencies: List = emptyList() - ): Builder { - return addNode(Node.new() - .withName(name) - .withDistribution(distribution) - .withDatabaseType(databaseType) - .withNotaryType(notaryType) - .withIssuableCurrencies(*issuableCurrencies.toTypedArray()) - ) - } - - fun addNode(nodeBuilder: Node.Builder): Builder { - nodeBuilder - .withDirectory(directory) - .withTimeout(timeout) - val node = nodeBuilder.build() - nodes[node.config.name] = node - return this - } - - fun generate(): Network { - val network = Network(nodes, directory, timeout) - - network.copyDatabaseDrivers() - if (!network.configureNodes()) { - throw CordaException("Unable to configure nodes in Corda network. Please check logs in $directory") - } - network.bootstrapLocalNetwork() - - return network - } - } - - fun copyDatabaseDrivers() { - val driverDirectory = (targetDirectory / "libs").createDirectories() - log.info("Copying database drivers from $stagingRoot/drivers to $driverDirectory") - FileUtils.copyDirectory((stagingRoot / "drivers").toFile(), driverDirectory.toFile()) - } - - fun configureNodes(): Boolean { - var allDependenciesStarted = true - log.info("Configuring nodes ...") - for (node in nodes.values) { - node.configure() - if (!node.startDependencies()) { - allDependenciesStarted = false - break - } - } - return if (allDependenciesStarted) { - log.info("Nodes configured") - true - } else { - false - } - } - - private fun bootstrapLocalNetwork() { - val bootstrapper = nodes.values - .sortedByDescending { it.config.distribution.version } - .first() - .config.distribution.networkBootstrapper - - if (!bootstrapper.exists()) { - signalFailure("Network bootstrapping tool does not exist; exiting ...") - return - } - - log.info("Bootstrapping network, please wait ...") - val command = JarCommand( - bootstrapper, - arrayOf("$targetDirectory"), - targetDirectory, - timeout - ) - log.info("Running command: {}", command) - command.output.subscribe { - if (it.contains("Exception")) { - log.warn("Found error in output; interrupting bootstrapping action ...\n{}", it) - command.interrupt() - } - } - command.start() - if (!command.waitFor()) { - hasError = true - error("Failed to bootstrap network") { - val matches = LogSource(targetDirectory) - .find(".*[Ee]xception.*") - .groupBy { it.filename.toAbsolutePath() } - for ((key, value) in matches) { - log.info("Log($key):\n${value.joinToString("\n") { it.contents }}") - } - } - } else { - log.info("Network set-up completed") - } - } - - private fun cleanup() { - try { - if (!hasError || CLEANUP_ON_ERROR) { - log.info("Cleaning up runtime ...") - targetDirectory.deleteRecursively() - } else { - log.info("Deleting temporary files, but retaining logs and config ...") - for (node in nodes.values) { - val nodeDir = targetDirectory / node.config.name - nodeDir.list { paths -> paths - .filter { it.fileName.toString() !in setOf("logs", "node.conf") } - .forEach(Path::deleteRecursively) - } - } - listOf("libs", ".cache").forEach { (targetDirectory / it).deleteRecursively() } - } - log.info("Network was shut down successfully") - } catch (e: Exception) { - log.warn("Failed to cleanup runtime environment") - e.printStackTrace() - } - } - - private fun error(message: String, ex: Throwable? = null, action: (() -> Unit)? = null) { - hasError = true - log.warn(message, ex) - action?.invoke() - stop() - throw Exception(message, ex) - } - - fun start() { - if (isRunning || hasError) { - return - } - isRunning = true - for (node in nodes.values) { - log.info("Starting node [{}]", node.config.name) - node.start() - } - } - - fun waitUntilRunning(waitDuration: Duration? = null): Boolean { - - log.info("Network.waitUntilRunning") - - if (hasError) { - return false - } - var failedNodes = 0 - val nodesLatch = CountDownLatch(nodes.size) - nodes.values.parallelStream().forEach { - if (!it.waitUntilRunning(waitDuration ?: timeout)) { - failedNodes += 1 - } - nodesLatch.countDown() - } - nodesLatch.await() - return if (failedNodes > 0) { - error("$failedNodes node(s) did not start up as expected within the given time frame") { - signal() - keepAlive(timeout) - } - false - } else { - log.info("All nodes are running") - true - } - } - - fun signalFailure(message: String?, ex: Throwable? = null) { - error(message ?: "Signaling error to network ...", ex) { - signal() - keepAlive(timeout) - } - } - - fun signal() { - log.info("Sending termination signal ...") - latch.countDown() - } - - fun keepAlive(timeout: Duration) { - val secs = timeout.seconds - log.info("Waiting for up to {} second(s) for termination signal ...", secs) - val wasSignalled = latch.await(secs, TimeUnit.SECONDS) - log.info(if (wasSignalled) { - "Received termination signal" - } else { - "Timed out. No termination signal received during wait period" - }) - stop() - } - - fun stop() { - if (isStopped) { - return - } - log.info("Shutting down network ...") - isStopped = true - log.info("Shutting down nodes ...") - for (node in nodes.values) { - node.shutDown() - } - cleanup() - } - - fun use(action: (Network) -> Unit) { - this.start() - action(this) - close() - } - - override fun close() { - stop() - } - - override fun iterator(): Iterator { - return nodes.values.iterator() - } - - operator fun get(nodeName: String): Node? { - return nodes[nodeName] - } - - companion object { - val log = contextLogger() - const val CLEANUP_ON_ERROR = false - - fun new(timeout: Duration = 2.minutes - ): Builder = Builder(timeout) - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt deleted file mode 100644 index 9f9fa80418..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt +++ /dev/null @@ -1,136 +0,0 @@ -package net.corda.behave.node - -import net.corda.behave.file.stagingRoot -import net.corda.core.internal.copyTo -import net.corda.core.internal.createDirectories -import net.corda.core.internal.div -import net.corda.core.internal.exists -import net.corda.core.utilities.contextLogger -import java.net.URL -import java.nio.file.Path - -/** - * Corda distribution. - */ -class Distribution private constructor( - - /** - * The version string of the Corda distribution. - */ - val version: String, - - /** - * The path of the distribution fat JAR on disk, if available. - */ - file: Path? = null, - - /** - * The URL of the distribution fat JAR, if available. - */ - val url: URL? = null, - - /** - * The Docker image details, if available - */ - val baseImage: String? = null -) { - - /** - * The path to the distribution fat JAR. - */ - val path: Path = file ?: nodePrefix / version - - /** - * The path to the distribution fat JAR. - */ - val cordaJar: Path = path / "corda.jar" - - /** - * The path to available Cordapps for this distribution. - */ - val cordappDirectory: Path = path / "apps" - - /** - * The path to network bootstrapping tool. - */ - val networkBootstrapper: Path = path / "network-bootstrapper.jar" - - /** - * Ensure that the distribution is available on disk. - */ - fun ensureAvailable() { - if (cordaJar.exists()) return - val url = checkNotNull(url) { "File not found $cordaJar" } - try { - cordaJar.parent.createDirectories() - url.openStream().use { it.copyTo(cordaJar) } - } catch (e: Exception) { - if ("HTTP response code: 401" in e.message!!) { - log.warn("CORDA_ARTIFACTORY_USERNAME ${System.getenv("CORDA_ARTIFACTORY_USERNAME")}") - log.warn("CORDA_ARTIFACTORY_PASSWORD ${System.getenv("CORDA_ARTIFACTORY_PASSWORD")}") - throw Exception("Incorrect Artifactory permission. Please set CORDA_ARTIFACTORY_USERNAME and CORDA_ARTIFACTORY_PASSWORD environment variables correctly.") - } - throw e - } - } - - /** - * Human-readable representation of the distribution. - */ - override fun toString() = "Corda(version = $version, path = $cordaJar)" - - companion object { - - private val log = contextLogger() - - private val distributions = mutableListOf() - - private val nodePrefix = stagingRoot / "corda" - - val MASTER = fromJarFile("corda-master") - - /** - * Get representation of a Corda distribution from Artifactory based on its version string. - * @param version The version of the Corda distribution. - */ - fun fromArtifactory(version: String): Distribution { - val url = URL("https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases/net/corda/corda/$version/corda-$version.jar") - log.info("Artifactory URL: $url\n") - val distribution = Distribution(version, url = url) - distributions.add(distribution) - return distribution - } - - /** - * Get representation of a Corda distribution based on its version string and fat JAR path. - * @param version The version of the Corda distribution. - * @param jarFile The path to the Corda fat JAR. - */ - fun fromJarFile(version: String, jarFile: Path? = null): Distribution { - val distribution = Distribution(version, file = jarFile) - distributions.add(distribution) - return distribution - } - - /** - * Get Corda distribution from a Docker image file. - * @param baseImage The name (eg. corda) of the Corda distribution. - * @param imageTag The version (github commit id or corda version) of the Corda distribution. - */ - fun fromDockerImage(baseImage: String, imageTag: String): Distribution { - val distribution = Distribution(version = imageTag, baseImage = baseImage) - distributions.add(distribution) - return distribution - } - - /** - * Get registered representation of a Corda distribution based on its version string. - * @param version The version of the Corda distribution - */ - fun fromVersionString(version: String): Distribution = when (version) { - "master" -> MASTER - "corda-3.0" -> fromArtifactory(version) - else -> fromJarFile(version) - } - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt deleted file mode 100644 index b6b9672b37..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt +++ /dev/null @@ -1,347 +0,0 @@ -package net.corda.behave.node - -import net.corda.behave.database.DatabaseConnection -import net.corda.behave.database.DatabaseType -import net.corda.behave.file.LogSource -import net.corda.behave.file.currentDirectory -import net.corda.behave.file.stagingRoot -import net.corda.behave.monitoring.PatternWatch -import net.corda.behave.node.configuration.* -import net.corda.behave.process.JarCommand -import net.corda.behave.service.Service -import net.corda.behave.service.ServiceSettings -import net.corda.behave.ssh.MonitoringSSHClient -import net.corda.behave.ssh.SSHClient -import net.corda.client.rpc.CordaRPCClient -import net.corda.client.rpc.CordaRPCClientConfiguration -import net.corda.core.internal.div -import net.corda.core.internal.exists -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.utilities.NetworkHostAndPort -import net.corda.core.utilities.loggerFor -import net.corda.core.utilities.seconds -import org.apache.commons.io.FileUtils -import java.net.InetAddress -import java.nio.file.Path -import java.time.Duration -import java.util.concurrent.CountDownLatch - -/** - * Corda node. - */ -class Node( - val config: Configuration, - private val rootDirectory: Path = currentDirectory, - private val settings: ServiceSettings = ServiceSettings() -) { - - private val log = loggerFor() - - private val runtimeDirectory = rootDirectory / config.name - - private val logDirectory = runtimeDirectory / "logs" - - private val command = JarCommand( - config.distribution.cordaJar, - arrayOf("--config", "node.conf"), - runtimeDirectory, - settings.timeout, - enableRemoteDebugging = false - ) - - private val isAliveLatch = PatternWatch(command.output, "Node for \".*\" started up and registered") - - private var isConfigured = false - - private val serviceDependencies = mutableListOf() - - private var isStarted = false - - private var haveDependenciesStarted = false - - private var haveDependenciesStopped = false - - fun describe(): String { - val network = config.nodeInterface - val database = config.database - return """ - |Node Information: ${config.name} - | - P2P: ${network.host}:${network.p2pPort} - | - RPC: ${network.host}:${network.rpcPort} - | - SSH: ${network.host}:${network.sshPort} - | - DB: ${network.host}:${database.port} (${database.type}) - |""".trimMargin() - } - - fun configure() { - if (isConfigured) { return } - isConfigured = true - log.info("Configuring {} ...", this) - serviceDependencies.addAll(config.database.type.dependencies(config)) - config.distribution.ensureAvailable() - config.writeToFile(rootDirectory / "${config.name}_node.conf") - installApps() - } - - fun start(): Boolean { - if (!startDependencies()) { - return false - } - log.info("Starting {} ...", this) - return try { - command.start() - isStarted = true - true - } catch (e: Exception) { - log.warn("Failed to start {}", this) - e.printStackTrace() - false - } - } - - fun waitUntilRunning(waitDuration: Duration? = null): Boolean { - val ok = isAliveLatch.await(waitDuration ?: settings.timeout) - if (!ok) { - log.warn("{} did not start up as expected within the given time frame", this) - } else { - log.info("{} is running and ready for incoming connections", this) - } - return ok - } - - fun shutDown(): Boolean { - return try { - if (isStarted) { - log.info("Shutting down {} ...", this) - command.kill() - } - stopDependencies() - true - } catch (e: Exception) { - log.warn("Failed to shut down {} cleanly", this) - e.printStackTrace() - false - } - } - - val nodeInfoGenerationOutput: LogSource by lazy { - LogSource(logDirectory, "node-info-gen.log") - } - - val logOutput: LogSource by lazy { - val hostname = InetAddress.getLocalHost().hostName - LogSource(logDirectory, "node-$hostname.*.log") - } - - val database: DatabaseConnection by lazy { - DatabaseConnection(config.database, config.databaseType.settings.template) - } - - fun ssh( - exitLatch: CountDownLatch? = null, - clientLogic: (MonitoringSSHClient) -> Unit - ) { - Thread(Runnable { - val network = config.nodeInterface - val user = config.users.first() - val client = SSHClient.connect(network.sshPort, user.password, username = user.username) - MonitoringSSHClient(client).use { - log.info("Connected to {} over SSH", this) - clientLogic(it) - log.info("Disconnecting from {} ...", this) - it.writeLine("bye") - exitLatch?.countDown() - } - }).start() - } - - fun rpc(action: (CordaRPCOps) -> T): T { - var result: T? = null - val user = config.users.first() - val address = config.nodeInterface - val targetHost = NetworkHostAndPort(address.host, address.rpcPort) - val config = CordaRPCClientConfiguration.DEFAULT.copy( - connectionMaxRetryInterval = 10.seconds - ) - log.info("Establishing RPC connection to ${targetHost.host} on port ${targetHost.port} ...") - CordaRPCClient(targetHost, config).use(user.username, user.password) { - log.info("RPC connection to ${targetHost.host}:${targetHost.port} established") - val client = it.proxy - result = action(client) - } - return result ?: error("Failed to run RPC action") - } - - override fun toString(): String { - return "Node(name = ${config.name}, version = ${config.distribution.version})" - } - - fun startDependencies(): Boolean { - if (haveDependenciesStarted) { return true } - haveDependenciesStarted = true - - if (serviceDependencies.isEmpty()) { return true } - - log.info("Starting dependencies for {} ...", this) - val latch = CountDownLatch(serviceDependencies.size) - var failed = false - serviceDependencies.parallelStream().forEach { - val wasStarted = it.start() - latch.countDown() - if (!wasStarted) { - failed = true - } - } - latch.await() - return if (!failed) { - log.info("Dependencies started for {}", this) - true - } else { - log.warn("Failed to start one or more dependencies for {}", this) - false - } - } - - private fun stopDependencies() { - if (haveDependenciesStopped) { return } - haveDependenciesStopped = true - - if (serviceDependencies.isEmpty()) { return } - - log.info("Stopping dependencies for {} ...", this) - val latch = CountDownLatch(serviceDependencies.size) - serviceDependencies.parallelStream().forEach { - it.stop() - latch.countDown() - } - latch.await() - log.info("Dependencies stopped for {}", this) - } - - private fun installApps() { - val version = config.distribution.version - val appDirectory = stagingRoot / "corda" / version / "apps" - if (appDirectory.exists()) { - val targetAppDirectory = runtimeDirectory / "cordapps" - FileUtils.copyDirectory(appDirectory.toFile(), targetAppDirectory.toFile()) - } - } - - class Builder { - - var name: String? = null - private set - - private var distribution = Distribution.MASTER - - private var databaseType = DatabaseType.H2 - - private var notaryType = NotaryType.NONE - - private val issuableCurrencies = mutableListOf() - - private var location: String = "London" - - private var country: String = "GB" - - private val apps = mutableListOf() - - private var includeFinance = false - - private var directory: Path? = null - - private var timeout = Duration.ofSeconds(60) - - fun withName(newName: String): Builder { - name = newName - return this - } - - fun withDistribution(newDistribution: Distribution): Builder { - distribution = newDistribution - return this - } - - fun withDatabaseType(newDatabaseType: DatabaseType): Builder { - databaseType = newDatabaseType - return this - } - - fun withNotaryType(newNotaryType: NotaryType): Builder { - notaryType = newNotaryType - return this - } - - fun withIssuableCurrencies(vararg currencies: String): Builder { - issuableCurrencies.addAll(currencies) - return this - } - - fun withIssuableCurrencies(currencies: List): Builder { - issuableCurrencies.addAll(currencies) - return this - } - - fun withLocation(location: String, country: String): Builder { - this.location = location - this.country = country - return this - } - - fun withFinanceApp(): Builder { - includeFinance = true - return this - } - - fun withApp(app: String): Builder { - apps.add(app) - return this - } - - fun withDirectory(newDirectory: Path): Builder { - directory = newDirectory - return this - } - - fun withTimeout(newTimeout: Duration): Builder { - timeout = newTimeout - return this - } - - fun build(): Node { - val name = name ?: error("Node name not set") - val directory = directory ?: error("Runtime directory not set") - return Node( - Configuration( - name, - distribution, - databaseType, - location = location, - country = country, - notary = NotaryConfiguration(notaryType), - cordapps = CordappConfiguration( - apps = apps, - includeFinance = includeFinance - ), - configElements = *arrayOf( - NotaryConfiguration(notaryType), - CurrencyConfiguration(issuableCurrencies) - ) - ), - directory, - ServiceSettings(timeout) - ) - } - - private fun error(message: String): T { - throw IllegalArgumentException(message) - } - } - - companion object { - - fun new() = Builder() - - } - -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt deleted file mode 100644 index de6450a6ca..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt +++ /dev/null @@ -1,58 +0,0 @@ -package net.corda.behave.node.configuration - -import net.corda.behave.database.DatabaseType -import net.corda.behave.node.Distribution -import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.writeText -import net.corda.core.utilities.contextLogger -import java.nio.file.Path - -class Configuration( - val name: String, - val distribution: Distribution = Distribution.MASTER, - val databaseType: DatabaseType = DatabaseType.H2, - val location: String = "London", - val country: String = "GB", - val users: UserConfiguration = UserConfiguration().withUser("corda", DEFAULT_PASSWORD), - val nodeInterface: NetworkInterface = NetworkInterface(), - val database: DatabaseConfiguration = DatabaseConfiguration( - databaseType, - nodeInterface.host, - nodeInterface.dbPort, - password = DEFAULT_PASSWORD - ), - // TODO This is not being used when it could be. The call-site is using configElements instead. - val notary: NotaryConfiguration = NotaryConfiguration(), - val cordapps: CordappConfiguration = CordappConfiguration(), - vararg configElements: ConfigurationTemplate -) { - - private val developerMode = true - - val cordaX500Name: CordaX500Name = CordaX500Name(name, location, country) - - private val basicConfig = """ - |myLegalName="C=$country,L=$location,O=$name" - |keyStorePassword="cordacadevpass" - |trustStorePassword="trustpass" - |devMode=$developerMode - |jarDirs = [ "../libs" ] - """.trimMargin() - - private val extraConfig = (configElements.toList() + listOf(users, nodeInterface)) - .joinToString(separator = "\n") { it.generate(this) } - - fun writeToFile(file: Path) { - file.writeText(this.generate()) - log.debug(this.generate()) - } - - private fun generate() = listOf(basicConfig, database.config(), extraConfig) - .filter { it.isNotBlank() } - .joinToString("\n") - - companion object { - private val log = contextLogger() - const val DEFAULT_PASSWORD = "S0meS3cretW0rd" - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/ConfigurationTemplate.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/ConfigurationTemplate.kt deleted file mode 100644 index 244d94847f..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/ConfigurationTemplate.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.corda.behave.node.configuration - -open class ConfigurationTemplate { - - protected open val config: (Configuration) -> String = { "" } - - fun generate(config: Configuration) = config(config).trimMargin() -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CordappConfiguration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CordappConfiguration.kt deleted file mode 100644 index b288cb9514..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CordappConfiguration.kt +++ /dev/null @@ -1,29 +0,0 @@ -package net.corda.behave.node.configuration - -// TODO This is a ConfigurationTemplate but is never used as one. Therefore the private "applications" list is never used -// and thus includeFinance isn't necessary either. Something is amiss. -class CordappConfiguration(var apps: List = emptyList(), val includeFinance: Boolean = false) : ConfigurationTemplate() { - - private val applications = apps + if (includeFinance) { - listOf("net.corda:corda-finance:CORDA_VERSION") - } else { - emptyList() - } - - override val config: (Configuration) -> String - get() = { config -> - if (applications.isEmpty()) { - "" - } else { - """ - |cordapps = [ - |${applications.joinToString(", ") { formatApp(config, it) }} - |] - """ - } - } - - private fun formatApp(config: Configuration, app: String): String { - return "\"${app.replace("CORDA_VERSION", config.distribution.version)}\"" - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CurrencyConfiguration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CurrencyConfiguration.kt deleted file mode 100644 index 301aad7d24..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/CurrencyConfiguration.kt +++ /dev/null @@ -1,23 +0,0 @@ -package net.corda.behave.node.configuration - -class CurrencyConfiguration(private val issuableCurrencies: List) : ConfigurationTemplate() { - - override val config: (Configuration) -> String - get() = { - if (issuableCurrencies.isEmpty()) { - "" - } else { - // TODO This is no longer correct. issuableCurrencies is a config of the finance app and belongs - // in a separate .conf file for the app (in the config sub-directory, with a filename matching the CorDapp - // jar filename). It is no longer read in from the node conf file. There seem to be pieces missing in the - // behave framework to allow one to do this. - """ - |custom : { - | issuableCurrencies : [ - | ${issuableCurrencies.joinToString(", ")} - | ] - |} - """ - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/DatabaseConfiguration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/DatabaseConfiguration.kt deleted file mode 100644 index e25257441d..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/DatabaseConfiguration.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.corda.behave.node.configuration - -import net.corda.behave.database.DatabaseType - -data class DatabaseConfiguration( - val type: DatabaseType, - val host: String, - val port: Int, - val username: String = type.settings.userName, - val password: String, - val database: String = type.settings.databaseName, - val schema: String = type.settings.schemaName -) { - - fun config() = type.settings.config(this) -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NetworkInterface.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NetworkInterface.kt deleted file mode 100644 index a96ca3da05..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NetworkInterface.kt +++ /dev/null @@ -1,62 +0,0 @@ -package net.corda.behave.node.configuration - -import java.net.Socket -import java.util.concurrent.atomic.AtomicInteger - -data class NetworkInterface( - val host: String = "localhost", - val sshPort: Int = getPort(2222 + nodeIndex), - val p2pPort: Int = getPort(12001 + (nodeIndex * 5)), - val rpcPort: Int = getPort(12002 + (nodeIndex * 5)), - val rpcAdminPort: Int = getPort(12003 + (nodeIndex * 5)), - val webPort: Int = getPort(12004 + (nodeIndex * 5)), - val dbPort: Int = getPort(12005 + (nodeIndex * 5)), - val dockerPort: Int = getPort(5000 + (nodeIndex * 5)) -) : ConfigurationTemplate() { - - init { - nodeIndex += 1 - } - - override val config: (Configuration) -> String - get() = { - """ - |sshd={ port=$sshPort } - |p2pAddress="$host:$p2pPort" - |rpcSettings = { - | useSsl = false - | standAloneBroker = false - | address = "$host:$rpcPort" - | adminAddress = "$host:$rpcAdminPort" - |} - """ - } - - companion object { - - private var nodeIndex = 0 - - private var startOfBackupRange = AtomicInteger(40000) - - private fun getPort(suggestedPortNumber: Int): Int { - var portNumber = suggestedPortNumber - while (isPortInUse(portNumber)) { - portNumber = startOfBackupRange.getAndIncrement() - } - if (portNumber >= 65535) { - throw Exception("No free port found (suggested $suggestedPortNumber)") - } - return portNumber - } - - private fun isPortInUse(portNumber: Int): Boolean { - return try { - val s = Socket("localhost", portNumber) - s.close() - true - } catch (_: Exception) { - false - } - } - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryConfiguration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryConfiguration.kt deleted file mode 100644 index 9cfa15b652..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryConfiguration.kt +++ /dev/null @@ -1,15 +0,0 @@ -package net.corda.behave.node.configuration - -class NotaryConfiguration(private val notaryType: NotaryType = NotaryType.NONE) : ConfigurationTemplate() { - - override val config: (Configuration) -> String - get() = { - when (notaryType) { - NotaryType.NONE -> "" - NotaryType.NON_VALIDATING -> - "notary { validating = false }" - NotaryType.VALIDATING -> - "notary { validating = true }" - } - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryType.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryType.kt deleted file mode 100644 index 788d430cdc..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/NotaryType.kt +++ /dev/null @@ -1,17 +0,0 @@ -package net.corda.behave.node.configuration - -enum class NotaryType { - - NONE, - VALIDATING, - NON_VALIDATING -} - -fun String.toNotaryType(): NotaryType? { - return when (this.toLowerCase()) { - "non-validating" -> NotaryType.NON_VALIDATING - "nonvalidating" -> NotaryType.NON_VALIDATING - "validating" -> NotaryType.VALIDATING - else -> null - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/UserConfiguration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/UserConfiguration.kt deleted file mode 100644 index 6da827f802..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/UserConfiguration.kt +++ /dev/null @@ -1,36 +0,0 @@ -package net.corda.behave.node.configuration - -class UserConfiguration : ConfigurationTemplate(), Iterable { - - data class User(val username: String, val password: String, val permissions: List) - - private val users = mutableListOf() - - fun withUser(username: String, password: String, permissions: List = listOf("ALL")): UserConfiguration { - users.add(User(username, password, permissions)) - return this - } - - override fun iterator(): Iterator { - return users.iterator() - } - - override val config: (Configuration) -> String - get() = { - """ - |rpcUsers=[ - |${users.joinToString("\n") { userObject(it) }} - |] - """ - } - - private fun userObject(user: User): String { - return """ - |{ - | username="${user.username}" - | password="${user.password}" - | permissions=[${user.permissions.joinToString(", ")}] - |} - """.trimMargin() - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt b/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt deleted file mode 100644 index 05d08f0bf4..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt +++ /dev/null @@ -1,156 +0,0 @@ -package net.corda.behave.process - -import net.corda.behave.await -import net.corda.behave.file.currentDirectory -import net.corda.behave.process.output.OutputListener -import net.corda.behave.waitFor -import net.corda.core.utilities.contextLogger -import net.corda.core.utilities.minutes -import net.corda.core.utilities.seconds -import rx.Observable -import rx.Subscriber -import java.io.Closeable -import java.io.IOException -import java.nio.file.Path -import java.time.Duration -import java.util.concurrent.CountDownLatch - -open class Command( - private val command: List, - private val directory: Path = currentDirectory, - private val timeout: Duration = 2.minutes -): Closeable { - companion object { - private val WAIT_BEFORE_KILL: Duration = 5.seconds - private val log = contextLogger() - } - - private val terminationLatch = CountDownLatch(1) - - private val outputCapturedLatch = CountDownLatch(1) - - private var isInterrupted = false - - private var process: Process? = null - - private var outputListener: OutputListener? = null - - var exitCode = -1 - private set - - val output: Observable = Observable.create { emitter -> - outputListener = object : OutputListener { - override fun onNewLine(line: String) = emitter.onNext(line) - override fun onEndOfStream() = emitter.onCompleted() - } - }.share() - - private val thread = Thread(Runnable { - try { - log.info("Executing command: $command from directory: $directory") - val processBuilder = ProcessBuilder(command) - .directory(directory.toFile()) - .redirectErrorStream(true) - processBuilder.environment().putAll(System.getenv()) - process = processBuilder.start() - val process = process!! - Thread(Runnable { - val input = process.inputStream.bufferedReader() - while (true) { - try { - val line = input.readLine()?.trimEnd() ?: break - log.trace(line) - outputListener?.onNewLine(line) - } catch (_: IOException) { - break - } catch (ex: Exception) { - log.error("Unexpected exception during reading input", ex) - break - } - } - input.close() - outputListener?.onEndOfStream() - outputCapturedLatch.countDown() - }).start() - val streamIsClosed = outputCapturedLatch.await(timeout) - val timeout = if (!streamIsClosed || isInterrupted) { - 1.seconds - } else { - timeout - } - if (!process.waitFor(timeout)) { - process.destroy() - process.waitFor(WAIT_BEFORE_KILL) - if (process.isAlive) { - process.destroyForcibly() - process.waitFor() - } - } - exitCode = process.exitValue() - if (isInterrupted) { - log.warn("Process ended after interruption") - } else if (exitCode != 0 && exitCode != 143 /* SIGTERM */) { - log.warn("Process {} ended with exit code {}", this, exitCode) - } - } catch (e: Exception) { - log.warn("Error occurred when trying to run process", e) - throw e - } - finally { - process = null - terminationLatch.countDown() - } - }) - - fun start() { - thread.start() - } - - fun interrupt() { - isInterrupted = true - outputCapturedLatch.countDown() - } - - fun waitFor(): Boolean { - terminationLatch.await() - return exitCode == 0 - } - - fun kill() { - process?.destroy() - process?.waitFor(WAIT_BEFORE_KILL) - if (process?.isAlive == true) { - process?.destroyForcibly() - } - if (process != null) { - terminationLatch.await() - } - process = null - } - - override fun close() { - if (process?.isAlive == true) { - kill() - } - waitFor() - } - - fun run(action: (Command) -> Unit = { }): Int { - use { - start() - action(this) - } - return exitCode - } - - fun run(subscriber: Subscriber, action: (Command, Observable) -> Unit = { _, _ -> }): Int { - run { - output.subscribe(subscriber) - start() - action(this, output) - } - return exitCode - } - - override fun toString() = "Command(${command.joinToString(" ")})" -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt b/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt deleted file mode 100644 index 5d76ac83fc..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt +++ /dev/null @@ -1,32 +0,0 @@ -package net.corda.behave.process - -import java.nio.file.Path -import java.time.Duration - -class JarCommand( - jarFile: Path, - arguments: Array, - directory: Path, - timeout: Duration, - enableRemoteDebugging: Boolean = false -) : Command( - command = listOf( - "/usr/bin/java", - *extraArguments(enableRemoteDebugging), - "-jar", "$jarFile", - *arguments - ), - directory = directory, - timeout = timeout -) { - - companion object { - - private fun extraArguments(enableRemoteDebugging: Boolean) = - if (enableRemoteDebugging) { - arrayOf("-Dcapsule.jvm.args=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005") - } else { - arrayOf() - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/process/output/OutputListener.kt b/experimental/behave/src/main/kotlin/net/corda/behave/process/output/OutputListener.kt deleted file mode 100644 index 7912596804..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/process/output/OutputListener.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.corda.behave.process.output - -interface OutputListener { - - fun onNewLine(line: String) - - fun onEndOfStream() -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/service/ContainerService.kt b/experimental/behave/src/main/kotlin/net/corda/behave/service/ContainerService.kt deleted file mode 100644 index 70763d06f1..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/service/ContainerService.kt +++ /dev/null @@ -1,117 +0,0 @@ -package net.corda.behave.service - -import com.spotify.docker.client.DefaultDockerClient -import com.spotify.docker.client.DockerClient -import com.spotify.docker.client.messages.ContainerConfig -import com.spotify.docker.client.messages.HostConfig -import com.spotify.docker.client.messages.PortBinding -import net.corda.behave.monitoring.PatternWatch -import rx.Observable -import java.io.Closeable - -abstract class ContainerService( - name: String, - port: Int, - val startupStatement: String, - settings: ServiceSettings = ServiceSettings() -) : Service(name, port, settings), Closeable { - - protected val client: DockerClient = DefaultDockerClient.fromEnv().build() - - protected var id: String? = null - - protected open val baseImage: String = "" - - protected open val imageTag: String = "latest" - - protected abstract val internalPort: Int - - private var isClientOpen: Boolean = true - - private val environmentVariables: MutableList = mutableListOf() - - private val imageReference: String - get() = "$baseImage:$imageTag" - - override fun startService(): Boolean { - return try { - val port = "$internalPort" - val portBindings = mapOf( - port to listOf(PortBinding.of("0.0.0.0", this.port)) - ) - val hostConfig = HostConfig.builder().portBindings(portBindings).build() - val containerConfig = ContainerConfig.builder() - .hostConfig(hostConfig) - .image(imageReference) - .exposedPorts(port) - .env(*environmentVariables.toTypedArray()) - .build() - - val creation = client.createContainer(containerConfig) - id = creation.id() - - val info = client.inspectContainer(id) - log.info("Container $id info: $info") - - client.startContainer(id) - true - } catch (e: Exception) { - id = null - e.printStackTrace() - false - } - } - - override fun stopService(): Boolean { - if (id != null) { - client.stopContainer(id, 30) - client.removeContainer(id) - id = null - } - return true - } - - protected fun addEnvironmentVariable(name: String, value: String) { - environmentVariables.add("$name=$value") - } - - override fun checkPrerequisites() { - if (!client.listImages().any { true == it.repoTags()?.contains(imageReference) }) { - log.info("Pulling image $imageReference ...") - client.pull(imageReference) { } - log.info("Image $imageReference downloaded") - } - } - - override fun verify(): Boolean { - return true - } - - override fun waitUntilStarted(): Boolean { - try { - var timeout = settings.startupTimeout.toMillis() - while (timeout > 0) { - client.logs(id, DockerClient.LogsParam.stdout(), DockerClient.LogsParam.stderr()).use { - val contents = it.readFully() - val observable = Observable.from(contents.split("\n", "\r")) - if (PatternWatch(observable, startupStatement).await(settings.pollInterval)) { - log.info("Found process start-up statement for {}", this) - return true - } - } - timeout -= settings.pollInterval.toMillis() - } - return false - } catch (e: Exception) { - e.printStackTrace() - return false - } - } - - override fun close() { - if (isClientOpen) { - isClientOpen = false - client.close() - } - } -} diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/service/Service.kt b/experimental/behave/src/main/kotlin/net/corda/behave/service/Service.kt deleted file mode 100644 index dad118d5d5..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/service/Service.kt +++ /dev/null @@ -1,71 +0,0 @@ -package net.corda.behave.service - -import net.corda.core.utilities.loggerFor -import java.io.Closeable - -abstract class Service( - val name: String, - val port: Int, - val settings: ServiceSettings = ServiceSettings() -) : Closeable { - - private var isRunning: Boolean = false - - protected val log = loggerFor() - - fun start(): Boolean { - if (isRunning) { - log.warn("{} is already running", this) - return false - } - log.info("Starting {} ...", this) - checkPrerequisites() - if (!startService()) { - log.warn("Failed to start {}", this) - return false - } - isRunning = true - Thread.sleep(settings.startupDelay.toMillis()) - return if (!waitUntilStarted()) { - log.warn("Failed to start {}", this) - stop() - false - } else if (!verify()) { - log.warn("Failed to verify start-up of {}", this) - stop() - false - } else { - log.info("{} started and available", this) - true - } - } - - fun stop() { - if (!isRunning) { - return - } - log.info("Stopping {} ...", this) - if (stopService()) { - log.info("{} stopped", this) - isRunning = false - } else { - log.warn("Failed to stop {}", this) - } - } - - override fun close() { - stop() - } - - override fun toString() = "Service(name = $name, port = $port)" - - protected open fun checkPrerequisites() {} - - protected open fun startService() = true - - protected open fun stopService() = true - - protected open fun verify() = true - - protected open fun waitUntilStarted() = true -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceInitiator.kt b/experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceInitiator.kt deleted file mode 100644 index eb3d042d7f..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceInitiator.kt +++ /dev/null @@ -1,5 +0,0 @@ -package net.corda.behave.service - -import net.corda.behave.node.configuration.Configuration - -typealias ServiceInitiator = (Configuration) -> Service diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceSettings.kt b/experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceSettings.kt deleted file mode 100644 index e8a34a790b..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/service/ServiceSettings.kt +++ /dev/null @@ -1,12 +0,0 @@ -package net.corda.behave.service - -import net.corda.core.utilities.minutes -import net.corda.core.utilities.seconds -import java.time.Duration - -data class ServiceSettings( - val timeout: Duration = 1.minutes, - val startupDelay: Duration = 1.seconds, - val startupTimeout: Duration = 15.seconds, - val pollInterval: Duration = 1.seconds -) diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/service/database/H2Service.kt b/experimental/behave/src/main/kotlin/net/corda/behave/service/database/H2Service.kt deleted file mode 100644 index 8a2b5c6b02..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/service/database/H2Service.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.corda.behave.service.database - -import net.corda.behave.service.Service - -class H2Service( - name: String, - port: Int -) : Service(name, port) { - - companion object { - - const val database = "node" - const val schema = "dbo" - const val username = "sa" - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/service/database/PostgreSQLService.kt b/experimental/behave/src/main/kotlin/net/corda/behave/service/database/PostgreSQLService.kt deleted file mode 100644 index e331dcde74..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/service/database/PostgreSQLService.kt +++ /dev/null @@ -1,50 +0,0 @@ -package net.corda.behave.service.database - -import net.corda.behave.database.DatabaseConnection -import net.corda.behave.database.DatabaseType -import net.corda.behave.database.configuration.PostgresConfigurationTemplate -import net.corda.behave.node.configuration.DatabaseConfiguration -import net.corda.behave.service.ContainerService -import net.corda.behave.service.ServiceSettings - -class PostgreSQLService( - name: String, - port: Int, - private val password: String, - settings: ServiceSettings = ServiceSettings() -) : ContainerService(name, port, "database system is ready to accept connections", settings) { - - override val baseImage = "postgres" - - override val internalPort = 5432 - - override fun verify(): Boolean { - val config = DatabaseConfiguration( - type = DatabaseType.POSTGRES, - host = host, - port = port, - database = database, - schema = schema, - username = username, - password = password - ) - val connection = DatabaseConnection(config, PostgresConfigurationTemplate()) - try { - connection.use { - return true - } - } catch (ex: Exception) { - log.warn(ex.message, ex) - ex.printStackTrace() - } - return false - } - - companion object { - const val host = "localhost" - const val database = "postgres" - const val schema = "public" - const val username = "postgres" - const val driver = "postgresql-42.1.4.jar" - } -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/ssh/MonitoringSSHClient.kt b/experimental/behave/src/main/kotlin/net/corda/behave/ssh/MonitoringSSHClient.kt deleted file mode 100644 index d55a2d2c69..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/ssh/MonitoringSSHClient.kt +++ /dev/null @@ -1,66 +0,0 @@ -package net.corda.behave.ssh - -import net.corda.behave.process.output.OutputListener -import rx.Observable -import java.io.Closeable -import java.io.InterruptedIOException - -class MonitoringSSHClient( - private val client: SSHClient -) : Closeable { - - private var isRunning = false - - private lateinit var outputListener: OutputListener - - val output: Observable = Observable.create { emitter -> - outputListener = object : OutputListener { - override fun onNewLine(line: String) { - emitter.onNext(line) - } - - override fun onEndOfStream() { - emitter.onCompleted() - } - } - } - - private val thread = Thread(Runnable { - while (isRunning) { - try { - val line = client.readLine() ?: break - outputListener.onNewLine(line) - } catch (_: InterruptedIOException) { - break - } - } - outputListener.onEndOfStream() - }) - - init { - isRunning = true - output.subscribe() - thread.start() - } - - override fun close() { - isRunning = false - thread.join(1000) - if (thread.isAlive) { - thread.interrupt() - } - client.close() - } - - fun use(action: (MonitoringSSHClient) -> Unit) { - use { - action(this) - } - } - - fun write(vararg bytes: Byte) = client.write(*bytes) - - fun write(charSequence: CharSequence) = client.write(charSequence) - - fun writeLine(string: String) = client.writeLine(string) -} \ No newline at end of file diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/ssh/SSHClient.kt b/experimental/behave/src/main/kotlin/net/corda/behave/ssh/SSHClient.kt deleted file mode 100644 index 1ff800408a..0000000000 --- a/experimental/behave/src/main/kotlin/net/corda/behave/ssh/SSHClient.kt +++ /dev/null @@ -1,161 +0,0 @@ -package net.corda.behave.ssh - -import net.corda.core.utilities.contextLogger -import org.apache.sshd.client.SshClient -import org.apache.sshd.client.channel.ChannelShell -import org.apache.sshd.client.session.ClientSession -import org.apache.sshd.common.channel.SttySupport -import org.crsh.util.Utils -import java.io.* -import java.time.Duration -import java.util.concurrent.TimeUnit - -open class SSHClient private constructor( - private val client: SshClient, - private val outputStream: OutputStream, - private val inputStream: InputStream, - private val session: ClientSession, - private val channel: ChannelShell -) : Closeable { - - private var isClosed = false - - fun read(): Int? { - if (isClosed) { - return null - } - val char = inputStream.read() - return if (char != -1) { - char - } else { - null - } - } - - fun readLine(): String? { - if (isClosed) { - return null - } - var ch: Int? - val lineBuffer = mutableListOf() - while (true) { - ch = read() - if (ch == null) { - if (lineBuffer.isEmpty()) { - return null - } - break - } - lineBuffer.add(ch.toChar()) - if (ch == 10) { - break - } - } - return String(lineBuffer.toCharArray()) - } - - fun write(s: CharSequence) { - if (isClosed) { - return - } - write(*s.toString().toByteArray(UTF8)) - } - - fun write(vararg bytes: Byte) { - if (isClosed) { - return - } - outputStream.write(bytes) - } - - fun writeLine(s: String) { - write("$s\n") - flush() - } - - fun flush() { - if (isClosed) { - return - } - outputStream.flush() - } - - override fun close() { - if (isClosed) { - return - } - try { - Utils.close(outputStream) - channel.close(false) - session.close(false) - client.stop() - } finally { - isClosed = true - } - } - - companion object { - - private val log = contextLogger() - - fun connect( - port: Int, - password: String, - hostname: String = "localhost", - username: String = "corda", - timeout: Duration = Duration.ofSeconds(4) - ): SSHClient { - val tty = SttySupport.parsePtyModes(TTY) - val client = SshClient.setUpDefaultClient() - client.start() - - log.info("Connecting to $hostname:$port ...") - val session = client - .connect(username, hostname, port) - .verify(timeout.seconds, TimeUnit.SECONDS) - .session - - log.info("Authenticating using password identity ...") - session.addPasswordIdentity(password) - val authFuture = session.auth().verify(timeout.seconds, TimeUnit.SECONDS) - - authFuture.addListener { - log.info("Authentication completed with " + if (it.isSuccess) "success" else "failure") - } - - val channel = session.createShellChannel() - channel.ptyModes = tty - - val outputStream = PipedOutputStream() - val channelIn = PipedInputStream(outputStream) - - val channelOut = PipedOutputStream() - val inputStream = PipedInputStream(channelOut) - - channel.`in` = channelIn - channel.out = channelOut - channel.err = ByteArrayOutputStream() - channel.open() - - return SSHClient(client, outputStream, inputStream, session, channel) - } - - private const val TTY = "speed 9600 baud; 36 rows; 180 columns;\n" + - "lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl\n" + - "\t-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo\n" + - "\t-extproc\n" + - "iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8\n" + - "\t-ignbrk brkint -inpck -ignpar -parmrk\n" + - "oflags: opost onlcr -oxtabs -onocr -onlret\n" + - "cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow\n" + - "\t-dtrflow -mdmbuf\n" + - "cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ;\n" + - "\teol2 = ; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;\n" + - "\tmin = 1; quit = ^\\; reprint = ^R; start = ^Q; status = ^T;\n" + - "\tstop = ^S; susp = ^Z; time = 0; werase = ^W;" - - private val UTF8 = charset("UTF-8") - - } - -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/Scenarios.kt b/experimental/behave/src/scenario/kotlin/Scenarios.kt deleted file mode 100644 index 5977c40cd9..0000000000 --- a/experimental/behave/src/scenario/kotlin/Scenarios.kt +++ /dev/null @@ -1,11 +0,0 @@ -import cucumber.api.CucumberOptions -import cucumber.api.junit.Cucumber -import org.junit.runner.RunWith - -@RunWith(Cucumber::class) -@CucumberOptions( - glue = ["net.corda.behave.scenarios"], - plugin = ["pretty"] -) -@Suppress("KDocMissingDocumentation") -class CucumberTest diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioRunner.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioRunner.kt deleted file mode 100644 index 4f811c8b90..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioRunner.kt +++ /dev/null @@ -1,60 +0,0 @@ -@file:JvmName("ScenarioRunner") - -package net.corda.behave.scenarios - -import joptsimple.OptionParser -import kotlin.system.exitProcess - -fun main(args: Array) { - val parser = OptionParser() - val featurePath = parser.accepts("path").withRequiredArg().required().ofType(String::class.java) - .describedAs("Path location of .feature specifications") - val glue = parser.accepts("glue").withOptionalArg().ofType(String::class.java) - .describedAs("location of additional step definitions, hooks and plugins") - .defaultsTo("net.corda.behave.scenarios") - val plugin = parser.accepts("plugin").withOptionalArg().ofType(String::class.java) - .describedAs("register additional plugins (see https://cucumber.io/docs/reference/jvm)") - .defaultsTo("pretty") - val tags = parser.accepts("tags").withOptionalArg().ofType(String::class.java) - .describedAs("only run scenarios marked as @") - val dryRun = parser.accepts("d") - - val options = try { - parser.parse(*args) - } catch (e: Exception) { - println(e.message) - printHelp(parser) - exitProcess(1) - } - - val cliArgs = listOf("--glue", - options.valueOf(glue), - "--plugin", - options.valueOf(plugin), - options.valueOf(featurePath)) + - (if (options.hasArgument("tags")) - listOf("--tags", options.valueOf(tags)) - else emptyList()) + - if (options.has(dryRun)) listOf("-d") else emptyList() - - println("Cucumber CLI scenario runner args: $cliArgs") - cucumber.api.cli.Main.main(cliArgs.toTypedArray()) -} - -private fun printHelp(parser: OptionParser) { - println(""" - Usage: ScenarioRunner [options] --path - - Examples: - ScenarioRunner -path - ScenarioRunner -path /.feature - ScenarioRunner -path /.feature:3:9 - - ScenarioRunner -path --plugin html --tags @qa - ScenarioRunner -path --plugin html --tags @compatibility - - Please refer to the Cucumber documentation https://cucumber.io/docs/reference/jvm for more info. - - """.trimIndent()) - parser.printHelpOn(System.out) -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt deleted file mode 100644 index d0422b934e..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/ScenarioState.kt +++ /dev/null @@ -1,85 +0,0 @@ -package net.corda.behave.scenarios - -import cucumber.api.java.After -import net.corda.behave.network.Network -import net.corda.behave.node.Node -import net.corda.core.messaging.CordaRPCOps -import org.assertj.core.api.Assertions.assertThat -import java.time.Duration - -class ScenarioState { - - private val nodes = mutableListOf() - - private var network: Network? = null - - fun fail(message: String) { - error(message) - } - - fun error(message: String, ex: Throwable? = null): T { - this.network?.signalFailure(message, ex) - if (ex != null) { - throw Exception(message, ex) - } else { - throw Exception(message) - } - } - - fun node(name: String): Node { - val network = network ?: error("Network is not running") - return network[nodeName(name)] ?: error("Node '$name' not found") - } - - fun nodeBuilder(name: String): Node.Builder { - return nodes.firstOrNull { it.name == nodeName(name) } ?: newNode(name) - } - - fun ensureNetworkIsRunning(timeout: Duration? = null) { - if (network != null) { - // Network is already running - return - } - val networkBuilder = Network.new() - for (node in nodes) { - networkBuilder.addNode(node) - } - network = networkBuilder.generate() - network?.start() - assertThat(network?.waitUntilRunning(timeout)).isTrue() - } - - inline fun withNetwork(action: ScenarioState.() -> T): T { - ensureNetworkIsRunning() - return action() - } - - inline fun withClient(nodeName: String, crossinline action: (CordaRPCOps) -> T): T { - withNetwork { - return node(nodeName).rpc { - action(it) - } - } - } - - @After - fun stopNetwork() { - val network = network ?: return - for (node in network) { - val matches = node.logOutput.find("\\[ERR") - if (matches.any()) { - fail("Found errors in the log for node '${node.config.name}': ${matches.first().filename}") - } - } - network.stop() - } - - private fun nodeName(name: String) = name - - private fun newNode(name: String): Node.Builder { - val builder = Node.new() - .withName(nodeName(name)) - nodes.add(builder) - return builder - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/StepsContainer.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/StepsContainer.kt deleted file mode 100644 index 73983a0542..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/StepsContainer.kt +++ /dev/null @@ -1,53 +0,0 @@ -package net.corda.behave.scenarios - -import cucumber.api.java8.En -import io.github.classgraph.ClassGraph -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.api.StepsProvider -import net.corda.behave.scenarios.steps.* -import net.corda.core.internal.objectOrNewInstance -import net.corda.core.internal.pooledScan -import net.corda.core.utilities.contextLogger - -@Suppress("KDocMissingDocumentation") -class StepsContainer(val state: ScenarioState) : En { - - companion object { - private val log = contextLogger() - - val stepsProviders: List by lazy { - ClassGraph() - .addClassLoader(this::class.java.classLoader) - .enableAllInfo() - .pooledScan() - .use { it.getClassesImplementing(StepsProvider::class.java.name).loadClasses(StepsProvider::class.java) } - .map { it.kotlin.objectOrNewInstance() } - } - } - - private val stepDefinitions: List = listOf( - CashSteps(), - ConfigurationSteps(), - DatabaseSteps(), - NetworkSteps(), - RpcSteps(), - SshSteps(), - StartupSteps(), - VaultSteps() - ) - - init { - log.info("Initialising common Steps Provider ...") - stepDefinitions.forEach { it.initialize(state) } - log.info("Searching and registering custom Steps Providers ...") - stepsProviders.forEach { stepsProvider -> - val stepsDefinition = stepsProvider.stepsDefinition - log.info("Registering: $stepsDefinition") - stepsDefinition.initialize(state) - } - } - - fun steps(action: (StepsContainer.() -> Unit)) { - action(this) - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsBlock.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsBlock.kt deleted file mode 100644 index cdb711b373..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsBlock.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.corda.behave.scenarios.api - -import cucumber.api.java8.En -import net.corda.behave.scenarios.ScenarioState -import net.corda.core.utilities.contextLogger - -interface StepsBlock : En { - - companion object { - val log = contextLogger() - } - - fun initialize(state: ScenarioState) - - fun succeed() = log.info("Step succeeded") -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsProvider.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsProvider.kt deleted file mode 100644 index fb72a0e951..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/api/StepsProvider.kt +++ /dev/null @@ -1,6 +0,0 @@ -package net.corda.behave.scenarios.api - -interface StepsProvider { - val name: String - val stepsDefinition: StepsBlock -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Cash.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Cash.kt deleted file mode 100644 index fbaec51f64..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Cash.kt +++ /dev/null @@ -1,65 +0,0 @@ -package net.corda.behave.scenarios.helpers - -import net.corda.behave.scenarios.ScenarioState -import net.corda.core.CordaRuntimeException -import net.corda.core.contracts.Amount -import net.corda.core.messaging.startFlow -import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.OpaqueBytes -import net.corda.core.utilities.getOrThrow -import net.corda.finance.flows.CashIssueFlow -import net.corda.finance.flows.CashPaymentFlow -import net.corda.finance.internal.CashConfigDataFlow -import java.util.* -import java.util.concurrent.TimeUnit - -class Cash(state: ScenarioState) : Substeps(state) { - - fun numberOfIssuableCurrencies(nodeName: String): Int { - return withClient(nodeName) { - try { - val config = it.startFlow(::CashConfigDataFlow).returnValue.get(10, TimeUnit.SECONDS) - for (supportedCurrency in config.supportedCurrencies) { - log.info("Can use $supportedCurrency") - } - for (issuableCurrency in config.issuableCurrencies) { - log.info("Can issue $issuableCurrency") - } - return@withClient config.issuableCurrencies.size - } catch (ex: Exception) { - log.warn("Failed to retrieve cash configuration data", ex) - throw ex - } - } - } - - fun issueCash(issueToNode: String, amount: Long, currency: String): SignedTransaction { - return withClient(issueToNode) { - try { - val notaryList = it.notaryIdentities() - if (notaryList.isEmpty()) - throw CordaRuntimeException("No Notaries configured in this network.") - val notaryParty = notaryList[0] - return@withClient it.startFlow(::CashIssueFlow, Amount(amount, Currency.getInstance(currency)), OpaqueBytes.of(1), notaryParty).returnValue.getOrThrow().stx - } catch (ex: Exception) { - log.warn("Failed to issue $amount $currency cash to $issueToNode", ex) - throw ex - } - } - } - - fun transferCash(senderNode: String, sendToNode: String, amount: Long, currency: String): SignedTransaction { - return withClient(senderNode) { - try { - val sendToX500Name = node(sendToNode).config.cordaX500Name - val sendToParty = node(senderNode).rpc { - it.wellKnownPartyFromX500Name(sendToX500Name) ?: throw IllegalStateException("Unable to locate $sendToX500Name in Network Map Service") - } - return@withClient it.startFlow(::CashPaymentFlow, Amount(amount, Currency.getInstance(currency)), sendToParty).returnValue.getOrThrow().stx - } catch (ex: Exception) { - log.warn("Failed to transfer $amount cash from $senderNode to $sendToNode", ex) - throw ex - } - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Database.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Database.kt deleted file mode 100644 index b74c34b293..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Database.kt +++ /dev/null @@ -1,22 +0,0 @@ -package net.corda.behave.scenarios.helpers - -import net.corda.behave.await -import net.corda.behave.scenarios.ScenarioState -import net.corda.core.utilities.seconds -import org.assertj.core.api.Assertions.assertThat -import java.util.concurrent.CountDownLatch - -class Database(state: ScenarioState) : Substeps(state) { - - fun canConnectTo(nodeName: String) { - withNetwork { - val latch = CountDownLatch(1) - log.info("Connecting to the database of node '$nodeName' ...") - node(nodeName).database.use { - log.info("Connected to the database of node '$nodeName'") - latch.countDown() - } - assertThat(latch.await(10.seconds)).isTrue() - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Ssh.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Ssh.kt deleted file mode 100644 index 7bf9eb4bf6..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Ssh.kt +++ /dev/null @@ -1,42 +0,0 @@ -package net.corda.behave.scenarios.helpers - -import net.corda.behave.scenarios.ScenarioState -import org.assertj.core.api.Assertions.assertThat -import rx.observers.TestSubscriber -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit - -class Ssh(state: ScenarioState) : Substeps(state) { - - fun canConnectTo(nodeName: String) { - withNetwork { - log.info("Connecting to node '$nodeName' over SSH ...") - hasSshStartupMessage(nodeName) - val latch = CountDownLatch(1) - val subscriber = TestSubscriber() - node(nodeName).ssh { - it.output.subscribe(subscriber) - assertThat(subscriber.onNextEvents).isNotEmpty - log.info("Successfully connect to node '$nodeName' over SSH") - latch.countDown() - } - if (!latch.await(15, TimeUnit.SECONDS)) { - fail("Failed to connect to node '$nodeName' over SSH") - } - } - } - - private fun hasSshStartupMessage(nodeName: String) { - var i = 5 - while (i > 0) { - Thread.sleep(2000) - if (state.node(nodeName).logOutput.find(".*SSH server listening on port.*").any()) { - break - } - i -= 1 - } - if (i == 0) { - state.fail("Unable to find SSH start-up message for node $nodeName") - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt deleted file mode 100644 index 1d07392b63..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt +++ /dev/null @@ -1,113 +0,0 @@ -package net.corda.behave.scenarios.helpers - -import net.corda.behave.process.JarCommand -import net.corda.behave.scenarios.ScenarioState -import net.corda.core.internal.div -import net.corda.core.utilities.minutes - -class Startup(state: ScenarioState) : Substeps(state) { - - fun hasLoggingInformation(nodeName: String) { - withNetwork { - log.info("Retrieving logging information for node '$nodeName' ...") - if (!node(nodeName).logOutput.find("Logs can be found in.*").any()) { - fail("Unable to find logging information for node $nodeName") - } - - withClient(nodeName) { - log.info("$nodeName: ${it.nodeInfo()} has registered flows:") - for (flow in it.registeredFlows()) { - log.info(flow) - } - } - } - } - - fun hasDatabaseDetails(nodeName: String) { - withNetwork { - log.info("Retrieving database details for node '$nodeName' ...") - if (!node(nodeName).logOutput.find("Database connection url is.*").any()) { - fail("Unable to find database details for node $nodeName") - } - } - } - - fun hasIdentityDetails(nodeName: String) { - withNetwork { - log.info("Retrieving identity details for node '$nodeName' ...") - try { - val nodeInfo = node(nodeName).rpc { it.nodeInfo() } - log.info("\nNode $nodeName identity details: $nodeInfo\n") - } catch (ex: Exception) { - log.warn("Failed to retrieve node identity details", ex) - throw ex - } - } - } - - fun hasPlatformVersion(nodeName: String, platformVersion: Int) { - withNetwork { - log.info("Finding platform version for node '$nodeName' ...") - val logOutput = node(nodeName).logOutput - if (!logOutput.find(".*Platform Version: $platformVersion .*").any()) { - val match = logOutput.find(".*Platform Version: .*").firstOrNull() - if (match == null) { - fail("Unable to find platform version for node '$nodeName'") - } else { - val foundVersion = Regex("Platform Version: (\\d+) ") - .find(match.contents) - ?.groups?.last()?.value - fail("Expected platform version $platformVersion for node '$nodeName', " + - "but found version $foundVersion") - - } - } - } - } - - fun hasVersion(nodeName: String, version: String) { - withNetwork { - log.info("Finding version for node '$nodeName' ...") - val logOutput = node(nodeName).logOutput - if (!logOutput.find(".*Release: $version .*").any()) { - val match = logOutput.find(".*Release: .*").firstOrNull() - if (match == null) { - fail("Unable to find version for node '$nodeName'") - } else { - val foundVersion = Regex("Release: ([^ ]+) ") - .find(match.contents) - ?.groups?.last()?.value - fail("Expected version $version for node '$nodeName', " + - "but found version $foundVersion") - - } - } - } - } - - fun hasLoadedCordapp(nodeName: String, cordappName: String) { - withNetwork { - log.info("Checking CorDapp $cordappName is loaded in node $nodeName ...\n") - val logOutput = node(nodeName).logOutput - if (!logOutput.find(".*Loaded CorDapps.*$cordappName.*").any()) { - fail("Unable to find $cordappName loaded in node $nodeName") - } - } - } - - fun runCordapp(nodeName: String, cordapp: String, vararg args: String) { - withNetwork { - val cordaApp = node(nodeName).config.cordapps.apps.find { it.contains(cordapp) } ?: fail("Unable to locate CorDapp: $cordapp") - // launch cordapp jar - // assumption is there is a Main() method declared in the manifest of the JAR - // eg. Main-Class: net.corda.notaryhealthcheck.MainKt - val cordappDirectory = node(nodeName).config.distribution.cordappDirectory - val cordappJar = cordappDirectory / "$cordapp.jar" - // Execute - val command = JarCommand(cordappJar, args, cordappDirectory, 1.minutes) - command.start() - if (!command.waitFor()) - fail("Failed to successfully run the CorDapp jar: $cordaApp") - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt deleted file mode 100644 index 6af97417eb..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Substeps.kt +++ /dev/null @@ -1,22 +0,0 @@ -package net.corda.behave.scenarios.helpers - -import net.corda.behave.scenarios.ScenarioState -import net.corda.core.messaging.CordaRPCOps -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -abstract class Substeps(protected val state: ScenarioState) { - protected val log: Logger = LoggerFactory.getLogger(javaClass) - - protected fun withNetwork(action: ScenarioState.() -> Unit) = state.withNetwork(action) - - protected fun withClient(nodeName: String, action: ScenarioState.(CordaRPCOps) -> T): T { - return state.withClient(nodeName) { - try { - action(state, it) - } catch (ex: Exception) { - state.error(ex.message ?: "Failed to execute RPC call") - } - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Vault.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Vault.kt deleted file mode 100644 index 8f9b96712a..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Vault.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.corda.behave.scenarios.helpers - -import net.corda.behave.scenarios.ScenarioState -import net.corda.core.contracts.ContractState -import net.corda.core.contracts.StateAndRef - -class Vault(state: ScenarioState) : Substeps(state) { - - fun query(nodeName: String, contractStateType: Class): List>{ - return withClient(nodeName) { - try { - val results = it.vaultQuery(contractStateType) - log.info("Vault query return results: $results") - return@withClient results.states - } catch (ex: Exception) { - log.warn("Failed to retrieve cash configuration data", ex) - throw ex - } - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/CashSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/CashSteps.kt deleted file mode 100644 index b2c3059511..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/CashSteps.kt +++ /dev/null @@ -1,37 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.helpers.Cash -import org.assertj.core.api.Assertions.assertThat - -class CashSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - val cash = Cash(state) - - Then("^node (\\w+) has 1 issuable currency$") { name -> - state.withNetwork { - assertThat(cash.numberOfIssuableCurrencies(name)).isEqualTo(1) - } - } - - Then("^node (\\w+) has (\\w+) issuable currencies$") { name, count -> - state.withNetwork { - assertThat(cash.numberOfIssuableCurrencies(name)).isEqualTo(count.toInt()) - } - } - - Then("^node (\\w+) can transfer (\\d+) (\\w+) to node (\\w+)$") { nodeA, amount, currency, nodeB -> - state.withNetwork { - cash.transferCash(nodeA, nodeB, amount, currency) - } - } - - Then("^node (\\w+) can issue (\\d+) (\\w+)$") { nodeA, amount, currency -> - state.withNetwork { - cash.issueCash(nodeA, amount, currency) - } - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/ConfigurationSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/ConfigurationSteps.kt deleted file mode 100644 index a50f92719a..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/ConfigurationSteps.kt +++ /dev/null @@ -1,65 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.database.DatabaseType -import net.corda.behave.node.Distribution -import net.corda.behave.node.configuration.toNotaryType -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock - -class ConfigurationSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - fun node(name: String) = state.nodeBuilder(name) - - Given("^a node (\\w+) of version ([^ ]+)$") { name, version -> - node(name) - .withDistribution(Distribution.fromVersionString(version)) - } - - Given("^a node (\\w+) in location (\\w+) and country (\\w+) of version ([^ ]+)$") { name, location, country, version -> - node(name) - .withDistribution(Distribution.fromVersionString(version)) - .withLocation(location.replace("_", " "), country) - } - - Given("^a (\\w+) notary node (\\w+) of version ([^ ]+)$") { notaryType, name, version -> - node(name) - .withDistribution(Distribution.fromVersionString(version)) - .withNotaryType(notaryType.toNotaryType() - ?: error("Unknown notary type '$notaryType'")) - } - - Given("^a (\\w+) notary (\\w+) of version ([^ ]+)$") { type, name, version -> - node(name) - .withDistribution(Distribution.fromVersionString(version)) - .withNotaryType(type.toNotaryType() - ?: error("Unknown notary type '$type'")) - } - - Given("^node (\\w+) uses database of type (.+)$") { name, type -> - node(name) - .withDatabaseType(DatabaseType.fromName(type) - ?: error("Unknown database type '$type'")) - } - - Given("^node (\\w+) can issue currencies of denomination (.+)$") { name, currencies -> - node(name).withIssuableCurrencies(currencies - .replace(" and ", ", ") - .split(", ") - .map { it.toUpperCase() }) - } - - Given("^node (\\w+) is located in (\\w+), (\\w+)$") { name, location, country -> - node(name).withLocation(location, country) - } - - Given("^node (\\w+) has the finance app installed$") { name -> - node(name).withFinanceApp() - } - - Given("^node (\\w+) has app installed: (.+)$") { name, app -> - node(name).withApp(app) - } - } -} - diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/DatabaseSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/DatabaseSteps.kt deleted file mode 100644 index a3deaf0670..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/DatabaseSteps.kt +++ /dev/null @@ -1,18 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.helpers.Database - -class DatabaseSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - val database = Database(state) - - Then("^user can connect to the database of node (\\w+)$") { name -> - state.withNetwork { - database.canConnectTo(name) - } - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/NetworkSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/NetworkSteps.kt deleted file mode 100644 index bf9a01642c..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/NetworkSteps.kt +++ /dev/null @@ -1,18 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.core.utilities.minutes - -class NetworkSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - When("^the network is ready$") { - state.ensureNetworkIsRunning() - } - - When("^the network is ready within (\\d+) minutes$") { minutes -> - state.ensureNetworkIsRunning(minutes.minutes) - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/RpcSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/RpcSteps.kt deleted file mode 100644 index 686e62b6d8..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/RpcSteps.kt +++ /dev/null @@ -1,15 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock - -class RpcSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - Then("^user can connect to node (\\w+) using RPC$") { name -> - state.withClient(name) { - succeed() - } - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/SshSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/SshSteps.kt deleted file mode 100644 index 0e4656b1a8..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/SshSteps.kt +++ /dev/null @@ -1,18 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.helpers.Ssh - -class SshSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - val ssh = Ssh(state) - - Then("^user can connect to node (\\w+) using SSH$") { name -> - state.withNetwork { - ssh.canConnectTo(name) - } - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/StartupSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/StartupSteps.kt deleted file mode 100644 index 73e7e37e5a..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/StartupSteps.kt +++ /dev/null @@ -1,66 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.helpers.Startup - -class StartupSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - val startup = Startup(state) - - Then("^user can retrieve database details for node (\\w+)$") { name -> - state.withNetwork { - startup.hasDatabaseDetails(name) - } - } - - Then("^user can retrieve logging information for node (\\w+)$") { name -> - state.withNetwork { - startup.hasLoggingInformation(name) - } - } - - Then("^node (\\w+) is on release version ([^ ]+)$") { name, version -> - state.withNetwork { - startup.hasVersion(name, version) - } - } - - Then("^node (\\w+) is on platform version (\\w+)$") { name, platformVersion -> - state.withNetwork { - startup.hasPlatformVersion(name, platformVersion.toInt()) - } - } - - Then("^user can retrieve node identity information for node (\\w+)") { name -> - state.withNetwork { - startup.hasIdentityDetails(name) - } - } - - Then("^node (\\w+) has loaded app (.+)$") { name, cordapp -> - state.withNetwork { - startup.hasLoadedCordapp(name, cordapp) - } - } - - Then("^node (\\w+) can run (\\w+)\$") { name, cordapp -> - state.withNetwork { - startup.runCordapp(name, cordapp) - } - } - - Then("^node (\\w+) can run (\\w+) (\\w+)\$") { name, cordapp, arg1 -> - state.withNetwork { - startup.runCordapp(name, cordapp, arg1) - } - } - - Then("^node (\\w+) can run (\\w+) (\\w+) (\\w+)\$") { name, cordapp, arg1, arg2 -> - state.withNetwork { - startup.runCordapp(name, cordapp, arg1, arg2) - } - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/VaultSteps.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/VaultSteps.kt deleted file mode 100644 index 0950e1a1e4..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/steps/VaultSteps.kt +++ /dev/null @@ -1,45 +0,0 @@ -package net.corda.behave.scenarios.steps - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.helpers.Vault -import net.corda.core.contracts.ContractState -import net.corda.core.internal.sumByLong -import net.corda.finance.contracts.asset.Cash - -class VaultSteps : StepsBlock { - - override fun initialize(state: ScenarioState) { - val vault = Vault(state) - - Then("^node (\\w+) vault contains (\\d+) states$") { node, count -> - if (vault.query(node, ContractState::class.java).size == count) - succeed() - else - state.fail("Vault on node $node does not contain expected number of states: $count") - } - - Then("^node (\\w+) vault contains (\\d+) (\\w+) states$") { node, count, contractType -> - try { - @Suppress("UNCHECKED_CAST") - val contractStateTypeClass = Class.forName(contractType) as Class - if (vault.query(node, contractStateTypeClass).size == count) - succeed() - else - state.fail("Vault on node $node does not contain expected number of states: $count") - } catch (e: Exception) { - state.fail("Invalid contract state class type: ${e.message}") - } - } - - Then("^node (\\w+) vault contains total cash of (\\d+) (\\w+)$") { node, total, currency -> - val cashStates = vault.query(node, Cash.State::class.java) - val sumCashStates = cashStates.filter { it.state.data.amount.token.product.currencyCode == currency }.sumByLong { it.state.data.amount.quantity } - print((sumCashStates)) - if (sumCashStates == total) - succeed() - else - state.fail("Vault on node $node does not contain total cash of : $total") - } - } -} diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/tests/StepsProviderTests.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/tests/StepsProviderTests.kt deleted file mode 100644 index 768eafd43a..0000000000 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/tests/StepsProviderTests.kt +++ /dev/null @@ -1,32 +0,0 @@ -package net.corda.behave.scenarios.tests - -import net.corda.behave.scenarios.ScenarioState -import net.corda.behave.scenarios.StepsContainer -import net.corda.behave.scenarios.api.StepsBlock -import net.corda.behave.scenarios.api.StepsProvider -import org.assertj.core.api.Assertions.assertThat -import org.junit.Test - -class StepsProviderTests { - - @Test - fun `module can discover steps providers`() { - - val foundProviders = StepsContainer.Companion.stepsProviders - assertThat(foundProviders).hasOnlyElementsOfType(FooStepsProvider::class.java).hasSize(1) - } - - class FooStepsProvider : StepsProvider { - - override val name: String - get() = "Foo" - - override val stepsDefinition: StepsBlock - get() = DummyStepsBlock() - } - - class DummyStepsBlock : StepsBlock { - override fun initialize(state: ScenarioState) { - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/scenario/resources/features/cash/currencies.feature b/experimental/behave/src/scenario/resources/features/cash/currencies.feature deleted file mode 100644 index 2b2ae5d285..0000000000 --- a/experimental/behave/src/scenario/resources/features/cash/currencies.feature +++ /dev/null @@ -1,35 +0,0 @@ -@cash @issuance -Feature: Cash - Issuable Currencies - To have cash on ledger, certain nodes must have the ability to issue cash of various currencies. - - Scenario Outline: Node can issue no currencies by default - Given a node PartyA of version - And node PartyA has the finance app installed - When the network is ready - Then node PartyA has 0 issuable currencies - - Examples: - | Node-Version | - | master | - - Scenario Outline: Node has an issuable currency - Given a node PartyA of version - And node PartyA can issue currencies of denomination USD - And node PartyA has the finance app installed - When the network is ready - Then node PartyA has 1 issuable currency - - Examples: - | Node-Version | - | master | - - Scenario Outline: Node can issue a currency - Given a node PartyA of version - And a nonvalidating notary Notary of version - And node PartyA has the finance app installed - When the network is ready - Then node PartyA can issue 100 USD - - Examples: - | Node-Version | - | master | diff --git a/experimental/behave/src/scenario/resources/features/database/connection.feature b/experimental/behave/src/scenario/resources/features/database/connection.feature deleted file mode 100644 index 6bbdf73c09..0000000000 --- a/experimental/behave/src/scenario/resources/features/database/connection.feature +++ /dev/null @@ -1,16 +0,0 @@ -@database @connectivity -Feature: Database - Connection - For Corda to work, a database must be running and appropriately configured. - - Scenario Outline: User can connect to node's database - Given a node PartyA of version - And node PartyA uses database of type - When the network is ready - Then user can connect to the database of node PartyA - - Examples: - | Node-Version | Database-Type | - | master | H2 | - -# To run this scenario using postgreSQL you must ensure that Docker is running locally -# | master | postgreSQL | \ No newline at end of file diff --git a/experimental/behave/src/scenario/resources/features/startup/logging.feature b/experimental/behave/src/scenario/resources/features/startup/logging.feature deleted file mode 100644 index ce4ef490ed..0000000000 --- a/experimental/behave/src/scenario/resources/features/startup/logging.feature +++ /dev/null @@ -1,34 +0,0 @@ -@logging @startup -Feature: Startup Information - Logging - A Corda node should inform the user of important parameters during startup so that he/she can confirm the setup and - configure / connect relevant software to said node. - - Scenario Outline: Node shows logging information on startup - Given a node PartyA of version - And node PartyA uses database of type - And node PartyA is located in London, GB - When the network is ready - Then user can retrieve logging information for node PartyA - - Examples: - | Node-Version | Database-Type | - | master | H2 | - - Scenario Outline: Node shows database details on startup - Given a node PartyA of version - And node PartyA uses database of type - When the network is ready - Then user can retrieve database details for node PartyA - - Examples: - | Node-Version | Database-Type | - | master | H2 | - - Scenario Outline: Node shows version information on startup - Given a node PartyA of version - Then node PartyA is on platform version - And node PartyA is on release version - - Examples: - | Node-Version | Platform-Version | Release-Version | - | master | 4 | corda-4.0-snapshot | diff --git a/experimental/behave/src/scenario/resources/log4j2.xml b/experimental/behave/src/scenario/resources/log4j2.xml deleted file mode 100644 index 43fcf63c3d..0000000000 --- a/experimental/behave/src/scenario/resources/log4j2.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/experimental/behave/src/scenario/resources/scripts/run-behave-features.sh b/experimental/behave/src/scenario/resources/scripts/run-behave-features.sh deleted file mode 100755 index e016d00107..0000000000 --- a/experimental/behave/src/scenario/resources/scripts/run-behave-features.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# -# Run this script from the experimental/behave directory -# -# $ pwd -# ./IdeaProjects/corda-reviews/experimental/behave -# $ src/scenario/resources/scripts/run-behave-features.sh -# -# Note: please ensure you have configured your staging environment by running the top-level script: prepare.sh - -BUILD_DIR=$PWD -cd ${BUILD_DIR} -../../gradlew behaveJar - -BEHAVE_JAR=$(ls build/libs/corda-behave-*.jar | tail -n1) -STAGING_ROOT=~/staging - -# startup -java -DSTAGING_ROOT=${STAGING_ROOT} -jar ${BEHAVE_JAR} --glue net.corda.behave.scenarios -path ./src/scenario/resources/features/startup/logging.feature - -# cash -java -DSTAGING_ROOT=${STAGING_ROOT} -jar ${BEHAVE_JAR} --glue net.corda.behave.scenarios -path ./src/scenario/resources/features/cash/currencies.feature - -# database -java -DSTAGING_ROOT=${STAGING_ROOT} -jar ${BEHAVE_JAR} --glue net.corda.behave.scenarios -path ./src/scenario/resources/features/cash/currencies.feature diff --git a/experimental/behave/src/test/kotlin/net/corda/behave/monitoring/MonitoringTests.kt b/experimental/behave/src/test/kotlin/net/corda/behave/monitoring/MonitoringTests.kt deleted file mode 100644 index 2f8869681f..0000000000 --- a/experimental/behave/src/test/kotlin/net/corda/behave/monitoring/MonitoringTests.kt +++ /dev/null @@ -1,63 +0,0 @@ -package net.corda.behave.monitoring - -import net.corda.core.utilities.seconds -import org.assertj.core.api.Assertions.assertThat -import org.junit.Test -import rx.Observable - -class MonitoringTests { - - @Test - fun `watch gets triggered when pattern is observed`() { - val observable = Observable.just("first", "second", "third") - val result = PatternWatch(observable, "c.n").await(1.seconds) - assertThat(result).isTrue() - } - - @Test - fun `watch does not get triggered when pattern is not observed`() { - val observable = Observable.just("first", "second", "third") - val result = PatternWatch(observable, "forth").await(1.seconds) - assertThat(result).isFalse() - } - - @Test - fun `conjunctive watch gets triggered when all its constituents match on the input`() { - val observable = Observable.just("first", "second", "third") - val watch1 = PatternWatch(observable, "fir") - val watch2 = PatternWatch(observable, "ond") - val watch3 = PatternWatch(observable, "ird") - val aggregate = watch1 * watch2 * watch3 - assertThat(aggregate.await(1.seconds)).isTrue() - } - - @Test - fun `conjunctive watch does not get triggered when one or more of its constituents do not match on the input`() { - val observable = Observable.just("first", "second", "third") - val watch1 = PatternWatch(observable, "fir") - val watch2 = PatternWatch(observable, "ond") - val watch3 = PatternWatch(observable, "baz") - val aggregate = watch1 * watch2 * watch3 - assertThat(aggregate.await(1.seconds)).isFalse() - } - - @Test - fun `disjunctive watch gets triggered when one or more of its constituents match on the input`() { - val observable = Observable.just("first", "second", "third") - val watch1 = PatternWatch(observable, "foo") - val watch2 = PatternWatch(observable, "ond") - val watch3 = PatternWatch(observable, "bar") - val aggregate = watch1 / watch2 / watch3 - assertThat(aggregate.await(1.seconds)).isTrue() - } - - @Test - fun `disjunctive watch does not get triggered when none its constituents match on the input`() { - val observable = Observable.just("first", "second", "third") - val watch1 = PatternWatch(observable, "foo") - val watch2 = PatternWatch(observable, "baz") - val watch3 = PatternWatch(observable, "bar") - val aggregate = watch1 / watch2 / watch3 - assertThat(aggregate.await(1.seconds)).isFalse() - } -} \ No newline at end of file diff --git a/experimental/behave/src/test/kotlin/net/corda/behave/network/NetworkTests.kt b/experimental/behave/src/test/kotlin/net/corda/behave/network/NetworkTests.kt deleted file mode 100644 index 11ddb590e2..0000000000 --- a/experimental/behave/src/test/kotlin/net/corda/behave/network/NetworkTests.kt +++ /dev/null @@ -1,41 +0,0 @@ -package net.corda.behave.network - -import net.corda.behave.database.DatabaseType -import net.corda.behave.node.configuration.NotaryType -import net.corda.core.utilities.seconds -import org.junit.Ignore -import org.junit.Test - -class NetworkTests { - - @Ignore - @Test - fun `network of two nodes can be spun up`() { - val network = Network - .new() - .addNode("Foo") - .addNode("Bar") - .generate() - network.use { - it.waitUntilRunning(30.seconds) - it.signal() - it.keepAlive(30.seconds) - } - } - - @Ignore - @Test - fun `network of three nodes and mixed databases can be spun up`() { - val network = Network - .new() - .addNode("Foo") - .addNode("Bar", databaseType = DatabaseType.POSTGRES) - .addNode("Baz", notaryType = NotaryType.NON_VALIDATING) - .generate() - network.use { - it.waitUntilRunning(30.seconds) - it.signal() - it.keepAlive(30.seconds) - } - } -} \ No newline at end of file diff --git a/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt b/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt deleted file mode 100644 index 88152420dd..0000000000 --- a/experimental/behave/src/test/kotlin/net/corda/behave/process/CommandTests.kt +++ /dev/null @@ -1,31 +0,0 @@ -package net.corda.behave.process - -import org.assertj.core.api.Assertions.assertThat -import org.junit.Test -import rx.observers.TestSubscriber - -class CommandTests { - @Test - fun `successful command returns zero`() { - val exitCode = Command(listOf("ls", "/")).run() - assertThat(exitCode).isEqualTo(0) - } - - @Test - fun `failed command returns non-zero`() { - val exitCode = Command(listOf("ls", "some-weird-path-that-does-not-exist")).run() - assertThat(exitCode).isNotEqualTo(0) - } - - @Test - fun `output stream for command can be observed`() { - val subscriber = TestSubscriber() - val exitCode = Command(listOf("ls", "/")).run(subscriber) { _, _ -> - subscriber.awaitTerminalEvent() - subscriber.assertCompleted() - subscriber.assertNoErrors() - assertThat(subscriber.onNextEvents).contains("bin", "etc", "var") - } - assertThat(exitCode).isEqualTo(0) - } -} \ No newline at end of file diff --git a/experimental/behave/src/test/kotlin/net/corda/behave/service/PostreSQLServiceTests.kt b/experimental/behave/src/test/kotlin/net/corda/behave/service/PostreSQLServiceTests.kt deleted file mode 100644 index a8d690afd0..0000000000 --- a/experimental/behave/src/test/kotlin/net/corda/behave/service/PostreSQLServiceTests.kt +++ /dev/null @@ -1,18 +0,0 @@ -package net.corda.behave.service - -import net.corda.behave.service.database.PostgreSQLService -import org.assertj.core.api.Assertions.assertThat -import org.junit.Ignore -import org.junit.Test - -class PostreSQLServiceTests { - - @Ignore - @Test - fun `postgres can be started and stopped`() { - val service = PostgreSQLService("test-postgres", 12345, "postgres") - val didStart = service.start() - service.stop() - assertThat(didStart).isTrue() - } -} \ No newline at end of file diff --git a/experimental/behave/src/test/resources/log4j2.xml b/experimental/behave/src/test/resources/log4j2.xml deleted file mode 100644 index 43fcf63c3d..0000000000 --- a/experimental/behave/src/test/resources/log4j2.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index d2589f6044..e5dddf8cd3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -28,7 +28,6 @@ include 'webserver' include 'webserver:webcapsule' include 'experimental' include 'experimental:avalanche' -include 'experimental:behave' include 'experimental:quasar-hook' include 'experimental:corda-utils' include 'experimental:nodeinfo'