diff --git a/build.gradle b/build.gradle index bd29e7b..ff011d9 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' // Include the cordapp-cpb plugin. This automatically includes the cordapp-cpk plugin as well. - // These extend existing build environment so that CPB and CPK files can be built. + // These extend the existing build environment so that CPB and CPK files can be built. // This includes a CorDapp DSL that allows the developer to supply metadata for the CorDapp // required by Corda. id 'net.corda.plugins.cordapp-cpb2' @@ -45,36 +45,6 @@ cordapp { } } -/* -// Declare the set of Kotlin compiler options we need to build a CorDapp. -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { - kotlinOptions { - allWarningsAsErrors = false - - // Specify the version of Kotlin that we are that we will be developing. - languageVersion = '1.7' - // Specify the Kotlin libraries that code is compatible with - apiVersion = '1.7' - // Note that we Need to use a version of Kotlin that will be compatible with the Corda API. - // Currently that is developed in Kotlin 1.7 so picking the same version ensures compatibility with that. - - // Specify the version of Java to target. - jvmTarget = javaVersion - - // Needed for reflection to work correctly. - javaParameters = true - - // -Xjvm-default determines how Kotlin supports default methods. - // JetBrains currently recommends developers use -Xjvm-default=all - // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-default/ - freeCompilerArgs += [ - "-Xjvm-default=all" - ] - } -} - - */ - // Declare the set of Kotlin compiler options we need to build a CorDapp. tasks.withType(JavaCompile) { @@ -84,8 +54,6 @@ tasks.withType(JavaCompile) { ] } - - repositories { // All dependencies are held in Maven Central mavenCentral() @@ -95,18 +63,11 @@ repositories { // A cordaProvided declaration is required for anything that we use that the Corda API provides. // This is required to allow us to build CorDapp modules as OSGi bundles that CPI and CPB files are built on. dependencies { - // We need a version of kotlin-stdlib-jdk8 built as an OSGi bundle, this is "kotlin-stdlib-jdk8-osgi". - // R3 builds kotlin-stdlib-jdk8-osgi from Kotlin's kotlin-stdlib-jdk8. - // NB: - // Kotlin's kotlin-osgi-bundle does not provide all of the Kotlin API that is required, - // There is no kotlin-stdlib-jdk11, but one is not needed even though we are targetting Java 11. - cordaProvided 'net.corda.kotlin:kotlin-stdlib-jdk8-osgi' - // Declare a "platform" so that we use the correct set of dependency versions for the version of the // Corda API specified. cordaProvided platform("net.corda:corda-api:$cordaApiVersion") - // If using transistive dependencies this will provide most of Corda-API: + // If using transistive dependencies this will provide most of the Corda-API: // cordaProvided 'net.corda:corda-application' // Alternatively we can explicitly specify all our Corda-API dependencies: @@ -135,9 +96,7 @@ dependencies { // Optional but used by exmaple tests. testImplementation "org.mockito:mockito-core:$mockitoVersion" - testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion" testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion" - } diff --git a/src/main/java/com/r3/developers/csdetemplate/Message.java b/src/main/java/com/r3/developers/csdetemplate/Message.java index a7109ef..4ca6092 100644 --- a/src/main/java/com/r3/developers/csdetemplate/Message.java +++ b/src/main/java/com/r3/developers/csdetemplate/Message.java @@ -3,15 +3,15 @@ package com.r3.developers.csdetemplate; import net.corda.v5.base.annotations.CordaSerializable; import net.corda.v5.base.types.MemberX500Name; -// // A class which will contain a message, It must be marked with @CordaSerializable for Corda -//// to be able to send from one virtual node to another. +// A class which will contain a message, It must be marked with @CordaSerializable for Corda +// to be able to send from one virtual node to another. @CordaSerializable public class Message { - // public Message() {} public Message(MemberX500Name sender, String message) { this.sender = sender; this.message = message; } + public MemberX500Name getSender() { return sender; } diff --git a/src/main/java/com/r3/developers/csdetemplate/MyFirstFlow.java b/src/main/java/com/r3/developers/csdetemplate/MyFirstFlow.java index 50d183a..21321c6 100644 --- a/src/main/java/com/r3/developers/csdetemplate/MyFirstFlow.java +++ b/src/main/java/com/r3/developers/csdetemplate/MyFirstFlow.java @@ -14,7 +14,7 @@ import org.slf4j.LoggerFactory; // MyFirstFlow is an initiating flow, it's corresponding responder flow is called MyFirstFlowResponder (defined below) // to link the two sides of the flow together they need to have the same protocol. -@InitiatingFlow(protocol = "another-flow") +@InitiatingFlow(protocol = "my-first-flow") // MyFirstFlow should inherit from RPCStartableFlow, which tells Corda it can be started via an RPC call public class MyFirstFlow implements RPCStartableFlow { @@ -26,27 +26,27 @@ public class MyFirstFlow implements RPCStartableFlow { // JsonMarshallingService provides a Service for manipulating json @CordaInject - JsonMarshallingService jsonMarshallingService; + public JsonMarshallingService jsonMarshallingService; // FlowMessaging provides a service for establishing flow sessions between Virtual Nodes and // sending and receiving payloads between them @CordaInject - FlowMessaging flowMessaging; + public FlowMessaging flowMessaging; // MemberLookup provides a service for looking up information about members of the Virtual Network which // this CorDapp is operating in. @CordaInject - MemberLookup memberLookup; + public MemberLookup memberLookup; public MyFirstFlow() {} - // When a flow is invoked it's call() method is called. + // When a flow is invoked its call() method is called. // 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 @NotNull @Suspendable @Override - public String call(@NotNull RPCRequestData requestBody) { + public String call(RPCRequestData requestBody) { // Useful logging to follow what's happening in the console or logs log.info("MFF: MyFirstFlow.call() called"); diff --git a/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowResponder.java b/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowResponder.java index 4e49f3b..d7fba74 100644 --- a/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowResponder.java +++ b/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowResponder.java @@ -11,9 +11,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// MyFirstFlowResponder is a responder flow, it's corresponding initiating flow is called MyFirstFlow (defined above) +// MyFirstFlowResponder is a responder flow, its corresponding initiating flow is called MyFirstFlow (defined in MyFirstFlow.java) // to link the two sides of the flow together they need to have the same protocol. -@InitiatedBy(protocol = "another-flow") +@InitiatedBy(protocol = "my-first-flow") // Responder flows must inherit from ResponderFlow public class MyFirstFlowResponder implements ResponderFlow { @@ -23,14 +23,14 @@ public class MyFirstFlowResponder implements ResponderFlow { // MemberLookup provides a service for looking up information about members of the Virtual Network which // this CorDapp is operating in. @CordaInject - MemberLookup memberLookup; + public MemberLookup memberLookup; public MyFirstFlowResponder() {} // Responder flows are invoked when an initiating flow makes a call via a session set up with the Virtual - // node hosting the Responder flow. When a responder flow is invoked it's call() method is called. + // node hosting the Responder flow. When a responder flow is invoked its call() method is called. // 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. // The Call method has the flow session passed in as a parameter by Corda so the session is available to // responder flow code, you don't need to inject the FlowMessaging service. @Suspendable diff --git a/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowStartArgs.java b/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowStartArgs.java index 1867875..4c5f2ff 100644 --- a/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowStartArgs.java +++ b/src/main/java/com/r3/developers/csdetemplate/MyFirstFlowStartArgs.java @@ -2,20 +2,14 @@ package com.r3.developers.csdetemplate; import net.corda.v5.base.types.MemberX500Name; -// // A class to hold the arguments required to start the flow -//class MyFirstFlowStartArgs(val otherMember: MemberX500Name) +// A class to hold the arguments required to start the flow public class MyFirstFlowStartArgs { public MemberX500Name otherMember; - public MemberX500Name getOtherMember() { - 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]" + // The JSON Marshalling Service, which handles serialisation, needs this constructor. public MyFirstFlowStartArgs() {} } diff --git a/src/test/java/com/r3/developers/csdetemplate/MyFirstFlowTest.java b/src/test/java/com/r3/developers/csdetemplate/MyFirstFlowTest.java index 1aa828f..e343318 100644 --- a/src/test/java/com/r3/developers/csdetemplate/MyFirstFlowTest.java +++ b/src/test/java/com/r3/developers/csdetemplate/MyFirstFlowTest.java @@ -1,6 +1,5 @@ package com.r3.developers.csdetemplate; - import net.corda.simulator.HoldingIdentity; import net.corda.simulator.RequestData; import net.corda.simulator.SimulatedVirtualNode; @@ -16,8 +15,8 @@ class MyFirstFlowTest { private MemberX500Name bobX500 = MemberX500Name.parse("CN=Bob, OU=Test Dept, O=R3, L=London, C=GB"); @Test + @SuppressWarnings("unchecked") public void test_that_MyFirstFLow_returns_correct_message() { - // Instantiate an instance of the Simulator Simulator simulator = new Simulator(); @@ -26,7 +25,7 @@ class MyFirstFlowTest { HoldingIdentity bobHoldingID = HoldingIdentity.Companion.create(bobX500); // Create Alice and Bob's virtual nodes, including the Class's of the flows which will be registered on each node. - // We don't assign Bob's virtual node to a val because we don't need it for this particular test. + // We don't assign Bob's virtual node to a variable because we don't need it for this particular test. SimulatedVirtualNode aliceVN = simulator.createVirtualNode(aliceHoldingID, MyFirstFlow.class); simulator.createVirtualNode(bobHoldingID, MyFirstFlowResponder.class); @@ -36,7 +35,7 @@ class MyFirstFlowTest { // Create a requestData object RequestData requestData = RequestData.Companion.create( "request no 1", // A unique reference for the instance of the flow request - MyFirstFlow.class, // The name of the flow class which is to be started + MyFirstFlow.class, // The name of the flow class which is to be started myFirstFlowStartArgs // The object which contains the start arguments of the flow );