CORDA-2672: Tidy up CorDapp deployments in samples. (#4815)

* CORDA-2672: Tidy up CorDapp deployments in samples.

* CORDA-2672: Refactor Attachment Demo.

* Remove Bank of Corda from Trader Demo.

* Configure SLF4J simple loggers, fix comments and documentation.
This commit is contained in:
Chris Rankin 2019-03-11 16:48:35 +00:00 committed by josecoll
parent b6fe3b2a81
commit dc83afb4de
37 changed files with 296 additions and 198 deletions

View File

@ -25,7 +25,7 @@ JAR will contain:
Build tools
-----------
In the instructions that follow, we assume you are using Gradle and the ``cordformation`` plugin to build your
In the instructions that follow, we assume you are using Gradle and the ``cordapp`` plugin to build your
CorDapp. You can find examples of building a CorDapp using these tools in the
`Kotlin CorDapp Template <https://github.com/corda/cordapp-template-kotlin>`_ and the
`Java CorDapp Template <https://github.com/corda/cordapp-template-java>`_.
@ -66,14 +66,17 @@ In certain cases, you may also wish to build against the unstable Master branch.
Corda dependencies
^^^^^^^^^^^^^^^^^^
The ``cordformation`` plugin adds two new gradle configurations:
The ``cordapp`` plugin adds three new gradle configurations:
* ``cordaCompile``, which extends ``compile``
* ``cordaRuntime``, which extends ``runtime``
* ``cordapp``, which extends ``compile``
``cordaCompile`` and ``cordaRuntime`` indicate dependencies that should not be included in the CorDapp JAR. These
configurations should be used for any Corda dependency (e.g. ``corda-core``, ``corda-node``) in order to prevent a
dependency from being included twice (once in the CorDapp JAR and once in the Corda JARs).
dependency from being included twice (once in the CorDapp JAR and once in the Corda JARs). The ``cordapp`` dependency
is for declaring a compile-time dependency on a "semi-fat" CorDapp JAR in the same way as ``cordaCompile``, except
that ``Cordformation`` will only deploy CorDapps contained within the ``cordapp`` configuration.
Here are some guidelines for Corda dependencies:
@ -81,15 +84,17 @@ Here are some guidelines for Corda dependencies:
``cordaCompile`` dependency, and ``net.corda:corda:$corda_release_version`` as a ``cordaRuntime`` dependency
* When building an RPC client that communicates with a node (e.g. a webserver), you should include
``net.corda:corda-rpc:$corda_release_version`` as a ``cordaCompile`` dependency
``net.corda:corda-rpc:$corda_release_version`` as a ``cordaCompile`` dependency.
* When you need to use the network bootstrapper to bootstrap a local network (e.g. when using ``Cordformation``), you
should include ``net.corda:corda-node-api:$corda_release_version`` as a ``cordaCompile`` dependency
should include ``net.corda:corda-node-api:$corda_release_version`` as either a ``cordaRuntime`` or a ``runtimeOnly``
dependency. You may also wish to include an implementation of SLF4J as a ``runtimeOnly`` dependency for the network
bootstrapper to use.
* To use Corda's test frameworks, add ``net.corda:corda-test-utils:$corda_release_version`` as a ``testCompile``
dependency. Never include ``corda-test-utils`` as a ``compile`` or ``cordaCompile`` dependency
dependency. Never include ``corda-test-utils`` as a ``compile`` or ``cordaCompile`` dependency.
* Any other Corda dependencies you need should be included as ``cordaCompile`` dependencies
* Any other Corda dependencies you need should be included as ``cordaCompile`` dependencies.
Here is an overview of the various Corda dependencies:
@ -107,7 +112,8 @@ Here is an overview of the various Corda dependencies:
* ``corda-jfx`` - JavaFX utilities with some Corda-specific models and utilities. Only use with JavaFX apps
* ``corda-mock`` - A small library of useful mocks. Use if the classes are useful to you
* ``corda-node`` - The Corda node. Do not depend on. Used only by the Corda fat JAR and indirectly in testing
frameworks
frameworks. (If your CorDapp _must_ depend on this for some reason then it should use the ``compileOnly``
configuration here - but please _don't_ do this if you can possibly avoid it!)
* ``corda-node-api`` - The node API. Required to bootstrap a local network
* ``corda-node-driver`` - Testing utility for programmatically starting nodes from JVM languages. Use for tests
* ``corda-rpc`` - The Corda RPC client library. Used when writing an RPC client
@ -312,7 +318,7 @@ Below is a sample CorDapp Gradle dependencies block. When building your own CorD
cordapp "net.corda:bank-of-corda-demo:1.0"
// Some other dependencies
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "junit:junit:$junit_version"

View File

@ -105,7 +105,7 @@ and if so, printed out.
.. container:: codeset
.. literalinclude:: ../../samples/attachment-demo/workflows/src/main/kotlin/net/corda/attachmentdemo/workflows/AttachmentDemo.kt
.. literalinclude:: ../../samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt
:language: kotlin
:start-after: DOCSTART 1
:end-before: DOCEND 1
@ -115,7 +115,7 @@ transaction and send it to the recipient node:
.. container:: codeset
.. literalinclude:: ../../samples/attachment-demo/workflows/src/main/kotlin/net/corda/attachmentdemo/workflows/AttachmentDemo.kt
.. literalinclude:: ../../samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt
:language: kotlin
:start-after: DOCSTART 2
:end-before: DOCEND 2

View File

@ -1,17 +1,68 @@
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
description 'Corda attachment demo'
cordapp {
info {
name "Corda Attachment Demo"
vendor "R3"
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
}
}
sourceSets {
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/kotlin')
}
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version"
compile "javax.servlet:javax.servlet-api:3.1.0"
compile "javax.ws.rs:javax.ws.rs-api:2.0.1"
cordaCompile project(':client:rpc')
// Cordformation needs a SLF4J implementation when executing the Network
// Bootstrapper, but Log4J doesn't shutdown completely from within Gradle.
// Use a much simpler SLF4J implementation here instead.
runtimeOnly "org.slf4j:slf4j-simple:$slf4j_version"
// Corda integration dependencies
cordaRuntime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
cordaRuntime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
cordapp project(':samples:attachment-demo:contracts')
cordapp project(':samples:attachment-demo:workflows')
testCompile(project(':node-driver')) {
// We already have a SLF4J implementation on our runtime classpath,
// and we don't need another one.
exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
}
testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:$assertj_version"
integrationTestCompile project(':webserver')
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
def nodeTask = tasks.getByPath(':node:capsule:assemble')
@ -25,7 +76,6 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask,
"InvokeRpc.internalVerifiedTransactionsFeed",
"InvokeRpc.startTrackedFlowDynamic"]]]
directory "./build/nodes"
nodeDefaults {
projectCordapp {
deploy = false
@ -70,16 +120,16 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask,
}
}
task runSender(type: JavaExec) {
task runSender(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.attachmentdemo.workflows.AttachmentDemoKt'
main = 'net.corda.attachmentdemo.AttachmentDemoKt'
args '--role'
args 'SENDER'
}
task runRecipient(type: JavaExec) {
task runRecipient(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.attachmentdemo.workflows.AttachmentDemoKt'
main = 'net.corda.attachmentdemo.AttachmentDemoKt'
args '--role'
args 'RECIPIENT'
}

View File

@ -1,7 +1,5 @@
package net.corda.attachmentdemo
import net.corda.attachmentdemo.workflows.recipient
import net.corda.attachmentdemo.workflows.sender
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.Permissions.Companion.all

View File

@ -1,28 +1,19 @@
package net.corda.attachmentdemo.workflows
package net.corda.attachmentdemo
import co.paralleluniverse.fibers.Suspendable
import joptsimple.OptionParser
import net.corda.attachmentdemo.contracts.ATTACHMENT_PROGRAM_ID
import net.corda.attachmentdemo.contracts.AttachmentContract
import net.corda.attachmentdemo.workflows.AttachmentDemoFlow
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.crypto.SecureHash
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.internal.Emoji
import net.corda.core.internal.InputStreamAndHash
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startTrackedFlow
import net.corda.core.node.StatesToRecord
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.getOrThrow
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.jar.JarInputStream
import javax.servlet.http.HttpServletResponse.SC_OK
import javax.ws.rs.core.HttpHeaders.CONTENT_DISPOSITION
@ -92,51 +83,6 @@ private fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.
}
// DOCEND 2
@InitiatingFlow
@StartableByRPC
class AttachmentDemoFlow(private val otherSide: Party,
private val notary: Party,
private val attachId: SecureHash.SHA256) : FlowLogic<SignedTransaction>() {
object SIGNING : ProgressTracker.Step("Signing transaction")
override val progressTracker: ProgressTracker = ProgressTracker(SIGNING)
@Suspendable
override fun call(): SignedTransaction {
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
val ptx = TransactionBuilder(notary)
.addOutputState(AttachmentContract.State(attachId), ATTACHMENT_PROGRAM_ID)
.addCommand(AttachmentContract.Command, ourIdentity.owningKey)
.addAttachment(attachId)
progressTracker.currentStep = SIGNING
val stx = serviceHub.signInitialTransaction(ptx)
// Send the transaction to the other recipient
return subFlow(FinalityFlow(stx, initiateFlow(otherSide)))
}
}
@InitiatedBy(AttachmentDemoFlow::class)
class StoreAttachmentFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
// As a non-participant to the transaction we need to record all states
subFlow(ReceiveFinalityFlow(otherSide, statesToRecord = StatesToRecord.ALL_VISIBLE))
}
}
@StartableByRPC
@StartableByService
class NoProgressTrackerShellDemo : FlowLogic<String>() {
@Suspendable
override fun call(): String {
return "You Called me!"
}
}
@Suppress("DEPRECATION")
// DOCSTART 1
fun recipient(rpc: CordaRPCOps, webPort: Int) {
@ -159,7 +105,7 @@ fun recipient(rpc: CordaRPCOps, webPort: Int) {
// Write out the entries inside this jar.
println("Attachment JAR contains these entries:")
JarInputStream(connection.inputStream).use { it ->
JarInputStream(connection.inputStream).use {
while (true) {
val e = it.nextJarEntry ?: break
println("Entry> ${e.name}")

View File

@ -0,0 +1,3 @@
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z

View File

@ -5,34 +5,12 @@ apply plugin: 'net.corda.plugins.cordapp'
description 'Corda attachment demo - workflows'
sourceSets {
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/kotlin')
}
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
// Corda integration dependencies
cordaCompile project(':core')
cordaCompile project(':webserver')
cordapp project(':samples:attachment-demo:contracts')
testCompile project(':node-driver')
testCompile "junit:junit:$junit_version"
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
idea {

View File

@ -0,0 +1,57 @@
package net.corda.attachmentdemo.workflows
import co.paralleluniverse.fibers.Suspendable
import net.corda.attachmentdemo.contracts.ATTACHMENT_PROGRAM_ID
import net.corda.attachmentdemo.contracts.AttachmentContract
import net.corda.core.crypto.SecureHash
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.node.StatesToRecord
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker
@InitiatingFlow
@StartableByRPC
class AttachmentDemoFlow(private val otherSide: Party,
private val notary: Party,
private val attachId: SecureHash.SHA256) : FlowLogic<SignedTransaction>() {
object SIGNING : ProgressTracker.Step("Signing transaction")
override val progressTracker: ProgressTracker = ProgressTracker(SIGNING)
@Suspendable
override fun call(): SignedTransaction {
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
val ptx = TransactionBuilder(notary)
.addOutputState(AttachmentContract.State(attachId), ATTACHMENT_PROGRAM_ID)
.addCommand(AttachmentContract.Command, ourIdentity.owningKey)
.addAttachment(attachId)
progressTracker.currentStep = SIGNING
val stx = serviceHub.signInitialTransaction(ptx)
// Send the transaction to the other recipient
return subFlow(FinalityFlow(stx, initiateFlow(otherSide)))
}
}
@InitiatedBy(AttachmentDemoFlow::class)
class StoreAttachmentFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
// As a non-participant to the transaction we need to record all states
subFlow(ReceiveFinalityFlow(otherSide, statesToRecord = StatesToRecord.ALL_VISIBLE))
}
}
@StartableByRPC
@StartableByService
class NoProgressTrackerShellDemo : FlowLogic<String>() {
@Suspendable
override fun call(): String {
return "You Called me!"
}
}

View File

@ -3,7 +3,7 @@ apply plugin: 'idea'
apply plugin: 'net.corda.plugins.cordformation'
dependencies {
compile project(':node-api')
runtimeOnly project(':node-api')
runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
// Corda integration dependencies

View File

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Configuration status="info" shutdownHook="disable">
<!-- Configure Log4J2 for the Network Bootstrapper. -->
<Properties>
<Property name="log-path">logs</Property>
<Property name="log-name">node-${hostName}</Property>
<Property name="log-path">build/logs</Property>
<Property name="log-name">cordapp-${hostName}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>

View File

@ -1,7 +1,5 @@
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
dependencies {
cordaCompile project(':core')

View File

@ -1,14 +1,8 @@
package net.corda.configsample
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.Contract
import net.corda.core.contracts.ContractState
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.AbstractParty
import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.utilities.ProgressTracker
// DOCSTART 1

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>

View File

@ -17,14 +17,22 @@ sourceSets {
}
}
cordapp {
info {
name "Corda IRS Demo"
vendor "R3"
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
}
}
dependencies {
cordapp project(':finance:contracts')
cordapp project(':finance:workflows')
// Corda integration dependencies
cordaRuntime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
cordaCompile project(':core')
cordaRuntime project(':node-api')
runtimeOnly "org.slf4j:slf4j-simple:$slf4j_version"
cordapp project(':samples:irs-demo:cordapp:contracts-irs')
cordapp project(':samples:irs-demo:cordapp:workflows-irs')

View File

@ -0,0 +1,3 @@
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z

View File

@ -2,9 +2,23 @@ apply plugin: 'kotlin'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
cordapp {
info {
name "Corda Network Verifier"
vendor "R3"
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
}
}
dependencies {
cordaCompile project(':core')
cordaCompile project(':node-api')
// Cordformation needs this for the Network Bootstrapper.
runtimeOnly project(':node-api')
// Cordformation needs a SLF4J implementation when executing the Network
// Bootstrapper, but Log4J doesn't shutdown completely from within Gradle.
// Use a much simpler SLF4J implementation here instead.
runtimeOnly "org.slf4j:slf4j-simple:$slf4j_version"
// Corda integration dependencies
cordaRuntime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
@ -23,7 +37,6 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask])
cordapp project(':samples:network-verifier:contracts')
cordapp project(':samples:network-verifier:workflows')
}
directory "./build/nodes"
node {
name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : false]

View File

@ -0,0 +1,3 @@
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z

View File

@ -1,17 +1,29 @@
import net.corda.plugins.Cordform
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
cordapp {
info {
name "Corda Notary Demo"
vendor "R3"
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
cordaCompile project(':client:rpc')
// Corda integration dependencies
cordaRuntime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
cordaCompile project(':core')
// Cordformation needs a SLF4J implementation when executing the Network
// Bootstrapper, but Log4J doesn't shutdown completely from within Gradle.
// Use a much simpler SLF4J implementation here instead.
runtimeOnly "org.slf4j:slf4j-simple:$slf4j_version"
// Notary implementations
cordapp project(':samples:notary-demo:contracts')
@ -240,7 +252,7 @@ task deployNodesBFT(type: Cordform, dependsOn: ['jar', nodeTask, webTask]) {
}
}
task notarise(type: JavaExec) {
task notarise(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.notarydemo.NotariseKt'
main = 'net.corda.notarydemo.client.NotariseKt'
}

View File

@ -1,4 +1,4 @@
package net.corda.notarydemo
package net.corda.notarydemo.client
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.crypto.CompositeKey

View File

@ -0,0 +1,3 @@
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z

View File

@ -6,7 +6,11 @@ description 'Corda Notary Demo - Workflows'
dependencies {
cordaCompile project(':core')
cordaCompile project(':client:rpc')
cordaCompile project(':node')
// We need to compile against the Node, but also DO NOT
// want the Node bundled inside the CorDapp or added to
// Gradle's runtime classpath.
compileOnly project(':node')
cordapp project(':samples:notary-demo:contracts')
}

View File

@ -62,6 +62,11 @@ dependencies {
testCompile "org.assertj:assertj-core:$assertj_version"
}
jar {
// A CorDapp does not configure the Node's logging!
exclude "**/log4j2*.xml"
}
def nodeTask = tasks.getByPath(':node:capsule:assemble')
def webTask = tasks.getByPath(':webserver:webcapsule:assemble')
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask, webTask]) {

View File

@ -53,7 +53,7 @@ task shrink(type: ProGuardTask) {
libraryjars "$javaHome/lib/rt.jar"
libraryjars "$javaHome/lib/jce.jar"
configurations.runtime.forEach {
configurations.runtimeClasspath.forEach {
libraryjars it.path, filter: '!META-INF/versions/**'
}

View File

@ -3,28 +3,20 @@ package net.corda.vega
import com.opengamma.strata.product.common.BuySell
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.div
import net.corda.core.internal.packageName
import net.corda.core.utilities.getOrThrow
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.http.HttpApi
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import net.corda.testing.node.internal.findCordapp
import net.corda.vega.api.PortfolioApi
import net.corda.vega.api.PortfolioApiUtils
import net.corda.vega.api.SwapDataModel
import net.corda.vega.api.SwapDataView
import net.corda.vega.plugin.customserializers.CurrencyParameterSensitivitiesSerializer
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import java.math.BigDecimal
import java.time.LocalDate

View File

@ -2,8 +2,8 @@
<Configuration status="info">
<Properties>
<Property name="log-path">logs</Property>
<Property name="log-name">node-${hostName}</Property>
<Property name="log-path">build/logs</Property>
<Property name="log-name">simm-valuation-${hostName}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>

View File

@ -1,29 +1,71 @@
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
cordapp {
info {
name "Trader Demo"
vendor "R3"
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
}
}
sourceSets {
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/kotlin')
}
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "net.sf.jopt-simple:jopt-simple:$jopt_simple_version"
cordaCompile project(':client:rpc')
// Cordformation needs a SLF4J implementation when executing the Network
// Bootstrapper, but Log4J doesn't shutdown completely from within Gradle.
// Use a much simpler SLF4J implementation here instead.
runtimeOnly "org.slf4j:slf4j-simple:$slf4j_version"
// We only need this for its DUMMY_BANK constants, and
// DO NOT want it added to Gradle's runtime classpath.
compileOnly project(':test-utils')
// The trader demo CorDapp depends upon Cash CorDapp features
cordapp project(':finance:contracts')
cordapp project(':finance:workflows')
cordapp project(':samples:bank-of-corda-demo')
cordapp project(':samples:trader-demo:workflows-trader')
// Corda integration dependencies
cordaRuntime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
cordaRuntime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
testCompile project(':test-utils')
testCompile(project(':node-driver')) {
// We already have a SLF4J implementation on our runtime classpath,
// and we don't need another one.
exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
}
testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:${assertj_version}"
testCompile "org.assertj:assertj-core:$assertj_version"
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
def nodeTask = tasks.getByPath(':node:capsule:assemble')
def webTask = tasks.getByPath(':webserver:webcapsule:assemble')
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask, webTask]) {
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask]) {
ext.rpcUsers = [['username': "demo", 'password': "demo", 'permissions': ["ALL"]]]
nodeDefaults {
projectCordapp {
@ -33,7 +75,6 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar', nodeTask,
cordapp project(':finance:contracts')
cordapp project(':samples:trader-demo:workflows-trader')
}
directory "./build/nodes"
node {
name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : true]
@ -96,15 +137,15 @@ idea {
}
}
task runBank(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
task runBank(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.test.runtimeClasspath
main = 'net.corda.traderdemo.TraderDemoKt'
args '--role'
args 'BANK'
}
task runSeller(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
task runSeller(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.test.runtimeClasspath
main = 'net.corda.traderdemo.TraderDemoKt'
args '--role'
args 'SELLER'

View File

@ -39,7 +39,7 @@ class TraderDemoTest {
driver(DriverParameters(
startNodesInProcess = true,
inMemoryDB = false,
cordappsForAllNodes = FINANCE_CORDAPPS + TestCordapp.findCordapp("net.corda.traderdemo")
cordappsForAllNodes = FINANCE_CORDAPPS + TestCordapp.findCordapp("net.corda.traderdemo.flow")
)) {
val (nodeA, nodeB, bankNode) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)),
@ -71,11 +71,14 @@ class TraderDemoTest {
assertThat(clientB.cashCount).isEqualTo(expectedBCash)
// Wait until A receives the commercial paper
val executor = Executors.newScheduledThreadPool(1)
poll(executor, "A to be notified of the commercial paper", pollInterval = 100.millis) {
val actualPaper = listOf(clientA.commercialPaperCount, clientB.commercialPaperCount)
if (actualPaper == expectedPaper) Unit else null
}.getOrThrow()
executor.shutdown()
try {
poll(executor, "A to be notified of the commercial paper", pollInterval = 100.millis) {
val actualPaper = listOf(clientA.commercialPaperCount, clientB.commercialPaperCount)
if (actualPaper == expectedPaper) Unit else null
}.getOrThrow()
} finally {
executor.shutdownNow()
}
assertThat(clientA.dollarCashBalance).isEqualTo(95.DOLLARS)
assertThat(clientB.dollarCashBalance).isEqualTo(5.DOLLARS)
}
@ -86,7 +89,7 @@ class TraderDemoTest {
driver(DriverParameters(
startNodesInProcess = false,
inMemoryDB = false,
cordappsForAllNodes = FINANCE_CORDAPPS + TestCordapp.findCordapp("net.corda.traderdemo")
cordappsForAllNodes = FINANCE_CORDAPPS + TestCordapp.findCordapp("net.corda.traderdemo.flow")
)) {
val (buyer, seller, bank) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME),

View File

@ -0,0 +1,3 @@
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z

View File

@ -1,45 +1,18 @@
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'net.corda.plugins.cordapp'
sourceSets {
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/kotlin')
}
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
cordaCompile project(':core')
// The trader demo CorDapp depends upon Cash CorDapp features
cordapp project(':finance:contracts')
cordapp project(':finance:workflows')
cordapp project(':samples:bank-of-corda-demo')
// Corda integration dependencies
cordaCompile project(':core')
testCompile project(':test-utils')
testCompile project(':node-driver')
testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:${assertj_version}"
integrationTestCompile project(':finance:workflows')
integrationTestCompile project(':finance:contracts')
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
testCompile "org.assertj:assertj-core:$assertj_version"
}
jar {

View File

@ -7,7 +7,6 @@ import net.corda.core.internal.Emoji
import net.corda.core.transactions.SignedTransaction
import net.corda.finance.contracts.CommercialPaper
import net.corda.finance.workflows.getCashBalances
import net.corda.traderdemo.TransactionGraphSearch
@InitiatedBy(SellerFlow::class)
class LoggingBuyerFlow(private val otherSideSession: FlowSession) : BuyerFlow(otherSideSession) {

View File

@ -1,4 +1,4 @@
package net.corda.traderdemo
package net.corda.traderdemo.flow
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.ContractState

View File

@ -1,4 +1,4 @@
package net.corda.traderdemo
package net.corda.traderdemo.flow
import net.corda.core.contracts.CommandData
import net.corda.core.crypto.newSecureRandom

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<ThresholdFilter level="info"/>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout pattern="%date %highlight{%level %c{1}.%method - %msg%n}{INFO=white,WARN=red,FATAL=bright red}"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>