|
| 1 | +package com.example; |
| 2 | + |
| 3 | +import com.microsoft.durabletask.AbstractTaskEntity; |
| 4 | +import com.microsoft.durabletask.EntityInstanceId; |
| 5 | +import com.microsoft.durabletask.TaskEntityOperation; |
| 6 | + |
| 7 | +import java.util.logging.Logger; |
| 8 | + |
| 9 | +/** |
| 10 | + * A durable entity that maintains a bank account balance. |
| 11 | + * <p> |
| 12 | + * Supports operations: deposit, withdraw, getBalance, reset. |
| 13 | + * <p> |
| 14 | + * Demonstrates: |
| 15 | + * - Entities signaling other entities: when a deposit exceeds a threshold, the account |
| 16 | + * signals an "Audit" entity to log the transaction. |
| 17 | + * - Entities starting orchestrations: when a large withdrawal occurs, the account |
| 18 | + * starts an audit orchestration. |
| 19 | + */ |
| 20 | +public class AccountEntity extends AbstractTaskEntity<Integer> { |
| 21 | + private static final Logger logger = Logger.getLogger(AccountEntity.class.getName()); |
| 22 | + private static final int LARGE_TRANSACTION_THRESHOLD = 500; |
| 23 | + |
| 24 | + @Override |
| 25 | + protected Integer initializeState(TaskEntityOperation operation) { |
| 26 | + return 0; |
| 27 | + } |
| 28 | + |
| 29 | + @Override |
| 30 | + protected Class<Integer> getStateType() { |
| 31 | + return Integer.class; |
| 32 | + } |
| 33 | + |
| 34 | + /** |
| 35 | + * Deposits funds into this account. |
| 36 | + * If the deposit amount exceeds the threshold, this entity signals an audit entity |
| 37 | + * to record the large transaction (entity-to-entity signaling). |
| 38 | + */ |
| 39 | + public void deposit(int amount) { |
| 40 | + this.state += amount; |
| 41 | + String key = this.context.getId().getKey(); |
| 42 | + logger.info(String.format("Account '%s': Deposited %d, new balance: %d", key, amount, this.state)); |
| 43 | + |
| 44 | + // Entity signals another entity: notify the audit entity of large deposits |
| 45 | + if (amount >= LARGE_TRANSACTION_THRESHOLD) { |
| 46 | + EntityInstanceId auditEntityId = new EntityInstanceId("Audit", "ledger"); |
| 47 | + String message = String.format("Large deposit of %d into account '%s'", amount, key); |
| 48 | + this.context.signalEntity(auditEntityId, "record", message); |
| 49 | + logger.info(String.format("Account '%s': Signaled audit entity for large deposit of %d", key, amount)); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + /** |
| 54 | + * Withdraws funds from this account. |
| 55 | + * If the withdrawal amount exceeds the threshold, this entity starts an audit |
| 56 | + * orchestration to process the large withdrawal (entity starting an orchestration). |
| 57 | + */ |
| 58 | + public void withdraw(int amount) { |
| 59 | + this.state -= amount; |
| 60 | + String key = this.context.getId().getKey(); |
| 61 | + logger.info(String.format("Account '%s': Withdrew %d, new balance: %d", key, amount, this.state)); |
| 62 | + |
| 63 | + // Entity starts a new orchestration: trigger an audit workflow for large withdrawals |
| 64 | + if (amount >= LARGE_TRANSACTION_THRESHOLD) { |
| 65 | + String auditInput = String.format("Large withdrawal of %d from account '%s', remaining balance: %d", |
| 66 | + amount, key, this.state); |
| 67 | + String instanceId = this.context.startNewOrchestration("AuditOrchestration", auditInput); |
| 68 | + logger.info(String.format("Account '%s': Started AuditOrchestration '%s' for large withdrawal of %d", |
| 69 | + key, instanceId, amount)); |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + public int getBalance() { |
| 74 | + logger.info(String.format("Account '%s': Current balance: %d", |
| 75 | + this.context.getId().getKey(), this.state)); |
| 76 | + return this.state; |
| 77 | + } |
| 78 | + |
| 79 | + public void reset() { |
| 80 | + this.state = 0; |
| 81 | + logger.info(String.format("Account '%s': Reset to 0", |
| 82 | + this.context.getId().getKey())); |
| 83 | + } |
| 84 | +} |
0 commit comments