public async Task The_saga_data_should_be_removed()
        {
            var saga = new SagaData
            {
                Id       = Guid.NewGuid(),
                SomeId   = "test-id",
                SomeName = "Test Name"
            };

            IDocumentSession session;
            var context = this.CreateContextWithSessionPresent(out session);

            var sagaPersister = new SagaPersister();
            var synchronizedStorageSession = new MartenSynchronizedStorageSession(session, true);

            await sagaPersister.Save(saga, new SagaCorrelationProperty("SomeId", saga.SomeId), synchronizedStorageSession, context);

            await session.SaveChangesAsync().ConfigureAwait(false);

            await sagaPersister.Complete(saga, synchronizedStorageSession, context);

            await session.SaveChangesAsync().ConfigureAwait(false);

            var savedSaga = await sagaPersister.Get <SagaData>(saga.Id, synchronizedStorageSession, context);

            savedSaga.Should().BeNull();
        }
    public void It_should_persist_successfully()
    {
        using (var store = DocumentStoreBuilder.Build())
        {
            var factory = new RavenSessionFactory(store);
            factory.ReleaseSession();
            var persister    = new SagaPersister(factory);
            var uniqueString = Guid.NewGuid().ToString();
            var saga1        = new SagaData
            {
                Id           = Guid.NewGuid(),
                UniqueString = uniqueString
            };
            persister.Save(saga1);
            factory.SaveChanges();
            factory.ReleaseSession();

            var saga = persister.Get <SagaData>(saga1.Id);
            persister.Complete(saga);
            factory.SaveChanges();
            factory.ReleaseSession();

            var saga2 = new SagaData
            {
                Id           = Guid.NewGuid(),
                UniqueString = uniqueString
            };

            persister.Save(saga2);
            factory.SaveChanges();
        }
    }
        public async Task TestMarkingAsComplete(ConventionType seedType)
        {
            using (var db = new ReusableDB())
            {
                List <TestSagaData> sagas;

                using (var store = db.NewStore())
                {
                    ApplyPrefillConventions(store, seedType);
                    store.Initialize();

                    sagas = await Prefill(store, seedType);
                }

                using (var store = db.NewStore())
                {
                    Console.WriteLine($"Testing saga lookups with DocumentStore initially configured for {seedType} conventions.");
                    ApplyTestConventions(store, seedType);
                    store.Initialize();

                    // Update each saga, once by id and once by correlation property
                    foreach (var saga in sagas)
                    {
                        var persister = new SagaPersister();
                        using (var session = store.OpenAsyncSession())
                        {
                            Console.WriteLine($"Retrieving SagaId {saga.Id} by Correlation Property OrderId={saga.OrderId} and completing.");
                            var ravenDBSynchronizedStorageSession = new RavenDBSynchronizedStorageSession(session, false);
                            var contextBag = new ContextBag();
                            var byOrderId  = await persister.Get <TestSagaData>("OrderId", saga.OrderId, ravenDBSynchronizedStorageSession, contextBag);

                            Assert.IsNotNull(byOrderId);

                            await persister.Complete(byOrderId, ravenDBSynchronizedStorageSession, contextBag);

                            await session.SaveChangesAsync();
                        }
                    }

                    db.WaitForIndexing(store);

                    // Ensure terms are still the saga type and unique identity type
                    var terms = store.DatabaseCommands.GetTerms("Raven/DocumentsByEntityName", "Tag", null, 1024).ToList();
                    Assert.AreEqual(2, terms.Count);

                    foreach (var term in terms)
                    {
                        var query = new IndexQuery
                        {
                            Query    = "Tag:" + term,
                            PageSize = 0
                        };

                        // Ensure there are none left
                        var queryResult = store.DatabaseCommands.Query("Raven/DocumentsByEntityName", query);
                        Assert.AreEqual(0, queryResult.TotalResults);
                    }
                }
            }
        }
    public async Task Should_delete_the_unique_doc_properly()
    {
        var sagaId = Guid.NewGuid();

        IAsyncDocumentSession session;
        var options   = this.CreateContextWithAsyncSessionPresent(out session);
        var persister = new SagaPersister();

        var sagaEntity = new SagaData
        {
            Id     = sagaId,
            SomeId = Guid.NewGuid()
        };
        var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

        await persister.Save(sagaEntity, this.CreateMetadata <SomeSaga>(sagaEntity), synchronizedSession, options);

        //session.Advanced.GetMetadataFor(sagaEntity).Remove("NServiceBus-UniqueDocId");
        await session.SaveChangesAsync().ConfigureAwait(false);

        var saga = await persister.Get <SagaData>(sagaId, synchronizedSession, options);

        await persister.Complete(saga, synchronizedSession, options);

        await session.SaveChangesAsync().ConfigureAwait(false);

        Assert.Null(await session.Query <SagaUniqueIdentity>().Customize(c => c.WaitForNonStaleResults()).SingleOrDefaultAsync(u => u.SagaId == sagaId));
    }
Example #5
0
    private async Task RunTestUsing(GetSagaDelegate getSaga)
    {
        var sagaId = StoreSagaDocuments();

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency())
        {
            var persister = new SagaPersister();
            var context   = new ContextBag();
            context.Set(session);
            var synchronizedSession = new RavenDBSynchronizedStorageSession(session);
            var sagaData            = await getSaga(persister, sagaId, synchronizedSession, context);

            Assert.IsNotNull(sagaData);
            Assert.AreEqual(42, sagaData.Counter);
            Assert.AreEqual("Alpha", sagaData.Name);

            await persister.Complete(sagaData, synchronizedSession, context);

            await session.SaveChangesAsync();
        }

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency())
        {
            var dataDocs = await session.Advanced.LoadStartingWithAsync <SagaDataContainer>("CountingSagaDatas/");

            var uniqueDocs = await session.Advanced.LoadStartingWithAsync <SagaUniqueIdentity>("Raven3Sagas-");

            Assert.IsEmpty(dataDocs);
            Assert.IsEmpty(uniqueDocs);
        }
    }
Example #6
0
    public async Task Should_delete_the_saga_and_the_unique_doc()
    {
        var sagaId = Guid.NewGuid();

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency().InContext(out var options))
        {
            var persister = new SagaPersister();
            var entity    = new SagaData
            {
                Id = sagaId
            };
            var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

            await persister.Save(entity, this.CreateMetadata <SomeSaga>(entity), synchronizedSession, options);

            await session.SaveChangesAsync().ConfigureAwait(false);

            var saga = await persister.Get <SagaData>(sagaId, synchronizedSession, options);

            await persister.Complete(saga, synchronizedSession, options);

            await session.SaveChangesAsync().ConfigureAwait(false);

            Assert.Null(await persister.Get <SagaData>(sagaId, synchronizedSession, options));
            Assert.Null(await session.Query <SagaUniqueIdentity>().Customize(c => c.WaitForNonStaleResults()).SingleOrDefaultAsync(u => u.SagaId == sagaId).ConfigureAwait(false));
        }
    }
    public void It_should_persist_successfully()
    {
        var factory = new RavenSessionFactory(store);
        factory.ReleaseSession();
        var persister = new SagaPersister(factory);
        var uniqueString = Guid.NewGuid().ToString();
        var saga1 = new SagaData
            {
                Id = Guid.NewGuid(),
                UniqueString = uniqueString
            };
        persister.Save(saga1);
        factory.SaveChanges();
        factory.ReleaseSession();

        var saga = persister.Get<SagaData>(saga1.Id);
        persister.Complete(saga);
        factory.SaveChanges();
        factory.ReleaseSession();

        var saga2 = new SagaData
            {
                Id = Guid.NewGuid(),
                UniqueString = uniqueString
            };

        persister.Save(saga2);
        factory.SaveChanges();
    }
        public void Complete_NullSaga_Throws()
        {
            // arrange
            // act
            Action action = () => _persister.Complete(null);

            // assert
            action.ShouldThrow <ArgumentNullException>()
            .WithMessage("*saga*");
        }
        public void Complete_ExistingSaga_DeletesSaga()
        {
            // arrange
            TestSagaDataWithRowVersion sagaData = AddSagaWithRowVersion();
            var persisterRetrievedSagaData      = _persister.Get <TestSagaDataWithRowVersion>(sagaData.Id);

            using (var dbc = new TestDbContext())
            {
                dbc.TestSagasWithRowVersion.Find(sagaData.Id).Should().NotBeNull();
            }

            // act
            _persister.Complete(persisterRetrievedSagaData);

            // assert
            using (var dbContext = new TestDbContext())
            {
                dbContext.TestSagasWithRowVersion.Find(sagaData.Id).Should().BeNull();
            }
        }
Example #10
0
    public async Task It_should_persist_successfully()
    {
        var saga1Id      = Guid.NewGuid();
        var uniqueString = Guid.NewGuid().ToString();

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency().InContext(out var options))
        {
            var persister = new SagaPersister();
            var saga1     = new SagaData
            {
                Id           = saga1Id,
                UniqueString = uniqueString
            };

            var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

            await persister.Save(saga1, this.CreateMetadata <SomeSaga>(saga1), synchronizedSession, options);

            await session.SaveChangesAsync().ConfigureAwait(false);
        }

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency().InContext(out var options))
        {
            var persister           = new SagaPersister();
            var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

            var saga = await persister.Get <SagaData>(saga1Id, synchronizedSession, options);

            await persister.Complete(saga, synchronizedSession, options);

            await session.SaveChangesAsync().ConfigureAwait(false);
        }

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency().InContext(out var options))
        {
            var persister           = new SagaPersister();
            var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

            var saga2 = new SagaData
            {
                Id           = Guid.NewGuid(),
                UniqueString = uniqueString
            };

            await persister.Save(saga2, this.CreateMetadata <SomeSaga>(saga2), synchronizedSession, options);

            await session.SaveChangesAsync().ConfigureAwait(false);
        }
    }
Example #11
0
        public void both_the_saga_and_the_unique_property_entity_should_be_deleted()
        {
            var sagaId = Saga1.Id;

            SagaPersister.Complete(Saga1);
            SagaPersister.DocumentSessionFactory.Current.SaveChanges();

            var deletedSaga = SagaPersister.Get <SagaEntityWithUniqueProperty>(sagaId);

            var persistedUniqueProperty = SagaPersister.DocumentSessionFactory.Current
                                          .Query <NServiceBus.SagaPersisters.RavenDB.UniqueProperty>()
                                          .Customize(x => x.WaitForNonStaleResults())
                                          .Where(p => p.SagaId == sagaId).SingleOrDefault();

            Assert.That(deletedSaga, Is.Null);
            Assert.That(persistedUniqueProperty, Is.Null);
        }
    public async Task It_should_persist_successfully()
    {
        IAsyncDocumentSession session;
        var options      = this.CreateContextWithAsyncSessionPresent(out session);
        var persister    = new SagaPersister();
        var uniqueString = Guid.NewGuid().ToString();
        var saga1        = new SagaData
        {
            Id           = Guid.NewGuid(),
            UniqueString = uniqueString
        };

        var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

        await persister.Save(saga1, this.CreateMetadata <SomeSaga>(saga1), synchronizedSession, options);

        await session.SaveChangesAsync().ConfigureAwait(false);

        session.Dispose();

        options             = this.CreateContextWithAsyncSessionPresent(out session);
        synchronizedSession = new RavenDBSynchronizedStorageSession(session);

        var saga = await persister.Get <SagaData>(saga1.Id, synchronizedSession, options);

        await persister.Complete(saga, synchronizedSession, options);

        await session.SaveChangesAsync().ConfigureAwait(false);

        session.Dispose();

        options             = this.CreateContextWithAsyncSessionPresent(out session);
        synchronizedSession = new RavenDBSynchronizedStorageSession(session);

        var saga2 = new SagaData
        {
            Id           = Guid.NewGuid(),
            UniqueString = uniqueString
        };

        await persister.Save(saga2, this.CreateMetadata <SomeSaga>(saga2), synchronizedSession, options);

        await session.SaveChangesAsync().ConfigureAwait(false);
    }
    public void Should_delete_the_saga()
    {
        var sagaId = Guid.NewGuid();

        var factory = new RavenSessionFactory(store);
        factory.ReleaseSession();
        var persister = new SagaPersister(factory);
        persister.Save(new SagaData
            {
                Id = sagaId
            });
        factory.SaveChanges();

        var saga = persister.Get<SagaData>(sagaId);
        persister.Complete(saga);
        factory.SaveChanges();

        Assert.Null(persister.Get<SagaData>(sagaId));
    }
    public async Task It_should_load_successfully()
    {
        var unique = Guid.NewGuid().ToString();

        CreateLegacySagaDocuments(store, unique);

        IAsyncDocumentSession session;
        var options = this.CreateContextWithAsyncSessionPresent(out session);
        var persister = new SagaPersister();

        var synchronizedSession = new RavenDBSynchronizedStorageSession(session, true);

        var saga = await persister.Get<SagaWithUniqueProperty>("UniqueString", unique, synchronizedSession, options);

        Assert.IsNotNull(saga, "Saga is null");

        await persister.Complete(saga, synchronizedSession, options);
        await session.SaveChangesAsync().ConfigureAwait(false);

        Assert.IsNull(await persister.Get<SagaWithUniqueProperty>("UniqueString", unique, synchronizedSession, options), "Saga was not completed");
    }
    public async Task It_should_load_successfully()
    {
        var unique = Guid.NewGuid().ToString();

        CreateLegacySagaDocuments(store, unique);

        IAsyncDocumentSession session;
        var options   = this.CreateContextWithAsyncSessionPresent(out session);
        var persister = new SagaPersister();

        var synchronizedSession = new RavenDBSynchronizedStorageSession(session, true);

        var saga = await persister.Get <SagaWithUniqueProperty>("UniqueString", unique, synchronizedSession, options);

        Assert.IsNotNull(saga, "Saga is null");

        await persister.Complete(saga, synchronizedSession, options);

        await session.SaveChangesAsync().ConfigureAwait(false);

        Assert.IsNull(await persister.Get <SagaWithUniqueProperty>("UniqueString", unique, synchronizedSession, options), "Saga was not completed");
    }
    public void Should_delete_the_saga()
    {
        using (var store = DocumentStoreBuilder.Build())
        {
            var sagaId = Guid.NewGuid();

            var factory = new RavenSessionFactory(store);
            factory.ReleaseSession();
            var persister = new SagaPersister(factory);
            persister.Save(new SagaData
            {
                Id = sagaId
            });
            factory.SaveChanges();

            var saga = persister.Get <SagaData>(sagaId);
            persister.Complete(saga);
            factory.SaveChanges();

            Assert.Null(persister.Get <SagaData>(sagaId));
        }
    }
    public async Task It_should_load_successfully()
    {
        var unique = Guid.NewGuid().ToString();

        CreateLegacySagaDocuments(store, unique);

        using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency().InContext(out var options))
        {
            var persister = new SagaPersister();

            var synchronizedSession = new RavenDBSynchronizedStorageSession(session);

            var saga = await persister.Get <SagaWithUniqueProperty>("UniqueString", unique, synchronizedSession, options);

            Assert.IsNotNull(saga, "Saga is null");

            await persister.Complete(saga, synchronizedSession, options);

            await session.SaveChangesAsync().ConfigureAwait(false);

            Assert.IsNull(await persister.Get <SagaWithUniqueProperty>("UniqueString", unique, synchronizedSession, options), "Saga was not completed");
        }
    }
        public void Invoke(BehaviorContext context, Action next)
        {
            currentContext = context;

            activeSagaInstances = DetectSagas(context).ToList();

            foreach (var sagaInstanceState in activeSagaInstances)
            {
                var saga = sagaInstanceState.Instance;

                var loadedEntity = TryLoadSagaEntity(saga, sagaInstanceState.MessageToProcess);


                if (loadedEntity == null)
                {
                    //if this message are not allowed to start the saga
                    if (!Features.Sagas.ShouldMessageStartSaga(sagaInstanceState.SagaType,
                                                               sagaInstanceState.MessageToProcess.MessageType))
                    {
                        sagaInstanceState.MarkAsNotFound();

                        InvokeSagaNotFoundHandlers(sagaInstanceState);
                        continue;
                    }

                    sagaInstanceState.AttachNewEntity(CreateNewSagaEntity(sagaInstanceState.SagaType));
                }
                else
                {
                    sagaInstanceState.AttachExistingEntity(loadedEntity);
                }

                if (IsTimeoutMessage(sagaInstanceState.MessageToProcess))
                {
                    sagaInstanceState.Handler.Invocation = HandlerInvocationCache.InvokeTimeout;
                }
            }

            //so that other behaviors can access the sagas
            context.Set(new ActiveSagaInstances(activeSagaInstances));

            next();

            foreach (var sagaInstanceState in activeSagaInstances)
            {
                if (sagaInstanceState.NotFound)
                {
                    continue;
                }

                var saga = sagaInstanceState.Instance;

                if (saga.Completed)
                {
                    if (!sagaInstanceState.IsNew)
                    {
                        SagaPersister.Complete(saga.Entity);
                    }

                    if (saga.Entity.Id != Guid.Empty)
                    {
                        NotifyTimeoutManagerThatSagaHasCompleted(saga);
                    }

                    logger.Debug(string.Format("{0} {1} has completed.", saga.GetType().FullName, saga.Entity.Id));
                }
                else
                {
                    if (sagaInstanceState.IsNew)
                    {
                        SagaPersister.Save(saga.Entity);
                    }
                    else
                    {
                        SagaPersister.Update(saga.Entity);
                    }
                }
            }
        }
        public async Task TestMarkingAsComplete(ConventionType seedType)
        {
            using (var db = new ReusableDB())
            {
                List<TestSagaData> sagas;

                using (var store = db.NewStore())
                {
                    ApplyPrefillConventions(store, seedType);
                    store.Initialize();

                    sagas = await Prefill(store, seedType);
                }

                using (var store = db.NewStore())
                {
                    Console.WriteLine($"Testing saga lookups with DocumentStore initially configured for {seedType} conventions.");
                    ApplyTestConventions(store, seedType);
                    store.Initialize();

                    // Update each saga, once by id and once by correlation property
                    foreach (var saga in sagas)
                    {
                        var persister = new SagaPersister();
                        using (var session = store.OpenAsyncSession())
                        {
                            Console.WriteLine($"Retrieving SagaId {saga.Id} by Correlation Property OrderId={saga.OrderId} and completing.");
                            var ravenDBSynchronizedStorageSession = new RavenDBSynchronizedStorageSession(session, false);
                            var contextBag = new ContextBag();
                            var byOrderId = await persister.Get<TestSagaData>("OrderId", saga.OrderId, ravenDBSynchronizedStorageSession, contextBag);
                            Assert.IsNotNull(byOrderId);

                            await persister.Complete(byOrderId, ravenDBSynchronizedStorageSession, contextBag);
                            await session.SaveChangesAsync();
                        }
                    }

                    db.WaitForIndexing(store);

                    // Ensure terms are still the saga type and unique identity type
                    var terms = store.DatabaseCommands.GetTerms("Raven/DocumentsByEntityName", "Tag", null, 1024).ToList();
                    Assert.AreEqual(2, terms.Count);

                    foreach (var term in terms)
                    {
                        var query = new IndexQuery
                        {
                            Query = "Tag:" + term,
                            PageSize = 0
                        };

                        // Ensure there are none left
                        var queryResult = store.DatabaseCommands.Query("Raven/DocumentsByEntityName", query);
                        Assert.AreEqual(0, queryResult.TotalResults);
                    }
                }
            }
        }
Example #20
0
        public void Invoke(HandlerInvocationContext context, Action next)
        {
            var saga = context.MessageHandler.Instance as ISaga;

            if (saga == null)
            {
                next();
                return;
            }

            currentContext = context;

            var sagaInstanceState = new ActiveSagaInstance(saga);

            //so that other behaviors can access the saga
            context.Set(sagaInstanceState);

            var loadedEntity = TryLoadSagaEntity(saga, context.LogicalMessage);

            if (loadedEntity == null)
            {
                //if this message are not allowed to start the saga
                if (!Features.Sagas.ShouldMessageStartSaga(sagaInstanceState.SagaType, context.LogicalMessage.MessageType))
                {
                    sagaInstanceState.MarkAsNotFound();

                    InvokeSagaNotFoundHandlers();
                    return;
                }

                sagaInstanceState.AttachNewEntity(CreateNewSagaEntity(sagaInstanceState.SagaType));
            }
            else
            {
                sagaInstanceState.AttachExistingEntity(loadedEntity);
            }


            if (IsTimeoutMessage(context.LogicalMessage))
            {
                context.MessageHandler.Invocation = HandlerInvocationCache.InvokeTimeout;
            }


            next();

            if (sagaInstanceState.NotFound)
            {
                return;
            }

            if (saga.Completed)
            {
                if (!sagaInstanceState.IsNew)
                {
                    SagaPersister.Complete(saga.Entity);
                }

                if (saga.Entity.Id != Guid.Empty)
                {
                    NotifyTimeoutManagerThatSagaHasCompleted(saga);
                }

                logger.Debug(string.Format("Saga: '{0}' with Id: '{1}' has completed.", sagaInstanceState.SagaType.FullName, saga.Entity.Id));
            }
            else
            {
                if (sagaInstanceState.IsNew)
                {
                    SagaPersister.Save(saga.Entity);
                }
                else
                {
                    SagaPersister.Update(saga.Entity);
                }
            }
        }