From 94fedd68597a66c572c856f7b85bba357b3d4a24 Mon Sep 17 00:00:00 2001 From: Erica Sadun Date: Mon, 22 Apr 2024 12:32:33 -0600 Subject: [PATCH 1/4] EDU-2293: Update source code for "Run your first app in Java" and port to Maven JIRA: https://temporalio.atlassian.net/browse/EDU-2293 --- README.md | 39 ++- build.gradle | 40 --- gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 - gradlew | 244 ------------------ gradlew.bat | 92 ------- pom.xml | 166 ++++++++++++ settings.gradle | 1 - .../AccountActivity.java | 10 +- .../moneytransfer/AccountActivityImpl.java | 26 ++ .../moneytransfer/MoneyTransferWorker.java | 42 +++ .../MoneyTransferWorkflow.java | 5 +- .../MoneyTransferWorkflowImpl.java | 52 ++++ .../Shared.java | 3 +- src/main/java/moneytransfer/TransferApp.java | 71 +++++ .../moneytransferapp/AccountActivityImpl.java | 26 -- .../InitiateMoneyTransfer.java | 37 --- .../moneytransferapp/MoneyTransferWorker.java | 28 -- .../MoneyTransferWorkflowImpl.java | 43 --- src/main/resources/logback.xml | 14 - .../MoneyTransferWorkflowTest.java | 2 + 21 files changed, 384 insertions(+), 563 deletions(-) delete mode 100644 build.gradle delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradlew delete mode 100644 gradlew.bat create mode 100644 pom.xml delete mode 100644 settings.gradle rename src/main/java/{moneytransferapp => moneytransfer}/AccountActivity.java (67%) create mode 100644 src/main/java/moneytransfer/AccountActivityImpl.java create mode 100644 src/main/java/moneytransfer/MoneyTransferWorker.java rename src/main/java/{moneytransferapp => moneytransfer}/MoneyTransferWorkflow.java (63%) create mode 100644 src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java rename src/main/java/{moneytransferapp => moneytransfer}/Shared.java (67%) create mode 100644 src/main/java/moneytransfer/TransferApp.java delete mode 100644 src/main/java/moneytransferapp/AccountActivityImpl.java delete mode 100644 src/main/java/moneytransferapp/InitiateMoneyTransfer.java delete mode 100644 src/main/java/moneytransferapp/MoneyTransferWorker.java delete mode 100644 src/main/java/moneytransferapp/MoneyTransferWorkflowImpl.java delete mode 100644 src/main/resources/logback.xml rename src/test/java/{moneytransferapp => moneytransfer}/MoneyTransferWorkflowTest.java (96%) diff --git a/README.md b/README.md index 3e5be32..3be1cd4 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,28 @@ -# Money transfer: Java project template - -This project can be used as a template to start building your own Temporal Workflow application. +# Money transfer project: Java +Learn how the pieces of a Temporal application work together. Follow the [Run your first app tutorial](https://docs.temporal.io/docs/java/run-your-first-app-tutorial) to learn more about Temporal Workflows. -This project uses [Snipsync](https://github.com/temporalio/snipsync) comment wrappers to automatically keep code snippets up to date within our documentation. - -## How to use the template - -To use the template, either download it as a zip file or click "Use Template" to make a copy of it in your own Github account. +Note: This project uses [Snipsync](https://github.com/temporalio/snipsync) comment wrappers to automatically keep code snippets up to date within our documentation. -## Build the project +## Building, cleaning, and other tasks -Either open the project in IntelliJ, which will automatically build it, or in the project's root directory run: - -``` -./gradlew build ``` +build: + mvn clean install -Dorg.slf4j.simpleLogger.defaultLogLevel=info 2>/dev/null -## Run the Workflow +clean: + mvn clean -q -Dmaven.logging.level=0 -First, make sure the [Temporal server](https://docs.temporal.io/docs/server/quick-install) is running. +worker: + mvn compile exec:java -Dexec.mainClass="moneytransferapp.MoneyTransferWorker" -Dorg.slf4j.simpleLogger.defaultLogLevel=warn -To start the Workflow, either run the InitiateMoneyTransfer class from IntelliJ or from the project root run: +run: + mvn compile exec:java -Dexec.mainClass="moneytransferapp.TransferApp" -Dorg.slf4j.simpleLogger.defaultLogLevel=warn -``` -./gradlew initiateTransfer -``` +serve: + `command -v temporal` server start-dev --log-level=never & -To start the Worker, either run the MoneyTransferWorker class from IntelliJ or from the project root run: - -``` -./gradlew startWorker --console=plain +stop-server: + pkill temporal ``` diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 13e08e8..0000000 --- a/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Java project to get you started. - * For more details take a look at the Java Quickstart chapter in the Gradle - * User Manual available at https://docs.gradle.org/7.0.2/userguide/tutorial_java_projects.html - */ - -plugins { - id 'java' -} - -repositories { - mavenCentral() -} - -ext { - javaSDKVersion = '1.18.1' -} - -dependencies { - // These dependencies are used by the application. - implementation "io.temporal:temporal-sdk:$javaSDKVersion" - implementation "ch.qos.logback:logback-classic:1.2.11" - - // Use JUnit test framework - testImplementation "io.temporal:temporal-testing:$javaSDKVersion" - testImplementation "junit:junit:4.13.2" - testImplementation "org.mockito:mockito-core:5.1.1" -} - -task initiateTransfer(type: JavaExec) { - mainClass = 'moneytransferapp.InitiateMoneyTransfer' - classpath = sourceSets.main.runtimeClasspath -} - -task startWorker(type: JavaExec) { - mainClass = 'moneytransferapp.MoneyTransferWorker' - classpath = sourceSets.main.runtimeClasspath -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61574 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 ScNgau(U?ep-K_E5zy1%ZQTdPn diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3499ded..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip -networkTimeout=10000 -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100755 index 65dcd68..0000000 --- a/gradlew +++ /dev/null @@ -1,244 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 93e3f59..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..980a0ff --- /dev/null +++ b/pom.xml @@ -0,0 +1,166 @@ + + + + 4.0.0 + + Money Transfer Project + io.temporal + moneytransfer + 1.0.0 + + + + UTF-8 + 1.8 + 1.8 + + + + + + + + + io.temporal + temporal-sdk + 1.22.2 + + + + + io.temporal + temporal-testing + 1.22.2 + test + + + + + + + org.slf4j + slf4j-nop + 2.0.6 + + + + + junit + junit + 4.11 + test + + + + + org.mockito + mockito-core + 5.10.0 + test + + + + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + + maven-resources-plugin + 3.0.2 + + + + + maven-compiler-plugin + 3.8.0 + + + + + maven-surefire-plugin + 2.22.1 + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.1 + + + + + maven-install-plugin + 2.5.2 + + + + + maven-deploy-plugin + 2.8.2 + + + + + maven-site-plugin + 3.7.1 + + + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 2eba58e..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'money-transfer-project-template-java' diff --git a/src/main/java/moneytransferapp/AccountActivity.java b/src/main/java/moneytransfer/AccountActivity.java similarity index 67% rename from src/main/java/moneytransferapp/AccountActivity.java rename to src/main/java/moneytransfer/AccountActivity.java index ef2840a..dcef4a7 100644 --- a/src/main/java/moneytransferapp/AccountActivity.java +++ b/src/main/java/moneytransfer/AccountActivity.java @@ -1,17 +1,17 @@ +// @@@SNIPSTART money-transfer-java-activity-interface package moneytransferapp; -// @@@SNIPSTART money-transfer-project-template-java-activity-interface - import io.temporal.activity.ActivityInterface; import io.temporal.activity.ActivityMethod; @ActivityInterface public interface AccountActivity { - + // Withdraw an amount of money from the source account @ActivityMethod - void deposit(String accountId, String referenceId, double amount); + void withdraw(String accountId, String referenceId, double amount); + // Deposit an amount of money into the destination account @ActivityMethod - void withdraw(String accountId, String referenceId, double amount); + void deposit(String accountId, String referenceId, double amount); } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/AccountActivityImpl.java b/src/main/java/moneytransfer/AccountActivityImpl.java new file mode 100644 index 0000000..d2aecb5 --- /dev/null +++ b/src/main/java/moneytransfer/AccountActivityImpl.java @@ -0,0 +1,26 @@ +// @@@SNIPSTART money-transfer-java-activity-implementation +package moneytransferapp; + +public class AccountActivityImpl implements AccountActivity { + // Mock up the withdrawal of an amount of money from the source account + @Override + public void withdraw(String accountId, String referenceId, double amount) { + System.out.printf( + "\nWithdrawing $%.2f from account %s.\n[ReferenceId: %s]\n", + amount, accountId, referenceId + ); + } + + // Mock up the deposit of an amount of money from the destination account + @Override + public void deposit(String accountId, String referenceId, double amount) { + System.out.printf( + "\nDepositing $%.2f into account %s.\n[ReferenceId: %s]\n", + amount, accountId, referenceId + ); + + // TO SIMULATE AN ACTIVITY ERROR: Uncomment the following line + // throw Activity.wrap(new RuntimeException("Simulated Activity error")); + } +} +// @@@SNIPEND diff --git a/src/main/java/moneytransfer/MoneyTransferWorker.java b/src/main/java/moneytransfer/MoneyTransferWorker.java new file mode 100644 index 0000000..e2de9c8 --- /dev/null +++ b/src/main/java/moneytransfer/MoneyTransferWorker.java @@ -0,0 +1,42 @@ +// @@@SNIPSTART money-transfer-java-worker +package moneytransferapp; + +import io.temporal.client.WorkflowClient; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerFactory; + +public class MoneyTransferWorker { + + public static void main(String[] args) { + // Create a stub that accesses a Temporal Service on the local development machine + WorkflowServiceStubs serviceStub = WorkflowServiceStubs.newLocalServiceStubs(); + + // The Worker uses the Client to communicate with the Temporal Service + WorkflowClient client = WorkflowClient.newInstance(serviceStub); + + // A WorkerFactory creates Workers + WorkerFactory factory = WorkerFactory.newInstance(client); + + // A Worker listens to one Task Queue. + // This Worker processes both Workflows and Activities + Worker worker = factory.newWorker(Shared.MONEY_TRANSFER_TASK_QUEUE); + + // Register a Workflow implementation with this Worker + // The implementation must be known at runtime to dispatch Workflow tasks + // Workflows are stateful so a type is needed to create instances. + worker.registerWorkflowImplementationTypes(MoneyTransferWorkflowImpl.class); + + // Register Activity implementation(s) with this Worker. + // The implementation must be known at runtime to dispatch Activity tasks + // Activities are stateless and thread safe so a shared instance is used. + worker.registerActivitiesImplementations(new AccountActivityImpl()); + + System.out.println("Worker is running and actively polling the Task Queue."); + System.out.println("To quit, use ^C to interrupt."); + + // Start all registered Workers. The Workers will start polling the Task Queue. + factory.start(); + } +} +// @@@SNIPEND diff --git a/src/main/java/moneytransferapp/MoneyTransferWorkflow.java b/src/main/java/moneytransfer/MoneyTransferWorkflow.java similarity index 63% rename from src/main/java/moneytransferapp/MoneyTransferWorkflow.java rename to src/main/java/moneytransfer/MoneyTransferWorkflow.java index 8b85543..159b382 100644 --- a/src/main/java/moneytransferapp/MoneyTransferWorkflow.java +++ b/src/main/java/moneytransfer/MoneyTransferWorkflow.java @@ -1,13 +1,14 @@ +// @@@SNIPSTART money-transfer-java-workflow-interface package moneytransferapp; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; -// @@@SNIPSTART money-transfer-project-template-java-workflow-interface @WorkflowInterface public interface MoneyTransferWorkflow { - // The Workflow method is called by the initiator either via code or CLI. + // The Workflow Execution that starts this method can be initiated from code or + // from the 'temporal' CLI utility. @WorkflowMethod void transfer(String fromAccountId, String toAccountId, String referenceId, double amount); } diff --git a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java new file mode 100644 index 0000000..bb6e52e --- /dev/null +++ b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java @@ -0,0 +1,52 @@ +// @@@SNIPSTART money-transfer-java-workflow-implementation +package moneytransferapp; + +import io.temporal.activity.ActivityOptions; +import io.temporal.workflow.Workflow; +import io.temporal.common.RetryOptions; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +public class MoneyTransferWorkflowImpl implements MoneyTransferWorkflow { + private static final String WITHDRAW = "Withdraw"; + + // RetryOptions specify how to automatically handle retries when Activities fail. + private final RetryOptions retryoptions = RetryOptions.newBuilder() + .setInitialInterval(Duration.ofSeconds(1)) // Wait 1 second before first retry + .setMaximumInterval(Duration.ofSeconds(20)) // Do not exceed 20 seconds between retries + .setBackoffCoefficient(2) // Wait 1 second, then 2, then 4, etc. + .setMaximumAttempts(5) // Fail after 5 attempts + .build(); + + // ActivityOptions specify the limits on how long an Activity can execute before + // being interrupted by the Orchestration service. + private final ActivityOptions defaultActivityOptions = ActivityOptions.newBuilder() + .setRetryOptions(retryoptions) // defined above + .setStartToCloseTimeout(Duration.ofSeconds(2)) // Max execution time for single Activity + .setScheduleToCloseTimeout(Duration.ofSeconds(5)) // Entire duration from scheduling to completion, + // including queue time. + .build(); + + private final Map perActivityMethodOptions = new HashMap() {{ + // A heartbeat time-out is a proof-of life indicator that an activity is still working. + // This option says to wait for 5 seconds to hear a heartbeat. If one is not heard, + // the Activity fails. + put(WITHDRAW, ActivityOptions.newBuilder().setHeartbeatTimeout(Duration.ofSeconds(5)).build()); + }}; + + // ActivityStubs enable calls to methods as if the Activity object is local, + // but actually perform an RPC invocation. + private final AccountActivity accountActivityStub = Workflow.newActivityStub(AccountActivity.class, defaultActivityOptions, perActivityMethodOptions); + + // The transfer method is the entry point to the Workflow. + // Activity method executions can be orchestrated here or from within + // other Activity methods. + @Override + public void transfer(String fromAccountId, String toAccountId, String referenceId, double amount) { + accountActivityStub.withdraw(fromAccountId, referenceId, amount); + accountActivityStub.deposit(toAccountId, referenceId, amount); + } +} +// @@@SNIPEND diff --git a/src/main/java/moneytransferapp/Shared.java b/src/main/java/moneytransfer/Shared.java similarity index 67% rename from src/main/java/moneytransferapp/Shared.java rename to src/main/java/moneytransfer/Shared.java index e04d30b..66ac416 100644 --- a/src/main/java/moneytransferapp/Shared.java +++ b/src/main/java/moneytransfer/Shared.java @@ -1,8 +1,7 @@ +// @@@SNIPSTART money-transfer-java-shared package moneytransferapp; -// @@@SNIPSTART money-transfer-project-template-java-shared-constants public interface Shared { - static final String MONEY_TRANSFER_TASK_QUEUE = "MONEY_TRANSFER_TASK_QUEUE"; } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/TransferApp.java b/src/main/java/moneytransfer/TransferApp.java new file mode 100644 index 0000000..9c56929 --- /dev/null +++ b/src/main/java/moneytransfer/TransferApp.java @@ -0,0 +1,71 @@ +// @@@SNIPSTART money-transfer-java-initiate-transfer +package moneytransferapp; + +import io.temporal.api.common.v1.WorkflowExecution; +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowOptions; +import io.temporal.serviceclient.WorkflowServiceStubs; + +import java.util.UUID; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.concurrent.ThreadLocalRandom; +import java.time.Instant; + +public class TransferApp { + private static final Random random; + + static { + // Seed the random number generator with nano date + random = new Random(Instant.now().getNano()); + } + + public static String randomAccountIdentifier() { + return IntStream.range(0, 11) + .mapToObj(i -> String.valueOf(random.nextInt(10))) + .collect(Collectors.joining()); + } + + public static void main(String[] args) throws Exception { + + // In the Java SDK, a stub represents an element that participates in + // Temporal orchestration and communicates using gRPC. + + // A WorkflowServiceStubs communicates with the Temporal front-end service. + WorkflowServiceStubs serviceStub = WorkflowServiceStubs.newLocalServiceStubs(); + + // A WorkflowClient wraps the stub. + // It can be used to start, signal, query, cancel, and terminate Workflows. + WorkflowClient client = WorkflowClient.newInstance(serviceStub); + + // Workflow options configure Workflow stubs. + // A WorkflowId prevents duplicate instances, which are removed. + WorkflowOptions options = WorkflowOptions.newBuilder() + .setTaskQueue(Shared.MONEY_TRANSFER_TASK_QUEUE) + .setWorkflowId("money-transfer-workflow") + .build(); + + // WorkflowStubs enable calls to methods as if the Workflow object is local + // but actually perform a gRPC call to the Temporal Service. + MoneyTransferWorkflow workflow = client.newWorkflowStub(MoneyTransferWorkflow.class, options); + + // Configure the details for this money transfer request + String referenceId = UUID.randomUUID().toString().substring(0, 18); + String fromAccount = randomAccountIdentifier(); + String toAccount = randomAccountIdentifier(); + double amountToTransfer = ThreadLocalRandom.current().nextDouble(15.0, 25.0); + + // Perform asynchronous execution. + // This process exits after making this call and printing details. + WorkflowExecution we = WorkflowClient.start( + workflow::transfer, fromAccount, toAccount, referenceId, amountToTransfer); + + System.out.printf("\nMONEY TRANSFER PROJECT\n\n"); + System.out.printf("Initiating transfer of $%.2f from [Account %s] to [Account %s].\n\n", + amountToTransfer, fromAccount, toAccount); + System.out.printf("[WorkflowID: %s]\n[RunID: %s]\n\n", we.getWorkflowId(), we.getRunId()); + System.exit(0); + } +} +// @@@SNIPEND diff --git a/src/main/java/moneytransferapp/AccountActivityImpl.java b/src/main/java/moneytransferapp/AccountActivityImpl.java deleted file mode 100644 index 74cc7e5..0000000 --- a/src/main/java/moneytransferapp/AccountActivityImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package moneytransferapp; - -// @@@SNIPSTART money-transfer-project-template-java-activity-implementation -public class AccountActivityImpl implements AccountActivity { - - @Override - public void withdraw(String accountId, String referenceId, double amount) { - - System.out.printf( - "\nWithdrawing $%f from account %s. ReferenceId: %s\n", - amount, accountId, referenceId - ); - } - - @Override - public void deposit(String accountId, String referenceId, double amount) { - - System.out.printf( - "\nDepositing $%f into account %s. ReferenceId: %s\n", - amount, accountId, referenceId - ); - // Uncomment the following line to simulate an Activity error. - // throw new RuntimeException("simulated"); - } -} -// @@@SNIPEND diff --git a/src/main/java/moneytransferapp/InitiateMoneyTransfer.java b/src/main/java/moneytransferapp/InitiateMoneyTransfer.java deleted file mode 100644 index 9f48dd3..0000000 --- a/src/main/java/moneytransferapp/InitiateMoneyTransfer.java +++ /dev/null @@ -1,37 +0,0 @@ -package moneytransferapp; - -import io.temporal.api.common.v1.WorkflowExecution; -import io.temporal.client.WorkflowClient; -import io.temporal.client.WorkflowOptions; -import io.temporal.serviceclient.WorkflowServiceStubs; - -import java.util.UUID; - -// @@@SNIPSTART money-transfer-project-template-java-workflow-initiator -public class InitiateMoneyTransfer { - - public static void main(String[] args) throws Exception { - - // WorkflowServiceStubs is a gRPC stubs wrapper that talks to the local Docker instance of the Temporal server. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowOptions options = WorkflowOptions.newBuilder() - .setTaskQueue(Shared.MONEY_TRANSFER_TASK_QUEUE) - // A WorkflowId prevents this it from having duplicate instances, remove it to duplicate. - .setWorkflowId("money-transfer-workflow") - .build(); - // WorkflowClient can be used to start, signal, query, cancel, and terminate Workflows. - WorkflowClient client = WorkflowClient.newInstance(service); - // WorkflowStubs enable calls to methods as if the Workflow object is local, but actually perform an RPC. - MoneyTransferWorkflow workflow = client.newWorkflowStub(MoneyTransferWorkflow.class, options); - String referenceId = UUID.randomUUID().toString(); - String fromAccount = "001-001"; - String toAccount = "002-002"; - double amount = 18.74; - // Asynchronous execution. This process will exit after making this call. - WorkflowExecution we = WorkflowClient.start(workflow::transfer, fromAccount, toAccount, referenceId, amount); - System.out.printf("\nTransfer of $%f from account %s to account %s is processing\n", amount, fromAccount, toAccount); - System.out.printf("\nWorkflowID: %s RunID: %s", we.getWorkflowId(), we.getRunId()); - System.exit(0); - } -} -// @@@SNIPEND diff --git a/src/main/java/moneytransferapp/MoneyTransferWorker.java b/src/main/java/moneytransferapp/MoneyTransferWorker.java deleted file mode 100644 index 38023f7..0000000 --- a/src/main/java/moneytransferapp/MoneyTransferWorker.java +++ /dev/null @@ -1,28 +0,0 @@ -package moneytransferapp; - -import io.temporal.client.WorkflowClient; -import io.temporal.serviceclient.WorkflowServiceStubs; -import io.temporal.worker.Worker; -import io.temporal.worker.WorkerFactory; - -// @@@SNIPSTART money-transfer-project-template-java-worker -public class MoneyTransferWorker { - - public static void main(String[] args) { - - // WorkflowServiceStubs is a gRPC stubs wrapper that talks to the local Docker instance of the Temporal server. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); - // Worker factory is used to create Workers that poll specific Task Queues. - WorkerFactory factory = WorkerFactory.newInstance(client); - Worker worker = factory.newWorker(Shared.MONEY_TRANSFER_TASK_QUEUE); - // This Worker hosts both Workflow and Activity implementations. - // Workflows are stateful so a type is needed to create instances. - worker.registerWorkflowImplementationTypes(MoneyTransferWorkflowImpl.class); - // Activities are stateless and thread safe so a shared instance is used. - worker.registerActivitiesImplementations(new AccountActivityImpl()); - // Start listening to the Task Queue. - factory.start(); - } -} -// @@@SNIPEND diff --git a/src/main/java/moneytransferapp/MoneyTransferWorkflowImpl.java b/src/main/java/moneytransferapp/MoneyTransferWorkflowImpl.java deleted file mode 100644 index 9d9e7e0..0000000 --- a/src/main/java/moneytransferapp/MoneyTransferWorkflowImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package moneytransferapp; - -import io.temporal.activity.ActivityOptions; -import io.temporal.workflow.Workflow; -import io.temporal.common.RetryOptions; - -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -// @@@SNIPSTART money-transfer-project-template-java-workflow-implementation -public class MoneyTransferWorkflowImpl implements MoneyTransferWorkflow { - private static final String WITHDRAW = "Withdraw"; - // RetryOptions specify how to automatically handle retries when Activities fail. - private final RetryOptions retryoptions = RetryOptions.newBuilder() - .setInitialInterval(Duration.ofSeconds(1)) - .setMaximumInterval(Duration.ofSeconds(100)) - .setBackoffCoefficient(2) - .setMaximumAttempts(500) - .build(); - private final ActivityOptions defaultActivityOptions = ActivityOptions.newBuilder() - // Timeout options specify when to automatically timeout Activities if the process is taking too long. - .setStartToCloseTimeout(Duration.ofSeconds(5)) - // Optionally provide customized RetryOptions. - // Temporal retries failures by default, this is simply an example. - .setRetryOptions(retryoptions) - .build(); - // ActivityStubs enable calls to methods as if the Activity object is local, but actually perform an RPC. - private final Map perActivityMethodOptions = new HashMap(){{ - put(WITHDRAW, ActivityOptions.newBuilder().setHeartbeatTimeout(Duration.ofSeconds(5)).build()); - }}; - private final AccountActivity account = Workflow.newActivityStub(AccountActivity.class, defaultActivityOptions, perActivityMethodOptions); - - // The transfer method is the entry point to the Workflow. - // Activity method executions can be orchestrated here or from within other Activity methods. - @Override - public void transfer(String fromAccountId, String toAccountId, String referenceId, double amount) { - - account.withdraw(fromAccountId, referenceId, amount); - account.deposit(toAccountId, referenceId, amount); - } -} -// @@@SNIPEND diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index 9fe6d5c..0000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - diff --git a/src/test/java/moneytransferapp/MoneyTransferWorkflowTest.java b/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java similarity index 96% rename from src/test/java/moneytransferapp/MoneyTransferWorkflowTest.java rename to src/test/java/moneytransfer/MoneyTransferWorkflowTest.java index 2bb6b3d..b8c1ecf 100644 --- a/src/test/java/moneytransferapp/MoneyTransferWorkflowTest.java +++ b/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java @@ -1,3 +1,4 @@ +// @@@SNIPSTART money-transfer-java-tests package moneytransferapp; import static org.mockito.ArgumentMatchers.eq; @@ -46,3 +47,4 @@ public void testTransfer() { verify(activities).deposit(eq("account2"), eq("reference1"), eq(1.23)); } } +// @@@SNIPEND From e276c21e50ceaf6576e97c11d262c11a2aefbf1a Mon Sep 17 00:00:00 2001 From: Erica Sadun Date: Mon, 22 Apr 2024 16:03:15 -0600 Subject: [PATCH 2/4] EDU-2293: Update source code for "Run your first app in Java" * Source code updated * Ported to Maven * Transaction details are now a single type * Jackson Deserialization is now supported for the custom type * Test run and pass * Worker runs correctly * Caller app runs correctly JIRA: https://temporalio.atlassian.net/browse/EDU-2293 --- .../moneytransfer/CoreTransactionDetails.java | 44 +++++++++++++++++++ .../moneytransfer/MoneyTransferWorkflow.java | 3 +- .../MoneyTransferWorkflowImpl.java | 9 ++-- .../moneytransfer/TransactionDetails.java | 13 ++++++ src/main/java/moneytransfer/TransferApp.java | 12 ++--- .../MoneyTransferWorkflowTest.java | 3 +- 6 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 src/main/java/moneytransfer/CoreTransactionDetails.java create mode 100644 src/main/java/moneytransfer/TransactionDetails.java diff --git a/src/main/java/moneytransfer/CoreTransactionDetails.java b/src/main/java/moneytransfer/CoreTransactionDetails.java new file mode 100644 index 0000000..db4b25e --- /dev/null +++ b/src/main/java/moneytransfer/CoreTransactionDetails.java @@ -0,0 +1,44 @@ +// @@@SNIPSTART money-transfer-java-coreTransactionDetails +package moneytransferapp; + +public class CoreTransactionDetails implements TransactionDetails { + private String sourceAccountId; + private String destinationAccountId; + private String transactionReferenceId; + private double amountToTransfer; + + // MARK: Constructor + + public CoreTransactionDetails() { + // Default constructor is needed for Jackson deserialization + } + + public CoreTransactionDetails(String sourceAccountId, + String destinationAccountId, + String transactionReferenceId, + double amountToTransfer) { + this.sourceAccountId = sourceAccountId; + this.destinationAccountId = destinationAccountId; + this.transactionReferenceId = transactionReferenceId; + this.amountToTransfer = amountToTransfer; + } + + // MARK: Getter methods + + public String getSourceAccountId() { + return sourceAccountId; + } + + public String getDestinationAccountId() { + return destinationAccountId; + } + + public String getTransactionReferenceId() { + return transactionReferenceId; + } + + public double getAmountToTransfer() { + return amountToTransfer; + } +} +// @@@SNIPEND diff --git a/src/main/java/moneytransfer/MoneyTransferWorkflow.java b/src/main/java/moneytransfer/MoneyTransferWorkflow.java index 159b382..4ffc791 100644 --- a/src/main/java/moneytransfer/MoneyTransferWorkflow.java +++ b/src/main/java/moneytransfer/MoneyTransferWorkflow.java @@ -6,10 +6,9 @@ @WorkflowInterface public interface MoneyTransferWorkflow { - // The Workflow Execution that starts this method can be initiated from code or // from the 'temporal' CLI utility. @WorkflowMethod - void transfer(String fromAccountId, String toAccountId, String referenceId, double amount); + void transfer(TransactionDetails transaction); } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java index bb6e52e..228fcb3 100644 --- a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java +++ b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java @@ -44,9 +44,12 @@ public class MoneyTransferWorkflowImpl implements MoneyTransferWorkflow { // Activity method executions can be orchestrated here or from within // other Activity methods. @Override - public void transfer(String fromAccountId, String toAccountId, String referenceId, double amount) { - accountActivityStub.withdraw(fromAccountId, referenceId, amount); - accountActivityStub.deposit(toAccountId, referenceId, amount); + public void transfer(TransactionDetails transaction) { + System.out.println("Starting"); + accountActivityStub.withdraw(transaction.getSourceAccountId(), transaction.getTransactionReferenceId(), transaction.getAmountToTransfer()); + System.out.println("Working"); + accountActivityStub.deposit(transaction.getDestinationAccountId(), transaction.getTransactionReferenceId(), transaction.getAmountToTransfer()); + System.out.println("Done"); } } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/TransactionDetails.java b/src/main/java/moneytransfer/TransactionDetails.java new file mode 100644 index 0000000..cb97283 --- /dev/null +++ b/src/main/java/moneytransfer/TransactionDetails.java @@ -0,0 +1,13 @@ +// @@@SNIPSTART money-transfer-java-transactionDetails +package moneytransferapp; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(as = CoreTransactionDetails.class) +public interface TransactionDetails { + String getSourceAccountId(); + String getDestinationAccountId(); + String getTransactionReferenceId(); + double getAmountToTransfer(); +} +// @@@SNIPEND + diff --git a/src/main/java/moneytransfer/TransferApp.java b/src/main/java/moneytransfer/TransferApp.java index 9c56929..03b2824 100644 --- a/src/main/java/moneytransfer/TransferApp.java +++ b/src/main/java/moneytransfer/TransferApp.java @@ -6,19 +6,21 @@ import io.temporal.client.WorkflowOptions; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.security.SecureRandom; +import java.time.Instant; import java.util.UUID; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.concurrent.ThreadLocalRandom; -import java.time.Instant; public class TransferApp { - private static final Random random; + private static final SecureRandom random; static { // Seed the random number generator with nano date - random = new Random(Instant.now().getNano()); + random = new SecureRandom(); + random.setSeed(Instant.now().getNano()); } public static String randomAccountIdentifier() { @@ -55,11 +57,11 @@ public static void main(String[] args) throws Exception { String fromAccount = randomAccountIdentifier(); String toAccount = randomAccountIdentifier(); double amountToTransfer = ThreadLocalRandom.current().nextDouble(15.0, 25.0); + TransactionDetails transaction = new CoreTransactionDetails(fromAccount, toAccount, referenceId, amountToTransfer); // Perform asynchronous execution. // This process exits after making this call and printing details. - WorkflowExecution we = WorkflowClient.start( - workflow::transfer, fromAccount, toAccount, referenceId, amountToTransfer); + WorkflowExecution we = WorkflowClient.start(workflow::transfer, transaction); System.out.printf("\nMONEY TRANSFER PROJECT\n\n"); System.out.printf("Initiating transfer of $%.2f from [Account %s] to [Account %s].\n\n", diff --git a/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java b/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java index b8c1ecf..a1ffebb 100644 --- a/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java +++ b/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java @@ -42,7 +42,8 @@ public void testTransfer() { .setTaskQueue(Shared.MONEY_TRANSFER_TASK_QUEUE) .build(); MoneyTransferWorkflow workflow = workflowClient.newWorkflowStub(MoneyTransferWorkflow.class, options); - workflow.transfer("account1", "account2", "reference1", 1.23); + TransactionDetails transaction = new CoreTransactionDetails("account1", "account2", "reference1", 1.23); + workflow.transfer(transaction); verify(activities).withdraw(eq("account1"), eq("reference1"), eq(1.23)); verify(activities).deposit(eq("account2"), eq("reference1"), eq(1.23)); } From 80c4addee7ae3439d05da0a4514270fd1ea77ac2 Mon Sep 17 00:00:00 2001 From: Erica Sadun Date: Tue, 23 Apr 2024 09:12:56 -0600 Subject: [PATCH 3/4] EDU-2293: Update source code for "Run your first app in Java" * Change amount from double to int * Added toggles to control the success of the deposit and refund * Add compensation mechanism to refund failed deposit JIRA: https://temporalio.atlassian.net/browse/EDU-2293 --- .../java/moneytransfer/AccountActivity.java | 4 +- .../moneytransfer/AccountActivityImpl.java | 16 +++-- .../moneytransfer/CoreTransactionDetails.java | 7 +- .../MoneyTransferWorkflowImpl.java | 67 +++++++++++++++++-- .../moneytransfer/TransactionDetails.java | 2 +- src/main/java/moneytransfer/TransferApp.java | 6 +- .../MoneyTransferWorkflowTest.java | 6 +- 7 files changed, 85 insertions(+), 23 deletions(-) diff --git a/src/main/java/moneytransfer/AccountActivity.java b/src/main/java/moneytransfer/AccountActivity.java index dcef4a7..01d3343 100644 --- a/src/main/java/moneytransfer/AccountActivity.java +++ b/src/main/java/moneytransfer/AccountActivity.java @@ -8,10 +8,10 @@ public interface AccountActivity { // Withdraw an amount of money from the source account @ActivityMethod - void withdraw(String accountId, String referenceId, double amount); + void withdraw(String accountId, String referenceId, int amount); // Deposit an amount of money into the destination account @ActivityMethod - void deposit(String accountId, String referenceId, double amount); + void deposit(String accountId, String referenceId, int amount, boolean activityShouldSucceed); } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/AccountActivityImpl.java b/src/main/java/moneytransfer/AccountActivityImpl.java index d2aecb5..da71c20 100644 --- a/src/main/java/moneytransfer/AccountActivityImpl.java +++ b/src/main/java/moneytransfer/AccountActivityImpl.java @@ -1,26 +1,30 @@ // @@@SNIPSTART money-transfer-java-activity-implementation package moneytransferapp; +import io.temporal.activity.*; + public class AccountActivityImpl implements AccountActivity { // Mock up the withdrawal of an amount of money from the source account @Override - public void withdraw(String accountId, String referenceId, double amount) { + public void withdraw(String accountId, String referenceId, int amount) { System.out.printf( - "\nWithdrawing $%.2f from account %s.\n[ReferenceId: %s]\n", + "\nWithdrawing $%d from account %s.\n[ReferenceId: %s]\n", amount, accountId, referenceId ); } // Mock up the deposit of an amount of money from the destination account @Override - public void deposit(String accountId, String referenceId, double amount) { + public void deposit(String accountId, String referenceId, int amount, boolean activityShouldSucceed) { System.out.printf( - "\nDepositing $%.2f into account %s.\n[ReferenceId: %s]\n", + "\nDepositing $%d into account %s.\n[ReferenceId: %s]\n", amount, accountId, referenceId ); - // TO SIMULATE AN ACTIVITY ERROR: Uncomment the following line - // throw Activity.wrap(new RuntimeException("Simulated Activity error")); + if (!activityShouldSucceed) { + System.out.println("Deposit failed"); + throw Activity.wrap(new RuntimeException("Simulated Activity error during deposit of funds")); + } } } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/CoreTransactionDetails.java b/src/main/java/moneytransfer/CoreTransactionDetails.java index db4b25e..fbc3a1f 100644 --- a/src/main/java/moneytransfer/CoreTransactionDetails.java +++ b/src/main/java/moneytransfer/CoreTransactionDetails.java @@ -5,7 +5,7 @@ public class CoreTransactionDetails implements TransactionDetails { private String sourceAccountId; private String destinationAccountId; private String transactionReferenceId; - private double amountToTransfer; + private int amountToTransfer; // MARK: Constructor @@ -16,7 +16,8 @@ public CoreTransactionDetails() { public CoreTransactionDetails(String sourceAccountId, String destinationAccountId, String transactionReferenceId, - double amountToTransfer) { + int amountToTransfer) + { this.sourceAccountId = sourceAccountId; this.destinationAccountId = destinationAccountId; this.transactionReferenceId = transactionReferenceId; @@ -37,7 +38,7 @@ public String getTransactionReferenceId() { return transactionReferenceId; } - public double getAmountToTransfer() { + public int getAmountToTransfer() { return amountToTransfer; } } diff --git a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java index 228fcb3..8df9dba 100644 --- a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java +++ b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java @@ -45,11 +45,68 @@ public class MoneyTransferWorkflowImpl implements MoneyTransferWorkflow { // other Activity methods. @Override public void transfer(TransactionDetails transaction) { - System.out.println("Starting"); - accountActivityStub.withdraw(transaction.getSourceAccountId(), transaction.getTransactionReferenceId(), transaction.getAmountToTransfer()); - System.out.println("Working"); - accountActivityStub.deposit(transaction.getDestinationAccountId(), transaction.getTransactionReferenceId(), transaction.getAmountToTransfer()); - System.out.println("Done"); + String sourceAccountId = transaction.getSourceAccountId(); + String destinationAccountId = transaction.getDestinationAccountId(); + String transactionReferenceId = transaction.getTransactionReferenceId(); + int amountToTransfer = transaction.getAmountToTransfer(); + + try { + accountActivityStub.withdraw(sourceAccountId, transactionReferenceId, amountToTransfer); + } catch (Exception e) { + // If the withdrawal fails, for any exception + System.out.printf("[%s] Withdrawal of $%d from account %s failed", + transactionReferenceId, amountToTransfer, sourceAccountId); + System.out.flush(); + + // Transaction ends here + return; + } + + // Change this from true to false to force the deposit to fail + boolean transferShouldSucceed = true; + + try { + accountActivityStub.deposit(destinationAccountId, transactionReferenceId, amountToTransfer, transferShouldSucceed); + + // Successful. Transaction ends here + System.out.printf("[%s] Transaction succeeded.\n", transactionReferenceId); + System.out.flush(); + return; + } catch (Exception e) { + // If the deposit fails, for any exception + System.out.printf("[%s] Deposit of $%d to account %s failed.\n", + transactionReferenceId, amountToTransfer, destinationAccountId); + System.out.flush(); + } + + // Continue by reversing transaction + + // Change this from true to false to force the recovery compensation to fail + boolean refundShouldSucceed = true; + + try { + // Refund the withdrawal + System.out.printf("[%s] Refunding $%d to account %s.\n", + transactionReferenceId, amountToTransfer, destinationAccountId); + System.out.flush(); + accountActivityStub.deposit(sourceAccountId, transactionReferenceId, amountToTransfer, refundShouldSucceed); + + // Recovery successful. Transaction ends here + System.out.printf("[%s] Refund to originating account was successful.\n", + transactionReferenceId); + System.out.printf("[%s] Transaction is complete. No transfer made.\n", + transactionReferenceId); + return; + } catch (Exception e) { + // A recovery mechanism can fail too. Handle any exception + System.out.printf("[%s] Deposit of $%d to account %s failed. Did not compensate withdrawal.\n", + transactionReferenceId, amountToTransfer, destinationAccountId); + System.out.flush(); + } + + System.out.printf("[%s] Ended transaction in inconsistent state.\n", + transactionReferenceId); + System.out.flush(); } } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/TransactionDetails.java b/src/main/java/moneytransfer/TransactionDetails.java index cb97283..6ad1893 100644 --- a/src/main/java/moneytransfer/TransactionDetails.java +++ b/src/main/java/moneytransfer/TransactionDetails.java @@ -7,7 +7,7 @@ public interface TransactionDetails { String getSourceAccountId(); String getDestinationAccountId(); String getTransactionReferenceId(); - double getAmountToTransfer(); + int getAmountToTransfer(); } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/TransferApp.java b/src/main/java/moneytransfer/TransferApp.java index 03b2824..42c9832 100644 --- a/src/main/java/moneytransfer/TransferApp.java +++ b/src/main/java/moneytransfer/TransferApp.java @@ -24,7 +24,7 @@ public class TransferApp { } public static String randomAccountIdentifier() { - return IntStream.range(0, 11) + return IntStream.range(0, 9) .mapToObj(i -> String.valueOf(random.nextInt(10))) .collect(Collectors.joining()); } @@ -56,7 +56,7 @@ public static void main(String[] args) throws Exception { String referenceId = UUID.randomUUID().toString().substring(0, 18); String fromAccount = randomAccountIdentifier(); String toAccount = randomAccountIdentifier(); - double amountToTransfer = ThreadLocalRandom.current().nextDouble(15.0, 25.0); + int amountToTransfer = ThreadLocalRandom.current().nextInt(15, 75); TransactionDetails transaction = new CoreTransactionDetails(fromAccount, toAccount, referenceId, amountToTransfer); // Perform asynchronous execution. @@ -64,7 +64,7 @@ public static void main(String[] args) throws Exception { WorkflowExecution we = WorkflowClient.start(workflow::transfer, transaction); System.out.printf("\nMONEY TRANSFER PROJECT\n\n"); - System.out.printf("Initiating transfer of $%.2f from [Account %s] to [Account %s].\n\n", + System.out.printf("Initiating transfer of $%d from [Account %s] to [Account %s].\n\n", amountToTransfer, fromAccount, toAccount); System.out.printf("[WorkflowID: %s]\n[RunID: %s]\n\n", we.getWorkflowId(), we.getRunId()); System.exit(0); diff --git a/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java b/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java index a1ffebb..ed08346 100644 --- a/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java +++ b/src/test/java/moneytransfer/MoneyTransferWorkflowTest.java @@ -42,10 +42,10 @@ public void testTransfer() { .setTaskQueue(Shared.MONEY_TRANSFER_TASK_QUEUE) .build(); MoneyTransferWorkflow workflow = workflowClient.newWorkflowStub(MoneyTransferWorkflow.class, options); - TransactionDetails transaction = new CoreTransactionDetails("account1", "account2", "reference1", 1.23); + TransactionDetails transaction = new CoreTransactionDetails("account1", "account2", "reference1", 10); workflow.transfer(transaction); - verify(activities).withdraw(eq("account1"), eq("reference1"), eq(1.23)); - verify(activities).deposit(eq("account2"), eq("reference1"), eq(1.23)); + verify(activities).withdraw(eq("account1"), eq("reference1"), eq(10)); + // Cannot reliably test deposit as the failure configurations will affect this } } // @@@SNIPEND From 774903e6cd962a4d863e50352970fe9b17c731e5 Mon Sep 17 00:00:00 2001 From: Erica Sadun Date: Thu, 2 May 2024 09:04:18 -0600 Subject: [PATCH 4/4] EDU-2293: updated to rethrow exception in Workflow fail case JIRA: https://temporalio.atlassian.net/browse/EDU-2293 --- .../MoneyTransferWorkflowImpl.java | 8 ++++---- src/main/java/moneytransfer/TransferApp.java | 2 +- workflow_input.png | Bin 0 -> 46597 bytes 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 workflow_input.png diff --git a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java index 8df9dba..dcee294 100644 --- a/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java +++ b/src/main/java/moneytransfer/MoneyTransferWorkflowImpl.java @@ -101,12 +101,12 @@ public void transfer(TransactionDetails transaction) { // A recovery mechanism can fail too. Handle any exception System.out.printf("[%s] Deposit of $%d to account %s failed. Did not compensate withdrawal.\n", transactionReferenceId, amountToTransfer, destinationAccountId); + System.out.printf("[%s] Workflow failed.", transactionReferenceId); System.out.flush(); - } - System.out.printf("[%s] Ended transaction in inconsistent state.\n", - transactionReferenceId); - System.out.flush(); + // Rethrowing the exception causes a Workflow Task failure + throw(e); + } } } // @@@SNIPEND diff --git a/src/main/java/moneytransfer/TransferApp.java b/src/main/java/moneytransfer/TransferApp.java index 42c9832..b9a3d61 100644 --- a/src/main/java/moneytransfer/TransferApp.java +++ b/src/main/java/moneytransfer/TransferApp.java @@ -66,7 +66,7 @@ public static void main(String[] args) throws Exception { System.out.printf("\nMONEY TRANSFER PROJECT\n\n"); System.out.printf("Initiating transfer of $%d from [Account %s] to [Account %s].\n\n", amountToTransfer, fromAccount, toAccount); - System.out.printf("[WorkflowID: %s]\n[RunID: %s]\n\n", we.getWorkflowId(), we.getRunId()); + System.out.printf("[WorkflowID: %s]\n[RunID: %s]\n[Transaction Reference: %s]\n\n", we.getWorkflowId(), we.getRunId(), referenceId); System.exit(0); } } diff --git a/workflow_input.png b/workflow_input.png new file mode 100644 index 0000000000000000000000000000000000000000..50ec31af8170eeab52f139b8b0b203735fd2fec0 GIT binary patch literal 46597 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 literal 0 HcmV?d00001