private async Task <IActionResult> Process(Guid id, int revision, string verb, TransactionStatus state, int timeout)
        {
            var         factory = new TransactionFactory(this.storage);
            Transaction trans;

            try
            {
                trans = await factory.ContinueTransactionAsync(id, revision);
            }
            catch (TransactionConflictException)
            {
                return(new StatusCodeResult(409));
            }
            catch (TransactionMissingException)
            {
                return(this.NotFound());
            }

            Task <Transaction> waitTask;

            try
            {
                var delta = await trans.CreateDelta(revision, false, (ref TransactionMutableData data) =>
                {
                    data.Expires = DateTime.UtcNow;
                    data.Script  = $"Handler.{verb}(Transaction);";
                });

                waitTask = this.storage.WaitForAsync(x => x.Id == id && (x.Status == state || x.Status == TransactionStatus.Failed), timeout);
            }
            finally
            {
                await trans.Free();
            }

            if (timeout == 0)
            {
                return(new StatusCodeResult(202));
            }

            var transaction = await waitTask;

            if (transaction == null)
            {
                return(new StatusCodeResult(202));
            }

            return(this.Created(this.Url.RouteUrl("TransactionGetRevision", new { id = transaction.Id, revision = transaction.Revision }), TransactionMapper.ToTransactionResult(transaction)));
        }
Exemple #2
0
        public async Task <IActionResult> Post(Guid id, [FromRoute] int?revision, [FromBody] IDictionary <string, object> model)
        {
            var factory = new TransactionFactory(this.storage);

            Transaction trans;

            if (revision != null)
            {
                trans = await factory.ContinueTransactionAsync(id, (int)revision, -1);
            }
            else
            {
                trans = await factory.ContinueTransactionAsync(id);
            }

            Transaction result;

            try
            {
                DateTime?expires;
                if (model.ContainsKey("expires"))
                {
                    if (model["expires"] == null)
                    {
                        expires = null;
                    }
                    else
                    {
                        if (model["expires"] is DateTime)
                        {
                            expires = (DateTime)model["expires"];
                        }
                        else if (!DateTimeParser.TryParseDateTime(model["expires"] as string, out expires))
                        {
                            return(this.BadRequest("The specified expiration date could not be parsed as standard ISO UTC time."));
                        }
                    }
                }
                else
                {
                    expires = trans.Expires;
                }

                TransactionStatus state;

                if (model.ContainsKey("state"))
                {
                    if (!Enum.TryParse((string)model["state"], false, out state))
                    {
                        return(this.BadRequest("Could not parse transaction state."));
                    }
                }
                else
                {
                    state = trans.Status;
                }

                result = await trans.CreateDelta(trans.Revision + 1, false, (ref TransactionMutableData data) =>
                {
                    data.Expires = expires;
                    data.Payload = model.ContainsKey("payload") ? model["payload"] : trans.Payload;
                    data.Script  = model.ContainsKey("script") ? model["script"] as string : trans.Script;
                    data.Status  = state;
                });
            }
            finally
            {
                await trans.Free();
            }

            return(this.Created(this.Url.RouteUrl("TransactionGet", new { id = result.Id }), result.ToTransactionResult()));
        }