示例#1
0
 public void Close()
 {
     lock (ConcurrencyLock)
     {
         _state = BankAccountState.Closed;
     }
 }
示例#2
0
 public void Open()
 {
     lock (ConcurrencyLock)
     {
         _state = BankAccountState.Open;
     }
 }
示例#3
0
 public BankAccount(long id, String number, Decimal balance, OverdraftPolicy overdraftPolicy, BankAccountState state)
 {
     this.id              = id;
     this.number          = number;
     this.Balance         = balance;
     this.overdraftPolicy = overdraftPolicy;
     this.state           = state;
 }
示例#4
0
        /// <summary>
        /// Initialize the state.
        /// TODO: isolate the State object in 3 differnt buckets: base info, operations, standing orders.
        /// This will improve perf in serialize/deserialize
        /// </summary>
        public Task InitializeState(string accountOwner, double openingBalance)
        {
            ActorEventSource.Current.ActorMessage(this, "@BankAccount.InitializeState for account '{0}'", Id.GetStringId());

            BankAccountState state = new BankAccountState();

            state.AccountNumber = Id.GetStringId(); // accountNumber;
            state.CustomerName  = accountOwner;
            state.Balance       = openingBalance;

            state.LastOperations = new List <Operation>();
            state.StandingOrders = new List <StandingOrder>();

            // inconditional set of data in instance's state
            return(StateManager.SetStateAsync("AccountState", state));
        }
示例#5
0
        /// <summary>
        /// Add a standing order to a given account
        /// </summary>
        public async Task AddStandingOrder(string toAccount, double amount, short minute)
        {
            ActorEventSource.Current.ActorMessage(this, "@BankAccount.AddStandingOrder for account '{0}', min = {1}", Id.GetStringId(), minute);

            BankAccountState state = await StateManager.GetStateAsync <BankAccountState>("AccountState");

            state.StandingOrders.Add(new StandingOrder
            {
                Amount           = amount,
                ToAccountNumber  = toAccount,
                RecurrenceMinute = minute
            });

            StateManager.SetStateAsync("AccountState", state).GetAwaiter().GetResult(); // could have just returned thread here -- testing

            return;
        }
示例#6
0
        /// <summary>
        /// Actor's Reminder - 1 hearbeat per minute
        /// </summary>
        public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period)
        {
            if (reminderName.Equals("process standing orders"))
            {
                BankAccountState state = StateManager.GetStateAsync <BankAccountState>("AccountState").GetAwaiter().GetResult();

                DateTime now = DateTime.Now;

                foreach (StandingOrder so in state.StandingOrders)
                {
                    if (so.RecurrenceMinute == now.Minute)
                    {
                        ActorEventSource.Current.ActorMessage(this, "@BankAccount.ReceiveReminderAsync paying from '{0}' to '{1}': €{2:f2}", Id.GetStringId(), so.ToAccountNumber, so.Amount);

                        // time to pay, says Roy Batty
                        Random r = new Random();
                        int    newOperationId = r.Next(0, int.MaxValue);

                        // remove money from this account
                        state.Balance -= so.Amount;

                        state.LastOperations.Add(new Operation
                        {
                            AccountNumber = so.ToAccountNumber,
                            Amount        = -so.Amount,
                            When          = now,
                            OperationId   = newOperationId
                        });

                        await StateManager.SetStateAsync("AccountState", state); // test if it can cause issues: mutiple payments in same account/minute?

                        // send money to target account
                        IBankAccount accountProxy = ActorProxy.Create <IBankAccount>(new ActorId(so.ToAccountNumber), "fabric:/SFActors.BankAccounts");
                        await accountProxy.Transfer(Id.GetStringId(), so.Amount, now, newOperationId);
                    }
                }
            }

            return;
        }
示例#7
0
        /// <summary>
        /// Receive a payment from another Actor or client
        /// </summary>
        public async Task <bool> Transfer(string sourceAccount, double amount, DateTime when, int uniqueOperationId)
        {
            ActorEventSource.Current.ActorMessage(this, "@BankAccount.Transfer for account '{0}' of {1}", Id.GetStringId(), amount);

            BankAccountState state = await StateManager.GetStateAsync <BankAccountState>("AccountState");

            // idempotency protection for repeated messages
            foreach (Operation op in state.LastOperations)
            {
                if (op.OperationId == uniqueOperationId)
                {
                    return(false);
                }
            }

            // validate positive amount (we are receiving money)
            if (amount <= 0)
            {
                return(false);
            }

            // accept the money :-)
            state.LastOperations.Add(new Operation
            {
                AccountNumber = sourceAccount,
                Amount        = amount,
                When          = when,
                OperationId   = uniqueOperationId
            });

            state.Balance += amount;

            await StateManager.SetStateAsync("AccountState", state);

            return(true);
        }
 //-------------------------------------------------------------------------
 public void ChangeState(BankAccountState aBankAcountState)
 {
     AccountState = aBankAcountState;
 }
示例#9
0
 public void setState(BankAccountState state)
 {
     this.state = state;
 }
示例#10
0
 public override BankAccountState ApplyTo(BankAccountState state) => state;
示例#11
0
 public abstract BankAccountState ApplyTo(BankAccountState state);
示例#12
0
 public override BankAccountState ApplyTo(BankAccountState state) => state.WithFrozen(false);
示例#13
0
 public void ChangeState(BankAccountState newState)
 {
     AccountState = newState;
 }
示例#14
0
 public override BankAccountState ApplyTo(BankAccountState state)
 => state.WithBalance(AmountDeposited + state.CurrentBalance);