예제 #1
0
        /// <summary>
        /// Calls <see cref="IAggregateFactory.Create"/> to get a, <typeparamref name="TSaga"/>.
        /// </summary>
        /// <typeparam name="TSaga">The <see cref="Type"/> of <see cref="ISaga{TAuthenticationToken}"/>.</typeparam>
        /// <param name="id">The id of the <typeparamref name="TSaga"/> to create.</param>
        protected virtual TSaga CreateSaga <TSaga>(Guid id)
            where TSaga : ISaga <TAuthenticationToken>
        {
            var saga = SagaFactory.Create <TSaga>(id);

            return(saga);
        }
예제 #2
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);
        }
예제 #4
0
        /// <summary>
        /// Calls <see cref="IAggregateFactory.Create"/> to get a, <typeparamref name="TSaga"/> and then calls <see cref="LoadSagaHistory{TSaga}"/>.
        /// </summary>
        /// <typeparam name="TSaga">The <see cref="Type"/> of <see cref="ISaga{TAuthenticationToken}"/>.</typeparam>
        /// <param name="id">The id of the <typeparamref name="TSaga"/> to create.</param>
        /// <param name="events">
        /// A collection of <see cref="IEvent{TAuthenticationToken}"/> to replay on the retrieved <see cref="ISaga{TAuthenticationToken}"/>.
        /// If null, the <see cref="IEventStore{TAuthenticationToken}"/> will be used to retrieve a list of <see cref="IEvent{TAuthenticationToken}"/> for you.
        /// </param>
        protected virtual TSaga LoadSaga <TSaga>(Guid id, IList <ISagaEvent <TAuthenticationToken> > events = null)
            where TSaga : ISaga <TAuthenticationToken>
        {
            var saga = SagaFactory.Create <TSaga>(id);

            LoadSagaHistory(saga, events);
            return(saga);
        }
예제 #5
0
        /// <summary>
        /// Calls <see cref="IAggregateFactory.Create"/> to get a, <typeparamref name="TSaga"/>.
        /// </summary>
        /// <typeparam name="TSaga">The <see cref="Type"/> of <see cref="ISaga{TAuthenticationToken}"/>.</typeparam>
        /// <param name="id">The id of the <typeparamref name="TSaga"/> to create.</param>
        protected override TSaga CreateSaga <TSaga>(Guid id)
        {
            var saga = SagaFactory.Create <TSaga>();

            return(saga);
        }