From a51236aad362112adf7e78da17e72d07376b6e76 Mon Sep 17 00:00:00 2001 From: Marcin Ziolek Date: Mon, 9 Dec 2024 22:35:52 +0100 Subject: [PATCH 1/3] upgrade daml --- .gitignore | 2 +- LICENSE | 2 +- PingPong/README.rst | 4 ++-- PingPong/daml.yaml | 6 +++--- PingPong/daml/PingPong.daml | 2 +- PingPong/pom.xml | 4 ++-- .../pingpong/codegen/PingPongCodegenMain.java | 2 +- .../pingpong/codegen/PingPongProcessor.java | 2 +- .../pingpong/grpc/PingPongGrpcMain.java | 2 +- .../pingpong/grpc/PingPongProcessor.java | 2 +- .../pingpong/reactive/PingPongProcessor.java | 2 +- .../reactive/PingPongReactiveMain.java | 2 +- PingPong/src/main/resources/logback.xml | 2 +- PingPong/start.sh | 2 +- README.rst | 2 +- StockExchange/README.rst | 6 +++++- StockExchange/canton_ledger.conf | 21 +++++++++++++++++++ StockExchange/daml.yaml | 6 +++--- StockExchange/pom.xml | 4 ++-- StockExchange/setup.sh | 9 ++++++++ StockExchange/src/main/resources/logback.xml | 2 +- .../stock_exchange_bootstrap_script.canton | 10 ++++----- 22 files changed, 65 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 50e7ea6..a03eccf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Copyright (c) 2020, Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +# Copyright (c) 2024, Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. # SPDX-License-Identifier: Apache-2.0 lib/ diff --git a/LICENSE b/LICENSE index e731021..387d2f8 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2020 Digital Asset (Switzerland) GmbH and/or its affiliates + Copyright 2024 Digital Asset (Switzerland) GmbH and/or its affiliates Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/PingPong/README.rst b/PingPong/README.rst index 7ed125c..417b6a5 100644 --- a/PingPong/README.rst +++ b/PingPong/README.rst @@ -3,7 +3,7 @@ Java Bindings Ping-Pong Example :: - Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. SPDX-License-Identifier: Apache-2.0.0 @@ -31,7 +31,7 @@ To set a project up: #. If you do not have it already, install the DAML SDK by running:: - curl https://get.daml.com | sh -s 2.8.0 + curl https://get.daml.com | sh -s 2.10.0 #. Use the start script for starting a ledger & the java application: diff --git a/PingPong/daml.yaml b/PingPong/daml.yaml index 99a52b5..869daa8 100644 --- a/PingPong/daml.yaml +++ b/PingPong/daml.yaml @@ -1,11 +1,11 @@ -# Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +# Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -sdk-version: 2.7.0 +sdk-version: 2.10.0-snapshot.20241106.0 name: ex-java-bindings source: daml/PingPong.daml init-script: PingPong:setup -version: 0.0.2 +version: 1.0.0 dependencies: - daml-prim - daml-stdlib diff --git a/PingPong/daml/PingPong.daml b/PingPong/daml/PingPong.daml index 4512ef1..5c87727 100644 --- a/PingPong/daml/PingPong.daml +++ b/PingPong/daml/PingPong.daml @@ -1,4 +1,4 @@ --- Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +-- Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -- SPDX-License-Identifier: Apache-2.0 module PingPong where diff --git a/PingPong/pom.xml b/PingPong/pom.xml index 772092c..d3845f5 100644 --- a/PingPong/pom.xml +++ b/PingPong/pom.xml @@ -5,13 +5,13 @@ com.daml.ledger.examples example-ping-pong-java jar - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT UTF-8 11 11 - 2.7.0 + 2.10.0-snapshot.20241106.13056.0.v910c3af2 diff --git a/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java b/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java index 0431c3e..ae1c5ac 100644 --- a/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java +++ b/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package examples.pingpong.codegen; diff --git a/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java b/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java index de4e105..e6b120b 100644 --- a/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java +++ b/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package examples.pingpong.codegen; diff --git a/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java b/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java index aab2ebc..86eb15c 100644 --- a/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java +++ b/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package examples.pingpong.grpc; diff --git a/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java b/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java index 1c7785d..d7fac99 100644 --- a/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java +++ b/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package examples.pingpong.grpc; diff --git a/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java b/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java index 2c87105..1ddff9e 100644 --- a/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java +++ b/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package examples.pingpong.reactive; diff --git a/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java b/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java index 092be9d..f74d6a0 100644 --- a/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java +++ b/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package examples.pingpong.reactive; diff --git a/PingPong/src/main/resources/logback.xml b/PingPong/src/main/resources/logback.xml index 2ae760b..3801900 100644 --- a/PingPong/src/main/resources/logback.xml +++ b/PingPong/src/main/resources/logback.xml @@ -1,5 +1,5 @@ diff --git a/PingPong/start.sh b/PingPong/start.sh index fc34251..3d857c3 100755 --- a/PingPong/start.sh +++ b/PingPong/start.sh @@ -16,7 +16,7 @@ trap cleanup ERR EXIT echo "Compiling daml" daml build -packageId=$(daml damlc inspect-dar --json .daml/dist/ex-java-bindings-0.0.2.dar | jq '.main_package_id' -r) +packageId=$(daml damlc inspect-dar --json .daml/dist/ex-java-bindings-1.0.0.dar | jq '.main_package_id' -r) echo "Generating java code" diff --git a/README.rst b/README.rst index cf4fa95..dbefad3 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ Java Bindings Examples :: - Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. SPDX-License-Identifier: Apache-2.0.0 This repository contains two subprojects that demonstrate building of Daml client applications with the usage of Java Bindings: diff --git a/StockExchange/README.rst b/StockExchange/README.rst index 33b3499..87cbb34 100644 --- a/StockExchange/README.rst +++ b/StockExchange/README.rst @@ -3,7 +3,7 @@ Example of Explicit Disclosure with Java Bindings :: - Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. + Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. SPDX-License-Identifier: Apache-2.0.0 This project demonstrates the usage of `Explicit Contract Disclosure `_ @@ -50,6 +50,10 @@ Running the example start_canton +#. In the first terminal, upload the package to all participant nodes + + upload_package + #. In the first terminal, run the example run_stock_exchange diff --git a/StockExchange/canton_ledger.conf b/StockExchange/canton_ledger.conf index fff451b..c86fc06 100644 --- a/StockExchange/canton_ledger.conf +++ b/StockExchange/canton_ledger.conf @@ -4,21 +4,37 @@ canton { storage.type = memory admin-api.port = 5012 ledger-api.port = 5011 + parameters { + initial-protocol-version = 7 + dev-version-support = yes + } } bankParticipant { storage.type = memory admin-api.port = 5022 ledger-api.port = 5021 + parameters { + initial-protocol-version = 7 + dev-version-support = yes + } } buyerParticipant { storage.type = memory admin-api.port = 5032 ledger-api.port = 5031 + parameters { + initial-protocol-version = 7 + dev-version-support = yes + } } sellerParticipant { storage.type = memory admin-api.port = 5042 ledger-api.port = 5041 + parameters { + initial-protocol-version = 7 + dev-version-support = yes + } } } domains { @@ -26,8 +42,13 @@ canton { storage.type = memory public-api.port = 5018 admin-api.port = 5019 + init.domain-parameters.protocol-version=7 } } // enable ledger_api commands for setup simplicity of the Ledger API features.enable-testing-commands = yes + parameters { + non-standard-config = yes + dev-version-support = yes + } } diff --git a/StockExchange/daml.yaml b/StockExchange/daml.yaml index ab97dca..a3b5838 100644 --- a/StockExchange/daml.yaml +++ b/StockExchange/daml.yaml @@ -1,10 +1,10 @@ -# Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +# Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -sdk-version: 2.8.0 +sdk-version: 2.10.0-snapshot.20241106.0 name: ex-java-bindings-stock-exchange source: daml/StockExchange.daml -version: 0.0.1 +version: 1.0.0 dependencies: - daml-prim - daml-stdlib diff --git a/StockExchange/pom.xml b/StockExchange/pom.xml index ceac89f..94e1dc7 100644 --- a/StockExchange/pom.xml +++ b/StockExchange/pom.xml @@ -5,13 +5,13 @@ com.daml.ledger.examples example-stock-exchange-java jar - 0.0.1-SNAPSHOT + 1.0.0-SNAPSHOT UTF-8 11 11 - 2.8.0 + 2.10.0-snapshot.20241106.13056.0.v910c3af2 diff --git a/StockExchange/setup.sh b/StockExchange/setup.sh index d38e58c..27d216b 100755 --- a/StockExchange/setup.sh +++ b/StockExchange/setup.sh @@ -22,6 +22,15 @@ function start_canton() { fi } +function upload_package() { + version=${1:-"1.0.0"} + for port in 5011 5021 5031 5041 ; + do + daml ledger upload-dar --host localhost --port "${port}" .daml/dist/ex-java-bindings-stock-exchange-"${version}".dar + done + +} + function run_stock_exchange() { echo "Running StockExchange" stockExchangePartiesFile="temp_stock_exchange_example/stock_exchange_parties.txt" diff --git a/StockExchange/src/main/resources/logback.xml b/StockExchange/src/main/resources/logback.xml index 8e5bd40..f732342 100644 --- a/StockExchange/src/main/resources/logback.xml +++ b/StockExchange/src/main/resources/logback.xml @@ -1,5 +1,5 @@ diff --git a/StockExchange/stock_exchange_bootstrap_script.canton b/StockExchange/stock_exchange_bootstrap_script.canton index 3edc952..01019ad 100644 --- a/StockExchange/stock_exchange_bootstrap_script.canton +++ b/StockExchange/stock_exchange_bootstrap_script.canton @@ -21,15 +21,15 @@ val buyer = buyerParticipant.parties.enable("buyer") val seller = sellerParticipant.parties.enable("seller") // Write party ids to a file for allowing easy discovery -val partiesFileContent = s"${stockExchange.toPrim}\n${bank.toPrim}\n${buyer.toPrim}\n${seller.toPrim}" +val partiesFileContent = s"${stockExchange.toProtoPrimitive}\n${bank.toProtoPrimitive}\n${buyer.toProtoPrimitive}\n${seller.toProtoPrimitive}" Files.createDirectories(Paths.get("temp_stock_exchange_example")); Files.write(Paths.get("temp_stock_exchange_example/stock_exchange_parties.txt"), partiesFileContent.getBytes(StandardCharsets.UTF_8)) println("Waiting for the parties to appear on their hosting participants' Ledger API...") -utils.retry_until_true(buyerParticipant.ledger_api.parties.list().exists(_.party.toPrim.toString.startsWith("buyer::"))) -utils.retry_until_true(sellerParticipant.ledger_api.parties.list().exists(_.party.toPrim.toString.startsWith("seller::"))) -utils.retry_until_true(bankParticipant.ledger_api.parties.list().exists(_.party.toPrim.toString.startsWith("bank::"))) -utils.retry_until_true(stockExchangeParticipant.ledger_api.parties.list().exists(_.party.toPrim.toString.startsWith("stockExchange::"))) +utils.retry_until_true(buyerParticipant.ledger_api.parties.list().exists(_.party.toProtoPrimitive.toString.startsWith("buyer::"))) +utils.retry_until_true(sellerParticipant.ledger_api.parties.list().exists(_.party.toProtoPrimitive.toString.startsWith("seller::"))) +utils.retry_until_true(bankParticipant.ledger_api.parties.list().exists(_.party.toProtoPrimitive.toString.startsWith("bank::"))) +utils.retry_until_true(stockExchangeParticipant.ledger_api.parties.list().exists(_.party.toProtoPrimitive.toString.startsWith("stockExchange::"))) stockExchangeParticipant.ledger_api.users.create("StockExchange", actAs = Set(stockExchange), primaryParty = Some(stockExchange)) bankParticipant.ledger_api.users.create("Bank", actAs = Set(bank), primaryParty = Some(bank)) From b17485eb90ca9d97e3b5351dac8403dc755875b8 Mon Sep 17 00:00:00 2001 From: Marcin Ziolek Date: Mon, 9 Dec 2024 22:42:19 +0100 Subject: [PATCH 2/3] daml-lf 1.17 --- PingPong/daml.yaml | 4 +++- StockExchange/daml.yaml | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/PingPong/daml.yaml b/PingPong/daml.yaml index 869daa8..4dd7aa0 100644 --- a/PingPong/daml.yaml +++ b/PingPong/daml.yaml @@ -13,4 +13,6 @@ dependencies: codegen: java: package-prefix: examples.pingpong.codegen - output-directory: src/main/java/ \ No newline at end of file + output-directory: src/main/java/ +build-options: + - --target=1.17 \ No newline at end of file diff --git a/StockExchange/daml.yaml b/StockExchange/daml.yaml index a3b5838..8eaac67 100644 --- a/StockExchange/daml.yaml +++ b/StockExchange/daml.yaml @@ -12,3 +12,5 @@ codegen: java: package-prefix: examples.codegen output-directory: src/main/java/ +build-options: + - --target=1.17 \ No newline at end of file From a0ecb33a6d08b64f7ae9af1e96624a30ed7a0f1c Mon Sep 17 00:00:00 2001 From: Marcin Ziolek Date: Tue, 10 Dec 2024 13:06:14 +0100 Subject: [PATCH 3/3] :Make examples agnostic to versions --- PingPong/deploy.sh | 136 ++++++++++++++++++ .../pingpong/codegen/PingPongCodegenMain.java | 29 +--- .../pingpong/codegen/PingPongProcessor.java | 10 +- .../pingpong/grpc/IdentifierCreator.java | 47 ++++++ .../pingpong/grpc/PingPongGrpcMain.java | 45 ++---- .../pingpong/grpc/PingPongProcessor.java | 26 ++-- .../pingpong/reactive/IdentifierCreator.java | 47 ++++++ .../pingpong/reactive/PingPongProcessor.java | 14 +- .../reactive/PingPongReactiveMain.java | 20 ++- 9 files changed, 273 insertions(+), 101 deletions(-) create mode 100755 PingPong/deploy.sh create mode 100644 PingPong/src/main/java/examples/pingpong/grpc/IdentifierCreator.java create mode 100644 PingPong/src/main/java/examples/pingpong/reactive/IdentifierCreator.java diff --git a/PingPong/deploy.sh b/PingPong/deploy.sh new file mode 100755 index 0000000..b92ead8 --- /dev/null +++ b/PingPong/deploy.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +# Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# Use absolute paths to allow this script to be called from any location +root_dir=$(cd "$(dirname $0)"; pwd -P) + +clean () { + if [[ -d ${root_dir}/.dars ]]; then + rm -r ${root_dir}/.dars + fi +} + +build () { + daml build + + # Copy all package dars into a dedicated folder + mkdir -p ${root_dir}/.dars + cp ${root_dir}/.daml/dist/* ${root_dir}/.dars/ +} + +start () { + + mkdir -p ${root_dir}/temp + output_file=$(mktemp -p ${root_dir}/temp) + + pushd ${root_dir} > /dev/null || exit + daml sandbox > ${output_file} & + sandbox_pid=$! + popd > /dev/null || exit + + echo "Sandbox running with pid: ${sandbox_pid}" + tail -n0 -f ${output_file} | sed '/Canton sandbox is ready/ q' + + rm ${root_dir}/temp/* + + echo "${sandbox_pid}" > ${root_dir}/temp/pid +} + +dars() { + find ${root_dir}/.daml/dist -name "*${1}.dar" -exec daml ledger upload-dar --host localhost --port 6865 {} \; +} + +setup () { + pushd ${root_dir} > /dev/null || exit + script_name=$(yq e '.init-script' daml.yaml) + script_options=$(yq e '.script-options[]' daml.yaml | tr '\n' ' ') + dar_name="${root_dir}/.daml/dist/ex-java-bindings-${1}.dar" + if [ ! -f ${dar_name} ]; then + echo "Setup dar not found!" + fi + echo "Running the script: ${script_name}" + daml script --dar ${dar_name} --script-name ${script_name} --ledger-host localhost --ledger-port 6865 ${script_options} + popd > /dev/null || exit +} + +codegen() { + pushd ${root_dir} > /dev/null || exit + echo "Generating java code" + daml codegen java + echo "Compiling code" + mvn compile + popd > /dev/null || exit +} + +grpc() { + pushd ${root_dir} > /dev/null || exit + mvn exec:java -Dexec.mainClass=examples.pingpong.grpc.PingPongGrpcMain -Dpackage.id=$packageId -Dexec.args="localhost 6865" + popd > /dev/null || exit +} + +rx() { + pushd ${root_dir} > /dev/null || exit + mvn exec:java -Dexec.mainClass=examples.pingpong.reactive.PingPongReactiveMain -Dpackage.id=$packageId -Dexec.args="localhost 6865" + popd > /dev/null || exit +} + +cdg() { + pushd ${root_dir} > /dev/null || exit + mvn exec:java -Dexec.mainClass=examples.pingpong.codegen.PingPongCodegenMain -Dpackage.id=$packageId -Dexec.args="localhost 6865" + popd > /dev/null || exit +} + +stop () { + sandbox_pid=$(cat "${root_dir}/temp/pid") + echo "Stopping sandbox with pid: ${sandbox_pid}" + kill ${sandbox_pid} +} + +operation=${1} +extension=${2:-"1.0.0"} +packageId=$(daml damlc inspect-dar --json ${root_dir}/.daml/dist/ex-java-bindings-${extension}.dar | jq '.main_package_id' -r) + +case $operation in + start) + start + ;; + + stop) + stop + ;; + + build) + build + ;; + + dars) + dars ${extension} + ;; + + setup) + setup ${extension} + ;; + + codegen) + codegen + ;; + + grpc) + grpc + ;; + + rx) + rx + ;; + + cdg) + cdg + ;; + + up) + start + dars ${extension} + setup ${extension} + +esac diff --git a/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java b/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java index ae1c5ac..74ef1d5 100644 --- a/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java +++ b/PingPong/src/main/java/examples/pingpong/codegen/PingPongCodegenMain.java @@ -21,6 +21,7 @@ import io.grpc.ManagedChannelBuilder; import java.util.List; +import java.util.Optional; import java.util.UUID; public class PingPongCodegenMain { @@ -47,24 +48,21 @@ public static void main(String[] args) { // Initialize a plaintext gRPC channel ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build(); - // fetch the ledger ID, which is used in subsequent requests sent to the ledger - String ledgerId = fetchLedgerId(channel); - // fetch the party IDs that got created in the Daml init script String aliceParty = fetchPartyId(channel, ALICE_USER); String bobParty = fetchPartyId(channel, BOB_USER); // initialize the ping pong processors for Alice and Bob - PingPongProcessor aliceProcessor = new PingPongProcessor(aliceParty, ledgerId, channel); - PingPongProcessor bobProcessor = new PingPongProcessor(bobParty, ledgerId, channel); + PingPongProcessor aliceProcessor = new PingPongProcessor(aliceParty, channel); + PingPongProcessor bobProcessor = new PingPongProcessor(bobParty, channel); // start the processors asynchronously aliceProcessor.runIndefinitely(); bobProcessor.runIndefinitely(); // send the initial commands for both parties - createInitialContracts(channel, ledgerId, aliceParty, bobParty, numInitialContracts); - createInitialContracts(channel, ledgerId, bobParty, aliceParty, numInitialContracts); + createInitialContracts(channel, aliceParty, bobParty, numInitialContracts); + createInitialContracts(channel, bobParty, aliceParty, numInitialContracts); try { @@ -80,12 +78,11 @@ public static void main(String[] args) { * Creates numContracts number of Ping contracts. The sender is used as the submitting party. * * @param channel the gRPC channel to use for services - * @param ledgerId the previously fetched ledger id * @param sender the party that sends the initial Ping contract * @param receiver the party that receives the initial Ping contract * @param numContracts the number of initial contracts to create */ - private static void createInitialContracts(ManagedChannel channel, String ledgerId, String sender, String receiver, int numContracts) { + private static void createInitialContracts(ManagedChannel channel, String sender, String receiver, int numContracts) { CommandSubmissionServiceFutureStub submissionService = CommandSubmissionServiceGrpc.newFutureStub(channel); for (int i = 0; i < numContracts; i++) { @@ -102,24 +99,12 @@ private static void createInitialContracts(ManagedChannel channel, String ledger .withWorkflowId(String.format("Ping-%s-%d", sender, i)); // convert the command submission to a proto data structure - final var request = SubmitRequest.toProto(ledgerId, commandsSubmission); + final var request = SubmitRequest.toProto("", commandsSubmission); // asynchronously send the request submissionService.submit(request); } } - /** - * Fetches the ledger id via the Ledger Identity Service. - * - * @param channel the gRPC channel to use for services - * @return the ledger id as provided by the ledger - */ - private static String fetchLedgerId(ManagedChannel channel) { - LedgerIdentityServiceBlockingStub ledgerIdService = LedgerIdentityServiceGrpc.newBlockingStub(channel); - GetLedgerIdentityResponse identityResponse = ledgerIdService.getLedgerIdentity(GetLedgerIdentityRequest.getDefaultInstance()); - return identityResponse.getLedgerId(); - } - private static String fetchPartyId(ManagedChannel channel, String userId) { UserManagementServiceBlockingStub userManagementService = UserManagementServiceGrpc.newBlockingStub(channel); GetUserResponse getUserResponse = userManagementService.getUser(GetUserRequest.newBuilder().setUserId(userId).build()); diff --git a/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java b/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java index e6b120b..2327832 100644 --- a/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java +++ b/PingPong/src/main/java/examples/pingpong/codegen/PingPongProcessor.java @@ -33,7 +33,6 @@ public class PingPongProcessor { private final String party; - private final String ledgerId; private final TransactionServiceStub transactionService; private final CommandSubmissionServiceBlockingStub submissionService; @@ -41,9 +40,8 @@ public class PingPongProcessor { private final Identifier pingIdentifier; private final Identifier pongIdentifier; - public PingPongProcessor(String party, String ledgerId, ManagedChannel channel) { + public PingPongProcessor(String party, ManagedChannel channel) { this.party = party; - this.ledgerId = ledgerId; this.transactionService = TransactionServiceGrpc.newStub(channel); this.submissionService = CommandSubmissionServiceGrpc.newBlockingStub(channel); this.pingIdentifier = Ping.TEMPLATE_ID; @@ -58,8 +56,8 @@ public void runIndefinitely() { final var filtersByParty = new FiltersByParty(Map.of(party, inclusiveFilter)); // assemble the request for the transaction stream final var getTransactionsRequest = new GetTransactionsRequest( - ledgerId, - LedgerOffset.LedgerBegin.getInstance(), + "", + LedgerOffset.LedgerEnd.getInstance(), filtersByParty, true ); @@ -105,7 +103,7 @@ private void processTransaction(Transaction tx) { .withActAs(List.of(party)) .withReadAs(List.of(party)) .withWorkflowId(tx.getWorkflowId()); - submissionService.submit(SubmitRequest.toProto(ledgerId, commandsSubmission)); + submissionService.submit(SubmitRequest.toProto("", commandsSubmission)); } } diff --git a/PingPong/src/main/java/examples/pingpong/grpc/IdentifierCreator.java b/PingPong/src/main/java/examples/pingpong/grpc/IdentifierCreator.java new file mode 100644 index 0000000..025a385 --- /dev/null +++ b/PingPong/src/main/java/examples/pingpong/grpc/IdentifierCreator.java @@ -0,0 +1,47 @@ +package examples.pingpong.grpc; + +import com.daml.ledger.javaapi.data.Identifier; + +public class IdentifierCreator { + private String packageId; + private static String packageName = "#ex-java-bindings"; + public IdentifierCreator(String packageId) { + this.packageId = packageId; + } + public Identifier pingIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageName) + .setModuleName("PingPong") + .setEntityName("Ping") + .build() + ); + } + public Identifier pinnedPingIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageId) + .setModuleName("PingPong") + .setEntityName("Ping") + .build() + ); + } + public Identifier pongIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageName) + .setModuleName("PingPong") + .setEntityName("Pong") + .build() + ); + } + public Identifier pinnedPongIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageId) + .setModuleName("PingPong") + .setEntityName("Pong") + .build() + ); + } +} diff --git a/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java b/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java index 86eb15c..6890f25 100644 --- a/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java +++ b/PingPong/src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java @@ -52,38 +52,24 @@ public static void main(String[] args) { // Initialize a plaintext gRPC channel ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build(); - // fetch the ledger ID, which is used in subsequent requests sent to the ledger - String ledgerId = fetchLedgerId(channel); - // fetch the party IDs that got created in the Daml init script String aliceParty = fetchPartyId(channel, ALICE_USER); String bobParty = fetchPartyId(channel, BOB_USER); String packageId = Optional.ofNullable(System.getProperty("package.id")) .orElseThrow(() -> new RuntimeException("package.id must be specified via sys properties")); - - Identifier pingIdentifier = Identifier.newBuilder() - .setPackageId(packageId) - .setModuleName("PingPong") - .setEntityName("Ping") - .build(); - Identifier pongIdentifier = Identifier.newBuilder() - .setPackageId(packageId) - .setModuleName("PingPong") - .setEntityName("Pong") - .build(); - + IdentifierCreator identifierCreator = new IdentifierCreator(packageId); // initialize the ping pong processors for Alice and Bob - PingPongProcessor aliceProcessor = new PingPongProcessor(aliceParty, ledgerId, channel, pingIdentifier, pongIdentifier); - PingPongProcessor bobProcessor = new PingPongProcessor(bobParty, ledgerId, channel, pingIdentifier, pongIdentifier); + PingPongProcessor aliceProcessor = new PingPongProcessor(aliceParty, channel, identifierCreator); + PingPongProcessor bobProcessor = new PingPongProcessor(bobParty, channel, identifierCreator); // start the processors asynchronously aliceProcessor.runIndefinitely(); bobProcessor.runIndefinitely(); // send the initial commands for both parties - createInitialContracts(channel, ledgerId, aliceParty, bobParty, pingIdentifier, numInitialContracts); - createInitialContracts(channel, ledgerId, bobParty, aliceParty, pingIdentifier, numInitialContracts); + createInitialContracts(channel, aliceParty, bobParty, identifierCreator, numInitialContracts); + createInitialContracts(channel, bobParty, aliceParty, identifierCreator, numInitialContracts); try { @@ -99,24 +85,24 @@ public static void main(String[] args) { * Creates numContracts number of Ping contracts. The sender is used as the submitting party. * * @param channel the gRPC channel to use for services - * @param ledgerId the previously fetched ledger id * @param sender the party that sends the initial Ping contract * @param receiver the party that receives the initial Ping contract * @param pingIdentifier the PingPong.Ping template identifier * @param numContracts the number of initial contracts to create */ - private static void createInitialContracts(ManagedChannel channel, String ledgerId, String sender, String receiver, Identifier pingIdentifier, int numContracts) { + private static void createInitialContracts(ManagedChannel channel, String sender, String receiver, + IdentifierCreator identifierCreator, int numContracts) { CommandSubmissionServiceFutureStub submissionService = CommandSubmissionServiceGrpc.newFutureStub(channel); for (int i = 0; i < numContracts; i++) { // command that creates the initial Ping contract with the required parameters according to the model Command createCommand = Command.newBuilder().setCreate( CreateCommand.newBuilder() - .setTemplateId(pingIdentifier) + .setTemplateId(identifierCreator.pingIdentifier().toProto()) .setCreateArguments( Record.newBuilder() // the identifier for a template's record is the same as the identifier for the template - .setRecordId(pingIdentifier) + .setRecordId(identifierCreator.pinnedPingIdentifier().toProto()) .addFields(RecordField.newBuilder().setLabel("sender").setValue(Value.newBuilder().setParty(sender))) .addFields(RecordField.newBuilder().setLabel("receiver").setValue(Value.newBuilder().setParty(receiver))) .addFields(RecordField.newBuilder().setLabel("count").setValue(Value.newBuilder().setInt64(0))) @@ -125,7 +111,6 @@ private static void createInitialContracts(ManagedChannel channel, String ledger SubmitRequest submitRequest = SubmitRequest.newBuilder().setCommands(Commands.newBuilder() - .setLedgerId(ledgerId) .setCommandId(UUID.randomUUID().toString()) .setWorkflowId(String.format("Ping-%s-%d", sender, i)) .setParty(sender) @@ -138,18 +123,6 @@ private static void createInitialContracts(ManagedChannel channel, String ledger } } - /** - * Fetches the ledger id via the Ledger Identity Service. - * - * @param channel the gRPC channel to use for services - * @return the ledger id as provided by the ledger - */ - private static String fetchLedgerId(ManagedChannel channel) { - LedgerIdentityServiceBlockingStub ledgerIdService = LedgerIdentityServiceGrpc.newBlockingStub(channel); - GetLedgerIdentityResponse identityResponse = ledgerIdService.getLedgerIdentity(GetLedgerIdentityRequest.getDefaultInstance()); - return identityResponse.getLedgerId(); - } - private static String fetchPartyId(ManagedChannel channel, String userId) { UserManagementServiceBlockingStub userManagementService = UserManagementServiceGrpc.newBlockingStub(channel); GetUserResponse getUserResponse = userManagementService.getUser(GetUserRequest.newBuilder().setUserId(userId).build()); diff --git a/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java b/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java index d7fac99..e3c3997 100644 --- a/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java +++ b/PingPong/src/main/java/examples/pingpong/grpc/PingPongProcessor.java @@ -40,21 +40,17 @@ public class PingPongProcessor { private final String party; - private final String ledgerId; - + private final TransactionServiceStub transactionService; private final CommandSubmissionServiceBlockingStub submissionService; - private final Identifier pingIdentifier; - private final Identifier pongIdentifier; + private final IdentifierCreator identifierCreator; - public PingPongProcessor(String party, String ledgerId, ManagedChannel channel, Identifier pingIdentifier, Identifier pongIdentifier) { + public PingPongProcessor(String party, ManagedChannel channel, IdentifierCreator identifierCreator) { this.party = party; - this.ledgerId = ledgerId; this.transactionService = TransactionServiceGrpc.newStub(channel); this.submissionService = CommandSubmissionServiceGrpc.newBlockingStub(channel); - this.pingIdentifier = pingIdentifier; - this.pongIdentifier = pongIdentifier; + this.identifierCreator = identifierCreator; } public void runIndefinitely() { @@ -64,14 +60,13 @@ public void runIndefinitely() { Filters.newBuilder() .setInclusive( InclusiveFilters.newBuilder() - .addTemplateIds(pingIdentifier) - .addTemplateIds(pongIdentifier) + .addTemplateIds(identifierCreator.pingIdentifier().toProto()) + .addTemplateIds(identifierCreator.pongIdentifier().toProto()) .build()) .build()); // assemble the request for the transaction stream GetTransactionsRequest transactionsRequest = GetTransactionsRequest.newBuilder() - .setLedgerId(ledgerId) - .setBegin(LedgerOffset.newBuilder().setBoundary(LedgerBoundary.LEDGER_BEGIN)) + .setBegin(LedgerOffset.newBuilder().setBoundary(LedgerBoundary.LEDGER_END)) .setFilter(filtersByParty) .setVerbose(true) .build(); @@ -114,7 +109,6 @@ private void processTransaction(Transaction tx) { .setCommands(Commands.newBuilder() .setCommandId(UUID.randomUUID().toString()) .setWorkflowId(tx.getWorkflowId()) - .setLedgerId(ledgerId) .setParty(party) .setApplicationId(PingPongGrpcMain.APP_ID) .addAllCommands(commands) @@ -137,10 +131,10 @@ private void processTransaction(Transaction tx) { private Stream processEvent(String workflowId, CreatedEvent event) { Identifier template = event.getTemplateId(); - boolean isPingPongModule = template.getModuleName().equals(pingIdentifier.getModuleName()); + boolean isPingPongModule = template.getModuleName().equals(identifierCreator.pingIdentifier().getModuleName()); - boolean isPing = template.getEntityName().equals(pingIdentifier.getEntityName()); - boolean isPong = template.getEntityName().equals(pongIdentifier.getEntityName()); + boolean isPing = template.getEntityName().equals(identifierCreator.pingIdentifier().getEntityName()); + boolean isPong = template.getEntityName().equals(identifierCreator.pongIdentifier().getEntityName()); if (!isPingPongModule || !isPing && !isPong) return Stream.empty(); diff --git a/PingPong/src/main/java/examples/pingpong/reactive/IdentifierCreator.java b/PingPong/src/main/java/examples/pingpong/reactive/IdentifierCreator.java new file mode 100644 index 0000000..e59cc0f --- /dev/null +++ b/PingPong/src/main/java/examples/pingpong/reactive/IdentifierCreator.java @@ -0,0 +1,47 @@ +package examples.pingpong.reactive; + +import com.daml.ledger.javaapi.data.Identifier; + +public class IdentifierCreator { + private String packageId; + private static String packageName = "#ex-java-bindings"; + public IdentifierCreator(String packageId) { + this.packageId = packageId; + } + public Identifier pingIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageName) + .setModuleName("PingPong") + .setEntityName("Ping") + .build() + ); + } + public Identifier pinnedPingIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageId) + .setModuleName("PingPong") + .setEntityName("Ping") + .build() + ); + } + public Identifier pongIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageName) + .setModuleName("PingPong") + .setEntityName("Pong") + .build() + ); + } + public Identifier pinnedPongIdentifier() { + return Identifier.fromProto( + com.daml.ledger.api.v1.ValueOuterClass.Identifier.newBuilder() + .setPackageId(packageId) + .setModuleName("PingPong") + .setEntityName("Pong") + .build() + ); + } +} diff --git a/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java b/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java index 1ddff9e..ed37660 100644 --- a/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java +++ b/PingPong/src/main/java/examples/pingpong/reactive/PingPongProcessor.java @@ -26,18 +26,14 @@ public class PingPongProcessor { private static final Logger logger = LoggerFactory.getLogger(PingPongProcessor.class); private final String party; - private final String ledgerId; private LedgerClient client; - private final Identifier pingIdentifier; - private final Identifier pongIdentifier; + private final IdentifierCreator identifierCreator; - public PingPongProcessor(String party, LedgerClient client, Identifier pingIdentifier, Identifier pongIdentifier) { + public PingPongProcessor(String party, LedgerClient client, IdentifierCreator identifierCreator) { this.party = party; - this.ledgerId = client.getLedgerId(); this.client = client; - this.pingIdentifier = pingIdentifier; - this.pongIdentifier = pongIdentifier; + this.identifierCreator = identifierCreator; } public void runIndefinitely() { @@ -84,8 +80,8 @@ private Single processTransaction(Transaction tx) { private Stream processEvent(String workflowId, CreatedEvent event) { Identifier template = event.getTemplateId(); - boolean isPing = template.equals(pingIdentifier); - boolean isPong = template.equals(pongIdentifier); + boolean isPing = template.getEntityName().equals(identifierCreator.pingIdentifier().getEntityName()); + boolean isPong = template.getEntityName().equals(identifierCreator.pongIdentifier().getEntityName()); if (!isPing && !isPong) return Stream.empty(); diff --git a/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java b/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java index f74d6a0..83adb1a 100644 --- a/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java +++ b/PingPong/src/main/java/examples/pingpong/reactive/PingPongReactiveMain.java @@ -9,7 +9,6 @@ import com.daml.ledger.api.v1.CommandsOuterClass.Command; import com.daml.ledger.api.v1.CommandsOuterClass.CreateCommand; -import com.daml.ledger.api.v1.ValueOuterClass.Identifier; import com.daml.ledger.api.v1.ValueOuterClass.Record; import com.daml.ledger.api.v1.ValueOuterClass.RecordField; import com.daml.ledger.api.v1.ValueOuterClass.Value; @@ -54,21 +53,18 @@ public static void main(String[] args) { String bobParty = userManagementClient.getUser(new GetUserRequest(BOB_USER)).blockingGet().getUser().getPrimaryParty().get(); String packageId = Optional.ofNullable(System.getProperty("package.id")).orElseThrow(() -> new RuntimeException("package.id must be specified via sys properties")); - var pingIdentifier = com.daml.ledger.javaapi.data.Identifier.fromProto(Identifier.newBuilder() - .setPackageId(packageId).setModuleName("PingPong").setEntityName("Ping").build()); - var pongIdentifier = com.daml.ledger.javaapi.data.Identifier.fromProto(Identifier.newBuilder() - .setPackageId(packageId).setModuleName("PingPong").setEntityName("Pong").build()); + IdentifierCreator identifierCreator = new IdentifierCreator(packageId); // initialize the ping pong processors for Alice and Bob - PingPongProcessor aliceProcessor = new PingPongProcessor(aliceParty, client, pingIdentifier, pongIdentifier); - PingPongProcessor bobProcessor = new PingPongProcessor(bobParty, client, pingIdentifier, pongIdentifier); + PingPongProcessor aliceProcessor = new PingPongProcessor(aliceParty, client, identifierCreator); + PingPongProcessor bobProcessor = new PingPongProcessor(bobParty, client, identifierCreator); // start the processors asynchronously aliceProcessor.runIndefinitely(); bobProcessor.runIndefinitely(); // send the initial commands for both parties - createInitialContracts(client, aliceParty, bobParty, pingIdentifier.toProto(), numInitialContracts); - createInitialContracts(client, bobParty, aliceParty, pingIdentifier.toProto(), numInitialContracts); + createInitialContracts(client, aliceParty, bobParty, identifierCreator, numInitialContracts); + createInitialContracts(client, bobParty, aliceParty, identifierCreator, numInitialContracts); try { // wait a couple of seconds for the processing to finish @@ -90,7 +86,7 @@ public static void main(String[] args) { * @param numContracts the number of initial contracts to create */ private static void createInitialContracts(LedgerClient client, String sender, String receiver, - Identifier pingIdentifier, int numContracts) { + IdentifierCreator identifierCreator, int numContracts) { for (int i = 0; i < numContracts; i++) { // command that creates the initial Ping contract with the required parameters @@ -98,12 +94,12 @@ private static void createInitialContracts(LedgerClient client, String sender, S Command createCommand = Command.newBuilder().setCreate( CreateCommand.newBuilder() - .setTemplateId(pingIdentifier) + .setTemplateId(identifierCreator.pingIdentifier().toProto()) .setCreateArguments( Record.newBuilder() // the identifier for a template's record is the same as the identifier for // the template - .setRecordId(pingIdentifier) + .setRecordId(identifierCreator.pinnedPingIdentifier().toProto()) .addFields(RecordField.newBuilder().setLabel("sender") .setValue(Value.newBuilder().setParty(sender))) .addFields(RecordField.newBuilder().setLabel("receiver")