示例#1
0
        public static async Task SagaOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context,
            ILogger log)
        {
            TransactionItem item = context.GetInput <TransactionItem>();

            var commandProducers = new Dictionary <string, Func <Task <ActivityResult <ProducerResult> > > >
            {
                [nameof(ValidateTransferCommand)] = () => ActivityFactory.ProduceValidateTransferCommandAsync(item, context, log),
                [nameof(TransferCommand)]         = () => ActivityFactory.ProduceTransferCommandAsync(item, context, log),
                [nameof(CancelTransferCommand)]   = () => ActivityFactory.ProduceCancelTransferCommandAsync(item, context, log),
                [nameof(IssueReceiptCommand)]     = () => ActivityFactory.ProduceIssueReceiptCommandAsync(item, context, log)
            };

            var sagaStatePersisters = new Dictionary <string, Func <Task <bool> > >
            {
                [nameof(SagaState.Pending)]   = () => SagaFactory.PersistSagaStateAsync(item, SagaState.Pending, context, log),
                [nameof(SagaState.Success)]   = () => SagaFactory.PersistSagaStateAsync(item, SagaState.Success, context, log),
                [nameof(SagaState.Cancelled)] = () => SagaFactory.PersistSagaStateAsync(item, SagaState.Cancelled, context, log),
                [nameof(SagaState.Fail)]      = () => SagaFactory.PersistSagaStateAsync(item, SagaState.Fail, context, log),
            };

            try
            {
                var       orchestrator = new DurableOrchestrator(commandProducers, sagaStatePersisters);
                SagaState sagaState    = await orchestrator.OrchestrateAsync(item, context, log);

                log.LogInformation($@"Saga state = {nameof(sagaState)} [{context.InstanceId}]");
            }
            catch (ArgumentException ex)
            {
                log.LogError(ex.Message);
            }
        }
        public async Task Failed_saga_should_be_persisted()
        {
            var mockContext = new Mock <IDurableOrchestrationContext>();
            var loggerMock  = new Mock <ILogger>();

            var retryOptions = new RetryOptions(
                firstRetryInterval: TimeSpan.FromSeconds(5),
                maxNumberOfAttempts: 3);

            var item = new TransactionItem
            {
                Id            = Guid.NewGuid().ToString(),
                AccountFromId = Guid.NewGuid().ToString(),
                AccountToId   = Guid.NewGuid().ToString(),
                Amount        = 100.00M,
                State         = SagaState.Pending.ToString()
            };

            var activity = new Activity <TransactionItem>
            {
                FunctionName = nameof(OrchestratorActivity.SagaOrchestratorActivity),
                Input        = item,
                Context      = mockContext.Object
            };

            mockContext
            .Setup(x => x.CallActivityWithRetryAsync <TransactionItem>(activity.FunctionName, retryOptions, activity.Input))
            .ReturnsAsync(item);

            var result = await SagaFactory.PersistSagaStateAsync(item, SagaState.Fail, mockContext.Object, loggerMock.Object);

            Assert.True(result);
        }