Example cordapp works on a corda cluster. Added getter methods for Data transfer objects, added default constructors.
This commit is contained in:
parent
a15efd43a1
commit
69f578a147
16
build.gradle
16
build.gradle
@ -45,6 +45,7 @@ cordapp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Declare the set of Kotlin compiler options we need to build a CorDapp.
|
// Declare the set of Kotlin compiler options we need to build a CorDapp.
|
||||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
@ -72,6 +73,19 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Declare the set of Kotlin compiler options we need to build a CorDapp.
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
|
||||||
|
// -parameters - Needed for reflection and serialization to work correctly.
|
||||||
|
options.compilerArgs += [
|
||||||
|
"-parameters"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// All dependencies are held in Maven Central
|
// All dependencies are held in Maven Central
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -134,7 +148,7 @@ test {
|
|||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
maven(MavenPublication) {
|
maven(MavenPublication) {
|
||||||
artifactId "corda-CSDE-kotlin-sample"
|
artifactId "corda-CSDE-java-sample"
|
||||||
groupId project.group
|
groupId project.group
|
||||||
artifact jar
|
artifact jar
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import com.r3.csde.CsdeRpcInterface
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java-library'
|
id 'java-library'
|
||||||
id 'checkstyle'
|
|
||||||
id 'groovy'
|
id 'groovy'
|
||||||
id 'java'
|
id 'java'
|
||||||
}
|
}
|
||||||
@ -37,7 +36,7 @@ def cordaJDBCDir = cordaBinDir + "/jdbcDrivers"
|
|||||||
def signingCertAlias="gradle-plugin-default-key"
|
def signingCertAlias="gradle-plugin-default-key"
|
||||||
// Get error if this is not a autotyped object
|
// Get error if this is not a autotyped object
|
||||||
// def signingCertFName = "$rootDir/config/gradle-plugin-default-key.pem"
|
// def signingCertFName = "$rootDir/config/gradle-plugin-default-key.pem"
|
||||||
def signingCertFName = rootDir.toString() + "/csde-config/gradle-plugin-default-key.pem"
|
def signingCertFName = rootDir.toString() + "/config/gradle-plugin-default-key.pem"
|
||||||
def keystoreAlias = "my-signing-key"
|
def keystoreAlias = "my-signing-key"
|
||||||
def keystoreFName = devEnvWorkspace + "/signingkeys.pfx"
|
def keystoreFName = devEnvWorkspace + "/signingkeys.pfx"
|
||||||
def keystoreCertFName = devEnvWorkspace + "/signingkey1.pem"
|
def keystoreCertFName = devEnvWorkspace + "/signingkey1.pem"
|
||||||
@ -82,7 +81,7 @@ tasks.register("createGroupPolicy") {
|
|||||||
doLast {
|
doLast {
|
||||||
|
|
||||||
def groupPolicyFName = new String("${devEnvWorkspace}/GroupPolicy.json")
|
def groupPolicyFName = new String("${devEnvWorkspace}/GroupPolicy.json")
|
||||||
def devnetFName = new String("$rootDir/csde-config/dev-net.json")
|
def devnetFName = new String("$rootDir/config/dev-net.json")
|
||||||
File groupPolicyFile = new File(groupPolicyFName)
|
File groupPolicyFile = new File(groupPolicyFName)
|
||||||
File devnetFile = new File(devnetFName)
|
File devnetFile = new File(devnetFName)
|
||||||
if (!groupPolicyFile.exists() || groupPolicyFile.lastModified() < devnetFile.lastModified()) {
|
if (!groupPolicyFile.exists() || groupPolicyFile.lastModified() < devnetFile.lastModified()) {
|
||||||
@ -128,7 +127,7 @@ tasks.register('createKeystore') {
|
|||||||
if(!keystoreFile.exists()) {
|
if(!keystoreFile.exists()) {
|
||||||
println('createKeystore: Create a keystore')
|
println('createKeystore: Create a keystore')
|
||||||
exec {
|
exec {
|
||||||
commandLine "keytool", "-genkeypair",
|
commandLine "${System.getProperty("java.home")}/bin/keytool", "-genkeypair",
|
||||||
"-alias", keystoreAlias,
|
"-alias", keystoreAlias,
|
||||||
"-keystore", keystoreFName,
|
"-keystore", keystoreFName,
|
||||||
"-storepass", "keystore password",
|
"-storepass", "keystore password",
|
||||||
@ -139,7 +138,7 @@ tasks.register('createKeystore') {
|
|||||||
}
|
}
|
||||||
// Need to add the default signing key to the keystore
|
// Need to add the default signing key to the keystore
|
||||||
exec {
|
exec {
|
||||||
commandLine "keytool", "-importcert",
|
commandLine "${System.getProperty("java.home")}/bin/keytool", "-importcert",
|
||||||
"-keystore", keystoreFName,
|
"-keystore", keystoreFName,
|
||||||
"-storepass", "keystore password",
|
"-storepass", "keystore password",
|
||||||
"-noprompt",
|
"-noprompt",
|
||||||
@ -148,7 +147,7 @@ tasks.register('createKeystore') {
|
|||||||
}
|
}
|
||||||
// keytool -exportcert -rfc -alias "signing key 1" -keystore signingkeys.pfx -storepass "keystore password" -file signingkey1.pem
|
// keytool -exportcert -rfc -alias "signing key 1" -keystore signingkeys.pfx -storepass "keystore password" -file signingkey1.pem
|
||||||
exec {
|
exec {
|
||||||
commandLine "keytool",
|
commandLine "${System.getProperty("java.home")}/bin/keytool",
|
||||||
"-exportcert", "-rfc", "-alias", keystoreAlias,
|
"-exportcert", "-rfc", "-alias", keystoreAlias,
|
||||||
"-keystore", keystoreFName,
|
"-keystore", keystoreFName,
|
||||||
"-storepass", "keystore password",
|
"-storepass", "keystore password",
|
||||||
|
@ -7,10 +7,19 @@ import net.corda.v5.base.types.MemberX500Name;
|
|||||||
//// to be able to send from one virtual node to another.
|
//// to be able to send from one virtual node to another.
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
public class Message {
|
public class Message {
|
||||||
Message(MemberX500Name _sender, String _message) {
|
// public Message() {}
|
||||||
sender = _sender;
|
public Message(MemberX500Name sender, String message) {
|
||||||
message = _message;
|
this.sender = sender;
|
||||||
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
public MemberX500Name getSender() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
public MemberX500Name sender;
|
public MemberX500Name sender;
|
||||||
public String message;
|
public String message;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
// to link the two sides of the flow together they need to have the same protocol.
|
// to link the two sides of the flow together they need to have the same protocol.
|
||||||
@InitiatingFlow(protocol = "another-flow")
|
@InitiatingFlow(protocol = "another-flow")
|
||||||
// MyFirstFlow should inherit from RPCStartableFlow, which tells Corda it can be started via an RPC call
|
// MyFirstFlow should inherit from RPCStartableFlow, which tells Corda it can be started via an RPC call
|
||||||
class MyFirstFlow implements RPCStartableFlow {
|
public class MyFirstFlow implements RPCStartableFlow {
|
||||||
|
|
||||||
// It is useful to be able to log messages from the flows for debugging.
|
// It is useful to be able to log messages from the flows for debugging.
|
||||||
private final Logger log = LoggerFactory.getLogger(MyFirstFlow.class);
|
private final Logger log = LoggerFactory.getLogger(MyFirstFlow.class);
|
||||||
@ -43,6 +43,7 @@ class MyFirstFlow implements RPCStartableFlow {
|
|||||||
// When a flow is invoked it's call() method is called.
|
// When a flow is invoked it's call() method is called.
|
||||||
// call() methods must be marked as @Suspendable, this allows Corda to pause mid-execution to wait
|
// call() methods must be marked as @Suspendable, this allows Corda to pause mid-execution to wait
|
||||||
// for a response from the other flows and services
|
// for a response from the other flows and services
|
||||||
|
@NotNull
|
||||||
@Suspendable
|
@Suspendable
|
||||||
@Override
|
@Override
|
||||||
public String call(@NotNull RPCRequestData requestBody) {
|
public String call(@NotNull RPCRequestData requestBody) {
|
||||||
@ -57,7 +58,7 @@ class MyFirstFlow implements RPCStartableFlow {
|
|||||||
MyFirstFlowStartArgs flowArgs = requestBody.getRequestBodyAs(jsonMarshallingService, MyFirstFlowStartArgs.class);
|
MyFirstFlowStartArgs flowArgs = requestBody.getRequestBodyAs(jsonMarshallingService, MyFirstFlowStartArgs.class);
|
||||||
|
|
||||||
// Obtain the MemberX500Name of counterparty
|
// Obtain the MemberX500Name of counterparty
|
||||||
MemberX500Name otherMember = flowArgs.othermember;
|
MemberX500Name otherMember = flowArgs.otherMember;
|
||||||
|
|
||||||
// Get our identity from the MemberLookup service.
|
// Get our identity from the MemberLookup service.
|
||||||
MemberX500Name ourIdentity = memberLookup.myInfo().getName();
|
MemberX500Name ourIdentity = memberLookup.myInfo().getName();
|
||||||
|
@ -15,7 +15,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
// to link the two sides of the flow together they need to have the same protocol.
|
// to link the two sides of the flow together they need to have the same protocol.
|
||||||
@InitiatedBy(protocol = "another-flow")
|
@InitiatedBy(protocol = "another-flow")
|
||||||
// Responder flows must inherit from ResponderFlow
|
// Responder flows must inherit from ResponderFlow
|
||||||
class MyFirstFlowResponder implements ResponderFlow {
|
public class MyFirstFlowResponder implements ResponderFlow {
|
||||||
|
|
||||||
// It is useful to be able to log messages from the flows for debugging.
|
// It is useful to be able to log messages from the flows for debugging.
|
||||||
private final Logger log = LoggerFactory.getLogger(MyFirstFlowResponder.class);
|
private final Logger log = LoggerFactory.getLogger(MyFirstFlowResponder.class);
|
||||||
|
@ -5,9 +5,17 @@ import net.corda.v5.base.types.MemberX500Name;
|
|||||||
// // A class to hold the arguments required to start the flow
|
// // A class to hold the arguments required to start the flow
|
||||||
//class MyFirstFlowStartArgs(val otherMember: MemberX500Name)
|
//class MyFirstFlowStartArgs(val otherMember: MemberX500Name)
|
||||||
public class MyFirstFlowStartArgs {
|
public class MyFirstFlowStartArgs {
|
||||||
public MemberX500Name othermember;
|
public MemberX500Name otherMember;
|
||||||
|
|
||||||
public MyFirstFlowStartArgs(MemberX500Name othermember) {
|
public MemberX500Name getOtherMember() {
|
||||||
this.othermember = othermember;
|
return otherMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MyFirstFlowStartArgs(MemberX500Name otherMember) {
|
||||||
|
this.otherMember = otherMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without the following we get
|
||||||
|
// "Cannot construct instance of `com.r3.developers.csdetemplate.MyFirstFlowStartArgs` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)\n at [Source: (String)\"{\"otherMember\":\"CN=Bob, OU=Test Dept, O=R3, L=London, C=GB\"}\"; line: 1, column: 2]"
|
||||||
|
public MyFirstFlowStartArgs() {}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.r3.developers.csdetemplate;
|
package com.r3.developers.csdetemplate;
|
||||||
|
|
||||||
|
|
||||||
import net.corda.simulator.HoldingIdentity;
|
import net.corda.simulator.HoldingIdentity;
|
||||||
import net.corda.simulator.RequestData;
|
import net.corda.simulator.RequestData;
|
||||||
import net.corda.simulator.SimulatedVirtualNode;
|
import net.corda.simulator.SimulatedVirtualNode;
|
||||||
@ -7,6 +8,7 @@ import net.corda.simulator.Simulator;
|
|||||||
import net.corda.v5.base.types.MemberX500Name;
|
import net.corda.v5.base.types.MemberX500Name;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
class MyFirstFlowTest {
|
class MyFirstFlowTest {
|
||||||
|
|
||||||
// Names picked to match the corda network in config/dev-net.json
|
// Names picked to match the corda network in config/dev-net.json
|
||||||
@ -45,3 +47,4 @@ class MyFirstFlowTest {
|
|||||||
assert(flowResponse.equals("Hello Alice, best wishes from Bob"));
|
assert(flowResponse.equals("Hello Alice, best wishes from Bob"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user