static Entry GetEntry(ReadOnlyContextBag context, Guid sagaDataId)
 {
     if (context.TryGet(ContextKey, out Dictionary <Guid, Entry> entries))
     {
         if (entries.TryGetValue(sagaDataId, out var entry))
         {
             return(entry);
         }
     }
     throw new Exception("The saga should be retrieved with Get method before it's updated");
 }
Example #2
0
        /// <summary>
        /// Initializes the error context.
        /// </summary>
        /// <param name="exception">The exception that caused the message processing failure.</param>
        /// <param name="headers">The message headers.</param>
        /// <param name="transportMessageId">Native message id.</param>
        /// <param name="body">The message body.</param>
        /// <param name="transportTransaction">Transaction (along with connection if applicable) used to receive the message.</param>
        /// <param name="immediateProcessingFailures">Number of failed immediate processing attempts.</param>
        /// <param name="context">A <see cref="ReadOnlyContextBag" /> which can be used to extend the current object.</param>
        public ErrorContext(Exception exception, Dictionary <string, string> headers, string transportMessageId, byte[] body, TransportTransaction transportTransaction, int immediateProcessingFailures, ReadOnlyContextBag context)
        {
            Exception                   = exception;
            TransportTransaction        = transportTransaction;
            ImmediateProcessingFailures = immediateProcessingFailures;

            Message = new IncomingMessage(transportMessageId, headers, body);

            DelayedDeliveriesPerformed = Message.GetDelayedDeliveriesPerformed();
            Extensions = context;
        }
Example #3
0
        /// <summary>
        /// Initializes the error context.
        /// </summary>
        /// <param name="exception">The exception that caused the message processing failure.</param>
        /// <param name="headers">The message headers.</param>
        /// <param name="nativeMessageId">The native message ID.</param>
        /// <param name="body">The message body.</param>
        /// <param name="transportTransaction">Transaction (along with connection if applicable) used to receive the message.</param>
        /// <param name="immediateProcessingFailures">Number of failed immediate processing attempts.</param>
        /// <param name="context">A <see cref="ReadOnlyContextBag" /> which can be used to extend the current object.</param>
        public ErrorContext(Exception exception, Dictionary <string, string> headers, string nativeMessageId, byte[] body, TransportTransaction transportTransaction, int immediateProcessingFailures, ReadOnlyContextBag context)
        {
            Guard.AgainstNull(nameof(exception), exception);
            Guard.AgainstNull(nameof(transportTransaction), transportTransaction);
            Guard.AgainstNegative(nameof(immediateProcessingFailures), immediateProcessingFailures);
            Guard.AgainstNull(nameof(context), context);

            Exception                   = exception;
            TransportTransaction        = transportTransaction;
            ImmediateProcessingFailures = immediateProcessingFailures;

            Message = new IncomingMessage(nativeMessageId, headers, body);

            DelayedDeliveriesPerformed = Message.GetDelayedDeliveriesPerformed();
            Extensions = context;
        }
Example #4
0
        /// <summary>
        /// Initializes the context.
        /// </summary>
        /// <param name="nativeMessageId">The native message ID.</param>
        /// <param name="wasAcknowledged">True if the message was acknowledged and removed from the queue.</param>
        /// <param name="headers">The message headers.</param>
        /// <param name="startedAt">The time that processing started.</param>
        /// <param name="completedAt">The time that processing started.</param>
        /// <param name="onMessageFailed"><c>true</c> if the call to <see cref="OnMessage"/> threw an exception.</param>
        /// <param name="context">A <see cref="ReadOnlyContextBag" /> containing the context for the message receive operation.</param>
        public CompleteContext(string nativeMessageId, bool wasAcknowledged, Dictionary <string, string> headers, DateTimeOffset startedAt, DateTimeOffset completedAt, bool onMessageFailed, ReadOnlyContextBag context)
        {
            Guard.AgainstNullAndEmpty(nameof(nativeMessageId), nativeMessageId);
            Guard.AgainstNull(nameof(headers), headers);
            Guard.AgainstNull(nameof(startedAt), startedAt);
            Guard.AgainstNull(nameof(completedAt), completedAt);
            Guard.AgainstNull(nameof(context), context);

            NativeMessageId = nativeMessageId;
            WasAcknowledged = wasAcknowledged;
            Headers         = headers;
            StartedAt       = startedAt;
            CompletedAt     = completedAt;
            OnMessageFailed = onMessageFailed;
            Extensions      = context;
        }
            public Task <TestSaga.SagaData> FindBy(StartSagaMessage message, SynchronizedStorageSession session, ReadOnlyContextBag context)
            {
                Context.StartSagaFinderUsed = true;

                return(session.GetSagaData <TestSaga.SagaData>(
                           context: context,
                           whereClause: "json_value(Data,'$.Property') = @propertyValue",
                           appendParameters: (builder, append) =>
                {
                    var parameter = builder();
                    parameter.ParameterName = "propertyValue";
                    parameter.Value = "Test";
                    append(parameter);
                }));
            }
Example #6
0
            public Task <MySagaData> FindBy(MyMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
            {
                //your custom finding logic here, e.g.
                ISession   nhibernateSession = storageSession.Session();
                MySagaData sagaData          = nhibernateSession.QueryOver <MySagaData>()
                                               .Where(x =>
                                                      x.SomeID == message.SomeID &&
                                                      x.SomeData == message.SomeData)
                                               .SingleOrDefault();

                return(Task.FromResult(sagaData));
            }
 public Task <TestSaga.SagaData> FindBy(StartSagaMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context, CancellationToken cancellationToken = default)
 {
     return(null);
 }
Example #8
0
            public Task <TestSaga.SagaData> FindBy(SomeOtherMessage message, SynchronizedStorageSession session, ReadOnlyContextBag context, CancellationToken cancellationToken = default)
            {
                testContext.FinderUsed = true;

                return(session.GetSagaData <TestSaga.SagaData>(
                           context: context,
                           whereClause: @"""Data""->>'Property' ='Test'",
                           appendParameters: (builder, append) =>
                {
                    var parameter = builder();
                    parameter.ParameterName = "propertyValue";
                    parameter.Value = "Test";
                    append(parameter);
                }, cancellationToken));
            }
 public Task <TestSaga07.SagaData07> FindBy(StartSagaMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context, CancellationToken cancellationToken)
 {
     testContext.ContextBag = context;
     testContext.FinderUsed = true;
     return(Task.FromResult(default(TestSaga07.SagaData07)));
 }
Example #10
0
    public Task <OrderSagaData> FindBy(CompleteOrder message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
    {
        var orderSagaData = storageSession.Session().QueryOver <OrderSagaData>()
                            .Where(d => d.OrderId == message.OrderId)
                            .SingleOrDefault();

        return(Task.FromResult(orderSagaData));
    }
Example #11
0
 public Task <SagaWithoutCorrelationPropertyData> FindBy(SagaWithoutCorrelationPropertyStartingMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context, CancellationToken cancellationToken = default)
 {
     return(Task.FromResult(sagaToFind));
 }
 public Task <SagaData> FindBy(SomeMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context, CancellationToken cancellationToken = default)
 {
     return(Task.FromResult(default(SagaData)));
 }
Example #13
0
    public Task <OrderSagaData> FindBy(StartOrder message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
    {
        var session = storageSession.RavenSession();

        // if the instance is null a new saga will be automatically created if
        // the Saga handles the message as IAmStartedByMessages<StartOrder>; otherwise an exception is raised.
        return(session.LoadByUniqueConstraintAsync <OrderSagaData>(d => d.OrderId, message.OrderId));
    }
Example #14
0
                public Task <TestSaga08.SagaData08> FindBy(SomeOtherMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
                {
                    Context.FinderUsed = true;
                    var bag = new ContextBag();

                    bag.Set(context.Get <IncomingMessage>());
                    return(SagaPersister.Get <TestSaga08.SagaData08>("Property", "Test", storageSession, bag));
                }
Example #15
0
        /// <summary>
        /// Retrieves a <see cref="IContainSagaData"/> instance. Used when implementing a <see cref="IFindSagas{T}"/>.
        /// </summary>
        /// <typeparam name="TSagaData">The <see cref="IContainSagaData"/> type to return.</typeparam>
        /// <param name="session">Used to provide an extension point and access the current <see cref="DbConnection"/> and <see cref="DbTransaction"/>.</param>
        /// <param name="context">Used to append a concurrency value that can be verified when the SagaData is persisted.</param>
        /// <param name="whereClause">The SQL where clause to append to the retrieve saga SQL statement.</param>
        /// <param name="appendParameters">Used to append <see cref="DbParameter"/>s used in the <paramref name="whereClause"/>.</param>
        public static Task <TSagaData> GetSagaData <TSagaData>(this SynchronizedStorageSession session, ReadOnlyContextBag context, string whereClause, ParameterAppender appendParameters)
            where TSagaData : class, IContainSagaData
        {
            Guard.AgainstNull(nameof(session), session);
            Guard.AgainstNull(nameof(context), context);
            Guard.AgainstNull(nameof(appendParameters), appendParameters);
            Guard.AgainstNullAndEmpty(nameof(whereClause), whereClause);
            var writableContextBag = (ContextBag)context;
            var sqlSession         = session.GetSqlStorageSession();

            return(SagaPersister.GetByWhereClause <TSagaData>(whereClause, session, writableContextBag, appendParameters, sqlSession.InfoCache));
        }
        /// <summary>
        /// Retrieves a <see cref="IContainSagaData"/> instance. Used when implementing a <see cref="IFindSagas{T}"/>.
        /// </summary>
        /// <typeparam name="TSagaData">The <see cref="IContainSagaData"/> type to return.</typeparam>
        /// <param name="session">Used to provide an extension point and access the current <see cref="DbConnection"/> and <see cref="DbTransaction"/>.</param>
        /// <param name="context">Used to append a concurrency value that can be verified when the SagaData is persisted.</param>
        /// <param name="whereClause">The SQL where clause to append to the retrieve saga SQL statement.</param>
        /// <param name="appendParameters">Used to append <see cref="DbParameter"/>s used in the <paramref name="whereClause"/>.</param>
        public static Task <TSagaData> GetSagaData <TSagaData>(this SynchronizedStorageSession session, ReadOnlyContextBag context, string whereClause, ParameterAppender appendParameters)
            where TSagaData : class, IContainSagaData
        {
            Guard.AgainstNull(nameof(session), session);
            Guard.AgainstNull(nameof(context), context);
            Guard.AgainstNull(nameof(appendParameters), appendParameters);
            Guard.AgainstNullAndEmpty(nameof(whereClause), whereClause);

            var writableContextBag = (ContextBag)context;
            var sqlSession         = session.GetSqlStorageSession();

            if (sqlSession.InfoCache == null)
            {
                throw new Exception("Cannot load saga data because the Sagas feature is disabled in the endpoint.");
            }
            return(SagaPersister.GetByWhereClause <TSagaData>(whereClause, session, writableContextBag, appendParameters, sqlSession.InfoCache));
        }
 public Task <SagaWithoutCorrelationPropertyData> FindBy(SagaWithoutCorrelationPropertyStartingMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
Example #18
0
                public async Task <TestSaga08.SagaData08> FindBy(SomeOtherMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
                {
                    Context.FinderUsed = true;
                    var sagaInstance = new TestSaga08.SagaData08
                    {
                        Property = "jfbsjdfbsdjh"
                    };
                    //Make sure saga exists in the store. Persisters expect it there when they save saga instance after processing a message.
                    await SagaPersister.Save(sagaInstance, SagaCorrelationProperty.None, storageSession, new ContextBag()).ConfigureAwait(false);

                    return(sagaInstance);
                }
Example #19
0
        public async Task <MySagaData> FindBy(MyMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
        {
            // SynchronizedStorageSession will have a persistence specific extension method
            // For example purposes GetDbSession is a stub extension method
            var dbSession = storageSession.GetDbSession();

            return(await dbSession.GetSagaFromDB(message.SomeId, message.SomeData));

            // If a saga can't be found Task.FromResult(null) should be returned
        }
Example #20
0
 public Task <TestSaga.SagaData> FindBy(StartSagaMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
 {
     return(null);
 }
Example #21
0
    public Task <OrderSagaData> FindBy(PaymentTransactionCompleted message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
    {
        var session = storageSession.RavenSession();

        return(session.LoadByUniqueConstraintAsync <OrderSagaData>(d => d.PaymentTransactionId, message.PaymentTransactionId));
    }
Example #22
0
            public Task <MySagaData> FindBy(MyMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
            {
                // the custom finding logic here, e.g.
                IAsyncDocumentSession ravenSession = storageSession.RavenSession();
                MySagaData            sagaData     = ravenSession
                                                     .Query <MySagaData>()
                                                     .SingleOrDefault(x =>
                                                                      x.SomeID == message.SomeID &&
                                                                      x.SomeData == message.SomeData);

                return(Task.FromResult(sagaData));
            }
 public Task <SagaWithNoCorrelation.SagaData> FindBy(AMessage message, SynchronizedStorageSession session, ReadOnlyContextBag context)
 {
     return(null);
 }
Example #24
0
    public Task <OrderSagaData> FindBy(PaymentTransactionCompleted message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
    {
        var session       = storageSession.Session();
        var orderSagaData = session.QueryOver <OrderSagaData>()
                            .Where(d => d.PaymentTransactionId == message.PaymentTransactionId)
                            .SingleOrDefault();

        return(Task.FromResult(orderSagaData));
    }
                public async Task <TestSaga08.SagaData08> FindBy(SomeOtherMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
                {
                    Context.FinderUsed = true;
                    var sagaData = await SagaPersister.Get <TestSaga08.SagaData08>(message.SagaId, storageSession, (ContextBag)context).ConfigureAwait(false);

                    return(sagaData);
                }
 public Task <OrderSagaData> FindBy(CompletePaymentTransaction message, SynchronizedStorageSession session, ReadOnlyContextBag context)
 {
     return(session.GetSagaData <OrderSagaData>(
                context: context,
                whereClause: "JSON_VALUE(Data,'$.PaymentTransactionId') = @propertyValue",
                appendParameters: (builder, append) =>
     {
         var parameter = builder();
         parameter.ParameterName = "propertyValue";
         parameter.Value = message.PaymentTransactionId;
         append(parameter);
     }));
 }
 public Task <TestSaga06.SagaData06> FindBy(StartSagaMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
 {
     Context.FinderUsed = true;
     return(Task.FromResult(default(TestSaga06.SagaData06)));
 }
Example #28
0
                public Task <SagaFinderSagaData> FindBy(StartSagaMessage message, SynchronizedStorageSession session, ReadOnlyContextBag options, CancellationToken cancellationToken = default)
                {
                    if (Context.SagaId == Guid.Empty)
                    {
                        return(Task.FromResult(default(SagaFinderSagaData)));
                    }

                    return(session.RavenSession().LoadAsync <SagaFinderSagaData>(Context.SagaId.ToString(), cancellationToken));
                }
Example #29
0
 public Task <SagaData> FindBy(OtherMessage message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
 {
     return(Task.FromResult(default(SagaData)));
 }
Example #30
0
    public Task <OrderSagaData> FindBy(StartOrder message, SynchronizedStorageSession storageSession, ReadOnlyContextBag context)
    {
        var session = storageSession.Session();
        // if the instance is null a new saga will be automatically created if
        // the Saga handles the message as IAmStartedByMessages<StartOrder>; otherwise an exception is raised.
        var orderSagaData = session.QueryOver <OrderSagaData>()
                            .Where(d => d.OrderId == message.OrderId)
                            .SingleOrDefault();

        return(Task.FromResult(orderSagaData));
    }