From 6fbc6a55cf1d59adacc03923cc6dfe9ceaffdfd7 Mon Sep 17 00:00:00 2001 From: Katelyn Baker Date: Mon, 12 Mar 2018 11:47:58 +0000 Subject: [PATCH 1/8] CORDA-1186 - Actually move annotation into core module, not just core namespace (#2789) --- .../net/corda/core/serialization/ConstructorForDeserialization.kt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {node-api => core}/src/main/kotlin/net/corda/core/serialization/ConstructorForDeserialization.kt (100%) diff --git a/node-api/src/main/kotlin/net/corda/core/serialization/ConstructorForDeserialization.kt b/core/src/main/kotlin/net/corda/core/serialization/ConstructorForDeserialization.kt similarity index 100% rename from node-api/src/main/kotlin/net/corda/core/serialization/ConstructorForDeserialization.kt rename to core/src/main/kotlin/net/corda/core/serialization/ConstructorForDeserialization.kt From 82786b3655d477a7800d4888d9f508e301c7ccad Mon Sep 17 00:00:00 2001 From: Katelyn Baker Date: Tue, 6 Mar 2018 17:06:30 +0000 Subject: [PATCH 2/8] CORDA-966 - RELEASE - Update version number to corda-4.0-snapshot --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a78020efbb..0d2d8ec9a4 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { file("$projectDir/constants.properties").withInputStream { constants.load(it) } // Our version: bump this on release. - ext.corda_release_version = "3.0-SNAPSHOT" + ext.corda_release_version = "corda-4.0-snapshot" // Increment this on any release that changes public APIs anywhere in the Corda platform ext.corda_platform_version = constants.getProperty("platformVersion") ext.gradle_plugins_version = constants.getProperty("gradlePluginsVersion") From 0e33ab7fdbc07fc0f8aa8cd4b9729ebe266a89f7 Mon Sep 17 00:00:00 2001 From: Katelyn Baker Date: Tue, 6 Mar 2018 17:12:49 +0000 Subject: [PATCH 3/8] CORDA-966 - RELEASE - Update static versions for V3 --- docs/source/_static/versions | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/_static/versions b/docs/source/_static/versions index b7932ed452..abeff3b667 100644 --- a/docs/source/_static/versions +++ b/docs/source/_static/versions @@ -10,5 +10,6 @@ "https://docs.corda.net/releases/release-M14.0": "M14.0", "https://docs.corda.net/releases/release-V1.0": "V1.0", "https://docs.corda.net/releases/release-V2.0": "V2.0", + "https://docs.corda.net/releases/release-V3.0": "V3.0", "https://docs.corda.net/head/": "Master" } From 2ecec9617ec8f3f95a76d1349242c42454fa7884 Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Tue, 13 Mar 2018 04:03:17 +0900 Subject: [PATCH 4/8] Adds demobench as an option for running nodes. Minor reorganisation. --- docs/source/running-a-node.rst | 48 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/source/running-a-node.rst b/docs/source/running-a-node.rst index e4d44e0726..1628f5ab52 100644 --- a/docs/source/running-a-node.rst +++ b/docs/source/running-a-node.rst @@ -8,29 +8,15 @@ Running nodes locally There are several ways to run a Corda node locally for testing purposes. -Starting all nodes at once --------------------------- - -.. note:: ``runnodes`` is a shell script (or batch file on Windows) that is generated by ``deployNodes`` to allow you - to quickly start up all nodes and their webservers. ``runnodes`` should only be used for testing purposes. - -Start the nodes with ``runnodes`` by running the following command from the root of the project: - -* Linux/macOS: ``build/nodes/runnodes`` -* Windows: ``call build\nodes\runnodes.bat`` - -.. warning:: On macOS, do not click/change focus until all the node terminal windows have opened, or some processes may - fail to start. - -If you receive an ``OutOfMemoryError`` exception when interacting with the nodes, you need to increase the amount of -Java heap memory available to them, which you can do when running them individually. See -:ref:`starting-an-individual-corda-node`. +Starting a Corda node using DemoBench +------------------------------------- +See the instructions in :doc:`demobench`. .. _starting-an-individual-corda-node: -Starting an individual Corda node ---------------------------------- -Run the node by opening a terminal window in the node's folder and running: +Starting a Corda node from the command line +------------------------------------------- +Run a node by opening a terminal window in the node's folder and running: .. code-block:: shell @@ -57,10 +43,28 @@ Optionally run the node's webserver as well by opening a terminal window in the .. warning:: The node webserver is for testing purposes only and will be removed soon. -Starting a node with remote debugging enabled ---------------------------------------------- +Enabling remote debugging +~~~~~~~~~~~~~~~~~~~~~~~~~ To enable remote debugging of the node, run the following from the terminal window: ``java -Dcapsule.jvm.args="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" -jar corda.jar`` This command line will start the debugger on port 5005 and pause the process awaiting debugger attachment. + +Starting all nodes at once from the command line +------------------------------------------------ +If you created your nodes using ``deployNodes``, a ``runnodes`` shell script (or batch file on Windows) will have been +generated to allow you to quickly start up all nodes and their webservers. ``runnodes`` should only be used for testing +purposes. + +Start the nodes with ``runnodes`` by running the following command from the root of the project: + +* Linux/macOS: ``build/nodes/runnodes`` +* Windows: ``call build\nodes\runnodes.bat`` + +.. warning:: On macOS, do not click/change focus until all the node terminal windows have opened, or some processes may + fail to start. + +If you receive an ``OutOfMemoryError`` exception when interacting with the nodes, you need to increase the amount of +Java heap memory available to them, which you can do when running them individually. See +:ref:`starting-an-individual-corda-node`. From d591ed59073fd804dd8b7c2c173f8c0dca757cc8 Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Tue, 13 Mar 2018 04:06:20 +0900 Subject: [PATCH 5/8] Update key-concepts-transactions.rst. --- docs/source/key-concepts-transactions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/key-concepts-transactions.rst b/docs/source/key-concepts-transactions.rst index 1e2c1ff836..b23219e4b9 100644 --- a/docs/source/key-concepts-transactions.rst +++ b/docs/source/key-concepts-transactions.rst @@ -105,7 +105,7 @@ will not be valid, and will not be accepted as inputs to subsequent transactions Other transaction components ---------------------------- -As well as input states and output states, transactions may contain: +As well as input states and output states, transactions contain: * Commands * Attachments @@ -178,4 +178,4 @@ In some cases, we want a transaction proposed to only be approved during a certa * A bond may only be redeemed before its expiry date In such cases, we can add a *time-window* to the transaction. Time-windows specify the time window during which the -transaction can be committed. We discuss time-windows in the section on :doc:`key-concepts-time-windows`. \ No newline at end of file +transaction can be committed. We discuss time-windows in the section on :doc:`key-concepts-time-windows`. From 568f7d7c17d5fc028793063e1234d050d64892b2 Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Tue, 13 Mar 2018 09:34:00 +0000 Subject: [PATCH 6/8] Documents limitations of calls to external resources in flows. --- docs/source/api-flows.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/api-flows.rst b/docs/source/api-flows.rst index 06357896ff..f36f1dec97 100644 --- a/docs/source/api-flows.rst +++ b/docs/source/api-flows.rst @@ -745,6 +745,12 @@ We then update the progress tracker's current step as we progress through the fl :end-before: DOCEND 18 :dedent: 12 +HTTP and database calls +----------------------- +HTTP, database and other calls to external resources are allowed in flows. However, their support is currently limited: + +* The call must be executed in a BLOCKING way. Flows don't currently support suspending to await the response to a call to an external resource +* The call must be idempotent. If the flow fails and has to restart from a checkpoint, the call will also be replayed Concurrency, Locking and Waiting -------------------------------- From 721728c8abc99c5ed7dc3fa1e6856c84c6c7b25a Mon Sep 17 00:00:00 2001 From: Thomas Schroeter Date: Tue, 13 Mar 2018 10:01:44 +0000 Subject: [PATCH 7/8] Terminate observables on RPC connection failures (#2770) --- .../net/corda/client/rpc/RPCStabilityTests.kt | 40 +++++++++++++++++++ .../rpc/internal/RPCClientProxyHandler.kt | 12 ++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt index 5025507f9c..d616f34bb3 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt @@ -316,6 +316,46 @@ class RPCStabilityTests { } } + interface NoOps : RPCOps { + fun subscribe(): Observable + } + + @Test + fun `observables error when connection breaks`() { + rpcDriver { + val ops = object : NoOps { + override val protocolVersion = 0 + override fun subscribe(): Observable { + return PublishSubject.create() + } + } + val serverFollower = shutdownManager.follower() + val serverPort = startRpcServer(ops = ops).getOrThrow().broker.hostAndPort!! + serverFollower.unfollow() + + val clientConfiguration = RPCClientConfiguration.default.copy(connectionRetryInterval = 500.millis, maxReconnectAttempts = 1) + val clientFollower = shutdownManager.follower() + val client = startRpcClient(serverPort, configuration = clientConfiguration).getOrThrow() + clientFollower.unfollow() + + var terminateHandlerCalled = false + var errorHandlerCalled = false + val subscription = client.subscribe() + .doOnTerminate{ terminateHandlerCalled = true } + .doOnError { errorHandlerCalled = true } + .subscribe() + + serverFollower.shutdown() + Thread.sleep(100) + + assertTrue(terminateHandlerCalled) + assertTrue(errorHandlerCalled) + assertTrue(subscription.isUnsubscribed) + + clientFollower.shutdown() // Driver would do this after the new server, causing hang. + } + } + interface ThreadOps : RPCOps { fun sendMessage(id: Int, msgNo: Int): String } diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt index f8cbc370ad..274dd63941 100644 --- a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt @@ -408,6 +408,14 @@ class RPCClientProxyHandler( when (event) { FailoverEventType.FAILURE_DETECTED -> { log.warn("RPC server unavailable. RPC calls are being buffered.") + log.warn("Terminating observables.") + val m = observableContext.observableMap.asMap() + m.keys.forEach { k -> + observationExecutorPool.run(k) { + m[k]?.onError(RPCException("Connection failure detected.")) + } + } + observableContext.observableMap.invalidateAll() } FailoverEventType.FAILOVER_COMPLETED -> { @@ -422,8 +430,6 @@ class RPCClientProxyHandler( "will throw an RPCException.") rpcReplyMap.forEach { id, replyFuture -> replyFuture.setException(RPCException("Could not re-connect to RPC server. Failover failed.")) - val observable = observableContext.observableMap.getIfPresent(id) - observable?.onError(RPCException("Could not re-connect to RPC server. Failover failed.")) } outgoingRequestBuffer.clear() rpcReplyMap.clear() @@ -507,4 +513,4 @@ object RpcClientObservableSerializer : Serializer>() { val rpcRequestOrObservableId = kryo.context[RPCApi.RpcRequestOrObservableIdKey] as InvocationId return observableContext.callSiteMap?.get(rpcRequestOrObservableId) } -} \ No newline at end of file +} From fae0dc0276e0f730b1e4e37bba50d2ecd28ea170 Mon Sep 17 00:00:00 2001 From: Michele Sollecito Date: Tue, 13 Mar 2018 14:51:55 +0000 Subject: [PATCH 8/8] [CORDA-1216]: Moved dependency on Jackson Databind from core to finance. (#2802) --- core/build.gradle | 2 -- finance/build.gradle | 9 +++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/core/build.gradle b/core/build.gradle index f3e24ed0ca..ab7f615c8a 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -105,8 +105,6 @@ dependencies { // This may be temporary until we experiment with other ways to do on-the-fly contract specialisation via an API. compile "org.apache.commons:commons-jexl3:3.0" compile 'commons-lang:commons-lang:2.6' - // For JSON - compile "com.fasterxml.jackson.core:jackson-databind:${jackson_version}" // Java ed25519 implementation. See https://github.com/str4d/ed25519-java/ compile "net.i2p.crypto:eddsa:$eddsa_version" diff --git a/finance/build.gradle b/finance/build.gradle index 662e7c9aa5..7180a5f9eb 100644 --- a/finance/build.gradle +++ b/finance/build.gradle @@ -29,6 +29,9 @@ dependencies { // TODO Remove this once we have app configs compile "com.typesafe:config:$typesafe_config_version" + // For JSON + compile "com.fasterxml.jackson.core:jackson-databind:${jackson_version}" + testCompile project(':test-utils') testCompile project(path: ':core', configuration: 'testArtifacts') testCompile "junit:junit:$junit_version" @@ -59,6 +62,12 @@ artifacts { jar { baseName 'corda-finance' + exclude "META-INF/*.DSA" + exclude "META-INF/*.RSA" + exclude "META-INF/*.SF" + exclude "META-INF/*.MF" + exclude "META-INF/LICENSE" + exclude "META-INF/NOTICE" } publish {