public async Task When_a_duplicate_messages_starting_a_saga_arrive_sequentially_one_of_them_fails() { var context = CreateMessageContext(); var sagaData = CreateNewSagaData(); var transaction1 = await outboxPersister.BeginTransaction(context); var session1 = new OutboxEventStoreSynchronizedStorageSession(connection, (EventStoreOutboxTransaction)transaction1); await persister.Save(sagaData, new SagaCorrelationProperty(CorrelationPropName, sagaData.StringProperty), session1, context); await transaction1.Commit(); var transaction2 = await outboxPersister.BeginTransaction(context); var session2 = new OutboxEventStoreSynchronizedStorageSession(connection, (EventStoreOutboxTransaction)transaction2); var loadedData = await persister.Get <SagaData>(CorrelationPropName, sagaData.StringProperty, session2, context); await persister.Update(loadedData, session2, context); try { await transaction2.Commit(); Assert.Fail("Expected exception"); } catch (Exception ex) { StringAssert.StartsWith("Append failed due to WrongExpectedVersion.", ex.Message); } }
public void Update_DbChangedEntityWithRowVersion_ShouldSaveSaga() { // arrange TestSagaDataWithRowVersion newSagaData = AddSagaWithRowVersion(); string expectedSomeProp1 = Guid.NewGuid().ToString(); string expectedSomeProp2 = Guid.NewGuid().ToString(); var persisterRetrievedSagaData = _persister.Get <TestSagaDataWithRowVersion>(newSagaData.Id); // simulates another worker updating the saga after "this" saga retrieves it's saga using (var dbc = new TestDbContext()) { var fromDb = dbc.TestSagasWithRowVersion.Find(newSagaData.Id); fromDb.SomeProp1 = expectedSomeProp1; dbc.SaveChanges(); } // act persisterRetrievedSagaData.SomeProp2 = expectedSomeProp2; _persister.Update(persisterRetrievedSagaData); // assert using (var dbc = new TestDbContext()) { var fromDb = dbc.TestSagasWithRowVersion.Find(newSagaData.Id); fromDb.Id.Should().Be(newSagaData.Id); fromDb.OriginalMessageId.Should().Be(newSagaData.OriginalMessageId); fromDb.Originator.Should().Be(newSagaData.Originator); fromDb.SomeProp1.Should().Be(expectedSomeProp1); fromDb.SomeProp2.Should().Be(expectedSomeProp2); } }
public async Task When_a_duplicate_messages_starting_a_saga_arrive_sequentially_both_succeed() { var context = CreateMessageContext(); var sagaData = CreateNewSagaData(); var session1 = new EventStoreSynchronizedStorageSession(connection); await persister.Save(sagaData, new SagaCorrelationProperty(CorrelationPropName, sagaData.StringProperty), session1, context); var session2 = new EventStoreSynchronizedStorageSession(connection); var loadedData = await persister.Get <SagaData>(CorrelationPropName, sagaData.StringProperty, session2, context); await persister.Update(loadedData, session2, context); }
public async Task It_should_persist_successfully() { 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); var savedSaga = await sagaPersister.Get <SagaData>(saga.Id, synchronizedStorageSession, context); savedSaga.SomeName = "Another name"; await sagaPersister.Update(saga, synchronizedStorageSession, context); await session.SaveChangesAsync().ConfigureAwait(false); var updatedSaga = await sagaPersister.Get <SagaData>(saga.Id, synchronizedStorageSession, context); updatedSaga.SomeName.Should().Be("Another name"); }
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, NonUniqueString = "notUnique" }; var synchronizedSession = new RavenDBSynchronizedStorageSession(session, true); await persister.Save(saga1, this.CreateMetadata <SomeSaga>(saga1), synchronizedSession, options); await session.SaveChangesAsync().ConfigureAwait(false); var saga = await persister.Get <SagaData>(saga1.Id, synchronizedSession, options); saga.NonUniqueString = "notUnique2"; await persister.Update(saga, synchronizedSession, options); await session.SaveChangesAsync().ConfigureAwait(false); }
public async Task It_should_persist_successfully() { using (var session = store.OpenAsyncSession().UsingOptimisticConcurrency().InContext(out var options)) { var persister = new SagaPersister(); var uniqueString = Guid.NewGuid().ToString(); var anotherUniqueString = Guid.NewGuid().ToString(); var saga1 = new SagaData { Id = Guid.NewGuid(), UniqueString = uniqueString, NonUniqueString = "notUnique" }; var synchronizedSession = new RavenDBSynchronizedStorageSession(session); await persister.Save(saga1, this.CreateMetadata <SomeSaga>(saga1), synchronizedSession, options); await session.SaveChangesAsync().ConfigureAwait(false); var saga = await persister.Get <SagaData>(saga1.Id, synchronizedSession, options); saga.NonUniqueString = "notUnique2"; saga.UniqueString = anotherUniqueString; await persister.Update(saga, synchronizedSession, options); await session.SaveChangesAsync().ConfigureAwait(false); } }
public void It_should_allow_the_update() { 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); saga.UniqueString = Guid.NewGuid().ToString(); persister.Update(saga); factory.SaveChanges(); factory.ReleaseSession(); var saga2 = new SagaData { Id = Guid.NewGuid(), UniqueString = uniqueString }; //this should not blow since we changed the unique value in the previous saga persister.Save(saga2); factory.SaveChanges(); }
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 anotherUniqueString = Guid.NewGuid().ToString(); var saga1 = new SagaData { Id = Guid.NewGuid(), UniqueString = uniqueString, NonUniqueString = "notUnique" }; persister.Save(saga1); factory.SaveChanges(); var saga = persister.Get <SagaData>(saga1.Id); saga.NonUniqueString = "notUnique2"; saga.UniqueString = anotherUniqueString; persister.Update(saga); factory.SaveChanges(); } }
public void It_should_allow_the_update() { 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); saga.UniqueString = Guid.NewGuid().ToString(); persister.Update(saga); factory.SaveChanges(); factory.ReleaseSession(); var saga2 = new SagaData { Id = Guid.NewGuid(), UniqueString = uniqueString }; //this should not blow since we changed the unique value in the previous saga persister.Save(saga2); factory.SaveChanges(); } }
public void Update_NullSaga_Throws() { // arrange // act Action action = () => _persister.Update(null); // assert action.ShouldThrow <ArgumentNullException>() .WithMessage("*saga*"); }
public void an_sagaEntity() { ((SagaEntityA)_sagaEntityA).SomeIdentifier = A_NEW_VALUE; SagaPersister.Update(_sagaEntityA); SagaPersister.DocumentSessionFactory.Current.SaveChanges(); var loadedUpdatedSagaEntity = SagaPersister.Get <SagaEntityA>(_sagaEntityA.Id); Assert.That(loadedUpdatedSagaEntity.Id, Is.EqualTo(_sagaEntityA.Id)); Assert.That(loadedUpdatedSagaEntity.SomeIdentifier, Is.EqualTo(A_NEW_VALUE)); }
public void should_also_update_its_unique_property_entity() { var saga3 = SagaPersister.Get <SagaEntityWithUniqueProperty>(Saga3.Id); saga3.ThisShouldBeUnique = UNIQUE_VALUE_FOUR; SagaPersister.Update(saga3); SagaPersister.DocumentSessionFactory.Current.SaveChanges(); var persistedUniqueProperty = SagaPersister.DocumentSessionFactory.Current .Query <NServiceBus.SagaPersisters.RavenDB.UniqueProperty>() .Customize(x => x.WaitForNonStaleResults()) .Where(p => p.SagaId == Saga3.Id) .SingleOrDefault(); Assert.That(persistedUniqueProperty.Value, Is.EqualTo(UNIQUE_VALUE_FOUR)); }
public void It_should_set_the_attribute_and_allow_the_update() { using (var store = DocumentStoreBuilder.Build()) { var factory = new RavenSessionFactory(store); factory.ReleaseSession(); var persister = new SagaPersister(factory); var uniqueString = Guid.NewGuid().ToString(); var anotherUniqueString = Guid.NewGuid().ToString(); var saga1 = new SagaData { Id = Guid.NewGuid(), UniqueString = uniqueString, NonUniqueString = "notUnique" }; persister.Save(saga1); factory.SaveChanges(); factory.ReleaseSession(); using (var session = store.OpenSession()) { //fake that the attribute was just added by removing the metadata session.Advanced.GetMetadataFor(saga1).Remove(SagaPersister.UniqueValueMetadataKey); session.SaveChanges(); } var saga = persister.Get <SagaData>(saga1.Id); saga.UniqueString = anotherUniqueString; persister.Update(saga); factory.SaveChanges(); factory.ReleaseSession(); using (var session = store.OpenSession()) { var value = session.Advanced.GetMetadataFor(saga1)[SagaPersister.UniqueValueMetadataKey].ToString(); Assert.AreEqual(anotherUniqueString, value); } } }
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, NonUniqueString = "notUnique" }; persister.Save(saga1); factory.SaveChanges(); var saga = persister.Get<SagaData>(saga1.Id); saga.NonUniqueString = "notUnique2"; persister.Update(saga); factory.SaveChanges(); }
public void It_should_set_the_attribute_and_allow_the_update() { var factory = new RavenSessionFactory(store); factory.ReleaseSession(); var persister = new SagaPersister(factory); var uniqueString = Guid.NewGuid().ToString(); var anotherUniqueString = Guid.NewGuid().ToString(); var saga1 = new SagaData { Id = Guid.NewGuid(), UniqueString = uniqueString, NonUniqueString = "notUnique" }; persister.Save(saga1); factory.SaveChanges(); factory.ReleaseSession(); using (var session = store.OpenSession()) { //fake that the attribute was just added by removing the metadata session.Advanced.GetMetadataFor(saga1).Remove(SagaPersister.UniqueValueMetadataKey); session.SaveChanges(); } var saga = persister.Get<SagaData>(saga1.Id); saga.UniqueString = anotherUniqueString; persister.Update(saga); factory.SaveChanges(); factory.ReleaseSession(); using (var session = store.OpenSession()) { var value = session.Advanced.GetMetadataFor(saga1)[SagaPersister.UniqueValueMetadataKey].ToString(); Assert.AreEqual(anotherUniqueString, value); } }
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 TestStoringSagas(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 updates 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(); Console.WriteLine($"Retrieving SagaId {saga.Id} by SagaId"); using (var session = store.OpenAsyncSession()) { var ravenDBSynchronizedStorageSession = new RavenDBSynchronizedStorageSession(session, false); var byId = await persister.Get<TestSagaData>(saga.Id, ravenDBSynchronizedStorageSession, null); Assert.IsNotNull(byId); byId.Counter++; await persister.Update(byId, ravenDBSynchronizedStorageSession, null); await session.SaveChangesAsync(); Console.WriteLine($"Retrieving SagaId {saga.Id} by Correlation Property OrderId={saga.OrderId}"); var byOrderId = await persister.Get<TestSagaData>("OrderId", saga.OrderId, ravenDBSynchronizedStorageSession, new ContextBag()); Assert.IsNotNull(byOrderId); byOrderId.Counter++; await persister.Update(byOrderId, ravenDBSynchronizedStorageSession, null); await session.SaveChangesAsync(); } } Console.WriteLine("Retrieving each saga again by SagaId and making sure Counter == 3"); foreach (var saga in sagas) { var persister = new SagaPersister(); using (var session = store.OpenAsyncSession()) { Console.WriteLine($"Retrieving SagaId {saga.Id} by SagaId"); var byId = await persister.Get<TestSagaData>(saga.Id, new RavenDBSynchronizedStorageSession(session, false), null); Assert.IsNotNull(byId); Assert.AreEqual(3, byId.Counter); } } } } }
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); } } }
public async Task TestStoringSagas(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 updates 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(); Console.WriteLine($"Retrieving SagaId {saga.Id} by SagaId"); using (var session = store.OpenAsyncSession()) { var ravenDBSynchronizedStorageSession = new RavenDBSynchronizedStorageSession(session, false); var byId = await persister.Get <TestSagaData>(saga.Id, ravenDBSynchronizedStorageSession, null); Assert.IsNotNull(byId); byId.Counter++; await persister.Update(byId, ravenDBSynchronizedStorageSession, null); await session.SaveChangesAsync(); Console.WriteLine($"Retrieving SagaId {saga.Id} by Correlation Property OrderId={saga.OrderId}"); var byOrderId = await persister.Get <TestSagaData>("OrderId", saga.OrderId, ravenDBSynchronizedStorageSession, new ContextBag()); Assert.IsNotNull(byOrderId); byOrderId.Counter++; await persister.Update(byOrderId, ravenDBSynchronizedStorageSession, null); await session.SaveChangesAsync(); } } Console.WriteLine("Retrieving each saga again by SagaId and making sure Counter == 3"); foreach (var saga in sagas) { var persister = new SagaPersister(); using (var session = store.OpenAsyncSession()) { Console.WriteLine($"Retrieving SagaId {saga.Id} by SagaId"); var byId = await persister.Get <TestSagaData>(saga.Id, new RavenDBSynchronizedStorageSession(session, false), null); Assert.IsNotNull(byId); Assert.AreEqual(3, byId.Counter); } } } } }