Skip to content
Three examples demonstrating three different approaches to using the Java ledger API bindings
Branch: master
Clone or download
gerolf-da Upgrade to SDK 0.12.17 (#3)
* Updated java packages for bindings-rxjava components
* Used `java.time.Instant`
Latest commit 22c8897 May 20, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
daml Copyright fix Mar 12, 2019
src/main Upgrade to SDK 0.12.17 (#3) May 20, 2019
.gitignore Copyright fix Mar 12, 2019
LICENSE Copyright fix Mar 12, 2019
README.rst Copyright fix Mar 12, 2019
da.yaml Upgrade to SDK 0.12.17 (#3) May 20, 2019
pom.xml Upgrade to SDK 0.12.17 (#3) May 20, 2019

README.rst

Java Bindings Example

Copyright (c) 2019, Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
SPDX-License-Identifier: Apache-2.0

This is an example of how a Java application would use the Java Binding library to connect to and exercise a DAML model running on a ledger. Since there are three levels of interface available, this example builds a similar application with all three levels.

The application is a simple PingPong application, which consists of:

  • a DAML model with two contract templates, Ping and Pong
  • two parties, Alice and Bob

The logic of the application is the following:

  1. The application injects a contract of type Ping for Alice.
  2. Alice sees this contract and exercises the consuming choice RespondPong to create a contract of type Pong for Bob.
  3. Bob sees this contract and exercises the consuming choice RespondPing to create a contract of type Ping for Alice.
  4. Points 1 and 2 are repeated until the maximum number of contracts defined in the DAML is reached.

Setting Up the Example Projects

To set a project up:

  1. Set the username and API Key for the Digital Asset repository in your settings.xml file as explained in Installing the SDK.

  2. Build the Java code with Maven by running:

    mvn compile
    
  3. Start the sandbox by running:

    da sandbox
    
  4. Run the applications by running the following command, specifying the main class:

    mvn exec:java \
        -Dexec.mainClass=<mainClass> \
        -Dexec.args="localhost 7600"
    
    where <mainClass> is one of:
    
    * examples.pingpong.grpc.PingPongGrpcMain
    * examples.pingpong.reactive.PingPongReactiveMain
    * examples.pingpong.components.PingPongComponentsMain
    
    depending on which example yuo wish to run
    

Example Project -- Ping Pong with gRPC Bindings

The code for this example is in the package examples.pingpong.grpc.

PingPongGrpcMain.java

The entry point for the Java code is the main class PingPongGrpcMain. Look at this class to see:

  • how to connect to and interact with the DAML Ledger via the Java Binding library
  • how to use the gRPC layer to build an automation for both parties.

The main function:

  • creates an instance of a ManagedChannel connecting to an existing ledger
  • fetches the ledgerID and packageId from the ledger
  • creates Identifiers for the Ping and Pong templates
  • creates and starts instances of PingPongProcessor that contain the logic of the automation
  • injects the initial contracts to start the process

PingPongProcessor.java

The core of the application is the method PingPongProcessor.runIndefinitely().

This method retrieves a gRPC streaming endpoint using the GetTransactionsRequest request, and then creates a RxJava StreamObserver, providing implementations of the onNext, onError and onComplete observer methods. RxJava arranges that these methods receive stream events asynchronously.

The method onNext is the main driver, extracting the transaction list from each GetTransactionResponse, and passing in to processTransaction() for processing. This method, and the method processTransaction() implents the application logic.

processTransaction() extracts all creation events from the the transaction and passes them to processEvent(). This produces a list of commands to be sent to the ledegr to further the workflow, and these are packages up in a Commands request and sent to the ledger.

processEvent() takes a transaction event and turns it into a stream of commands to be sent back to the ledger. To do this, it examines the event for the correct package and template (it's a create of a Ping or Pong template) and then looks at the receiving part to decide if this processor should respond. If so, an exercise command for the correct choice is created and returned in a Stream.

In all other cases, an empty Stream is returned, indication no action is required.

Output

The application prints statements similar to these:

Bob is exercising RespondPong on #1:0 in workflow Ping-Alice-1 at count 0
Alice is exercising RespondPing on #344:1 in workflow Ping-Alice-7 at count 9

The first line shows that:

  • Bob is exercising the RespondPong choice on the contract with ID #1:0 for the workflow Ping-Alice-1.
  • Count 0 means that this is the first choice after the initial Ping contract.
  • The workflow ID Ping-Alice-1 conveys that this is the workflow triggered by the second initial Ping contract that was created by Alice.

The second line is analogous to the first one.

Example Project -- Ping Pong without Reactive Components

The code for this example is in the package examples.pingpong.reactive.

PingPongReactiveMain.java

The entry point for the Java code is the main class PingPongReactiveMain. Look at this class to see:

  • how to connect to and interact with the DAML Ledger via the Java Binding library
  • how to use the Reactive layer to build an automation for both parties.

At high level, the code does the following steps:

  • creates an instance of DamlLedgerClient connecting to an existing Ledger
  • connect this instance to the Ledger with DamlLedgerClient.connect()
  • create two instances of PingPongProcessor, which contain the logic of the automation
  • run the PingPongProcessor forever by connecting them to the incoming transactions
  • inject some contracts for each party of both templates
  • wait until the application is done

PingPongProcessor.runIndefinitely()

The core of the application is the method PingPongProcessor.runIndefinitely().

The PingPongProcessor queries the transactions first via the TransactionsClient of the DamlLedgerClient. Then, for each transaction, it produces Commands that will be sent to the Ledger via the CommandSubmissionClient of the DamlLedgerClient.

Output

The application prints statements similar to these:

14:36:24.789 [client-1] INFO  e.p.reactive.PingPongProcessor - Bob is exercising RespondPong on #3136:0 in workflow Ping-Alice-1 at count 0
14:36:24.791 [client-0] INFO  e.p.reactive.PingPongProcessor - Alice is exercising RespondPing on #3139:1 in workflow Ping-Alice-0 at count 1

Example Project -- Ping Pong with Reactive Components

The code for this example is in the package examples.pingpong.components.

PingPongComponentsMain.java

The entry point for the Java code is the main class PingPongComponentsMain. Look at this class to see:

  • how to connect to and interact with the DAML Ledger via the Java Binding library
  • how to use the Reactive Components to build an automation for both parties

PingPongBot

At high level, this application follows the same steps as the one without Reactive Components except for the PingPongProcessor. In this application, the PingPongProcessor is replaced by the PingPongBot.

The PingPongBot has two important methods:

  • getContractInfo() which is used to get the information useful to the application from a created contract and the context
  • process() which implements the logic of the application by converting the local view of the Ledger into a stream of Commands

Output

The application prints statements similar to the ones seen in the section above.

The Underlying Library: RxJava

The Java Binding is RxJava, a library for composing asynchronous and event-based programs using observable sequences for the Java VM. It is part of the family of libraries called ReactiveX.

ReactiveX was chosen as the underlying library for the Java Binding because many services that the DAML Ledger offers are exposed as streams of events. So an application that wants to interact with the DAML Ledger must react to one or more DAML Ledger streams.

You can’t perform that action at this time.