public async Task SagaStore_FindAsyncWhenSagaHasPendingCommandPutThemToBus() { var options = PopulateContext(); using (var context = new InfrastructureContext(options)) { var mockBus = new Mock <ICommandBus>(); var stubSagaSerializer = new Mock <ISagaSerializer>(); stubSagaSerializer.Setup(s => s.Deserialize <FakeSaga>(It.IsAny <byte[]>())) .Returns <byte[]>((v) => { var payload = Encoding.UTF8.GetString(v); return(JsonConvert.DeserializeObject <FakeSaga>( payload, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All })); }); var sut = new SagaStore(mockBus.Object, stubSagaSerializer.Object, context); await sut.FindAsync <FakeSaga>(ToGuid(2)); mockBus.Verify(s => s.SendCommandAsync <Command>(It.IsAny <FakeCommand>())); } }
public void CorrelationIdIsSagaId() { var sagaId = GuidStrategy.NewGuid(); var saga = SagaStore.CreateSaga(typeof(FakeSaga), sagaId); Assert.Equal(sagaId, saga.CorrelationId); }
public async Task SagaStore_SaveAsyncWhenPendingCommandsPutThemToBusIfExceptionThrownSagaPersisted() { var options = PopulateContext(); using (var context = new InfrastructureContext(options)) { var mockBus = new Mock <ICommandBus>(); mockBus.SetupSequence(s => s.SendCommandAsync <Command>(It.IsAny <FakeCommand>())) .Returns(Task.CompletedTask) .Throws(new DbUpdateException("Cannot save entity in db. Connection closed", new Exception())); var saga = new FakeSaga { Id = Guid.Empty, PendingCommands = { new FakeCommand(), new FakeCommand() } }; var sut = new SagaStore(mockBus.Object, Mock.Of <ISagaSerializer>(), context); await Assert.ThrowsAsync <DbUpdateException>(async() => await sut.SaveAsync(saga)); Assert.Equal(1, saga.PendingCommands.Count); } using (var context = new InfrastructureContext(options)) { var sagaEntity = context.Sagas.FindAsync(Guid.Empty, typeof(SagaStore).FullName); Assert.NotNull(sagaEntity); } }
public async Task SagaStore_FindAsyncWhenSagaIsCompletedReturnsNull() { var options = PopulateContext(); using (var context = new InfrastructureContext(options)) { var stubSagaSerializer = new Mock <ISagaSerializer>(); stubSagaSerializer.Setup(s => s.Deserialize <FakeSaga>(It.IsAny <byte[]>())) .Returns <byte[]>((v) => { var payload = Encoding.UTF8.GetString(v); return(JsonConvert.DeserializeObject <FakeSaga>( payload, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All })); }); var sut = new SagaStore(Mock.Of <ICommandBus>(), stubSagaSerializer.Object, context); var saga = await sut.FindAsync <FakeSaga>(ToGuid(3)); Assert.Null(saga); } }
public async Task Remove(Guid id) { await weakInMemorySagaPersistance.Remove(id); using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions)) await sagaStore.Remove(id); }
public async Task SagaStore_SaveAsyncInvokesSerializeOnISagaSerializer() { var options = PopulateContext(); using (var context = new InfrastructureContext(options)) { var stubSagaSerializer = new Mock <ISagaSerializer>(); stubSagaSerializer.Setup(s => s.Serialize(It.IsAny <FakeSaga>())) .Returns <FakeSaga>((s) => { var payload = JsonConvert.SerializeObject( s, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); return(Encoding.UTF8.GetBytes(payload)); }); var saga = new FakeSaga { Id = Guid.Empty }; var sut = new SagaStore(Mock.Of <ICommandBus>(), stubSagaSerializer.Object, context); await sut.SaveAsync(saga); stubSagaSerializer.Verify(v => v.Serialize(saga)); } }
public async Task Set(ISaga saga) { await weakInMemorySagaPersistance.Set(saga); using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions)) await sagaStore.Store(saga); }
public void PublishCommandsOnSuccessfulSave() { SagaStore.Setup(mock => mock.CreateSaga(typeof(FakeSaga), SagaId)).Returns(new FakeSaga()); SagaEventHandler.Handle(EventContext); CommandPublisher.Verify(mock => mock.Publish(HeaderCollection.Empty, It.IsAny <CommandEnvelope>()), Times.Once()); }
public void TimeoutUpperBoundIsExclusive() { var timeout = DateTime.Now.AddMinutes(20); var saga = new FakeSaga { Version = 0, Timeout = timeout }; SagaStore.Save(saga, SagaContext); Assert.Equal(0, SagaStore.GetScheduledTimeouts(timeout).Count); }
public void CommandsNotPublishedOnFailedSave() { var saga = new FakeSaga(); SagaStore.Setup(mock => mock.CreateSaga(typeof(FakeSaga), SagaId)).Returns(saga); SagaStore.Setup(mock => mock.Save(saga, It.IsAny <SagaContext>())).Throws(new Exception()); Assert.Throws <Exception>(() => SagaEventHandler.Handle(EventContext)); CommandPublisher.Verify(mock => mock.Publish(HeaderCollection.Empty, It.IsAny <CommandEnvelope>()), Times.Never()); }
public void DoNotInsertNewSagaIfCompleted() { var saga = new FakeSaga { Version = 0, Completed = true }; var result = default(Saga); SagaStore.Save(saga, SagaContext); Assert.False(SagaStore.TryGetSaga(typeof(FakeSaga), saga.CorrelationId, out result)); }
public void SagaStore_IsAssignableFromISagaStore() { var options = SetupContext(); using (var context = new InfrastructureContext(options)) { var sut = new SagaStore(Mock.Of <ICommandBus>(), Mock.Of <ISagaSerializer>(), context); Assert.IsAssignableFrom <ISagaStore>(sut); } }
public async Task <ISaga> Get(Guid id) { ISaga saga = await weakInMemorySagaPersistance.Get(id); if (saga != null) { return(saga); } using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions)) return(await sagaStore.Get(id)); }
public async Task Set(ISaga saga) { await weakInMemorySagaPersistance.Set(saga); using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions)) { await messageBus. Publish(new SagaBeforeStoredMessage(saga)); await sagaStore.Store(saga); } }
public void IncrementVersionIfSaveSuccessful() { var saga = new FakeSaga { CorrelationId = SagaId, Version = 0 }; var savedSaga = default(Saga); SagaStore.Save(saga, SagaContext); Assert.True(SagaStore.TryGetSaga(typeof(FakeSaga), SagaId, out savedSaga)); Assert.Equal(1, saga.Version); }
public void ThrowConcurrencyExceptionIfSagaVersionOutOfSync() { var saga1 = new FakeSaga { CorrelationId = SagaId, Version = 0 }; var saga2 = new FakeSaga { CorrelationId = SagaId, Version = 2 }; SagaStore.Save(saga1, SagaContext); Assert.Throws <ConcurrencyException>(() => SagaStore.Save(saga2, SagaContext)); }
public void RemoveSagaIfCompleted() { var saga = new FakeSaga { CorrelationId = SagaId, Version = 0 }; var savedSaga = default(Saga); SagaStore.Save(saga, SagaContext); saga.Completed = true; SagaStore.Save(saga, SagaContext); Assert.False(SagaStore.TryGetSaga(typeof(FakeSaga), SagaId, out savedSaga)); }
public void ClearTimeoutIfTimeoutScheduledAndMatchesExpectedTimeout() { var timeout = SystemTime.Now; var saga = ConfigureSagaTimeout(timeout); using (var eventContext = CreateEventContext(saga, timeout)) { SagaEventHandler.Handle(eventContext); SagaStore.Verify(mock => mock.Save(saga, It.Is((SagaContext context) => context.TimeoutChanged)), Times.Once); } Assert.Null(saga.Timeout); Assert.True(Handled); }
public void TimeoutContainsAllNonStateData() { var timeout = DateTime.Now.AddMinutes(20); var saga = new FakeSaga { CorrelationId = GuidStrategy.NewGuid(), Version = 0, Timeout = timeout }; SagaStore.Save(saga, SagaContext); var sagaTimeout = SagaStore.GetScheduledTimeouts(timeout.AddMinutes(1)).Single(); Assert.Equal(saga.CorrelationId, sagaTimeout.SagaId); Assert.Equal(saga.GetType(), sagaTimeout.SagaType); Assert.Equal(saga.Timeout, sagaTimeout.Timeout); }
public void IgnoreTimeoutIfNoTimeoutScheduled() { var timeout = SystemTime.Now; var saga = ConfigureSagaTimeout(default(DateTime?)); using (var eventContext = CreateEventContext(saga, timeout)) { SagaEventHandler.Handle(eventContext); SagaStore.Verify(mock => mock.Save(saga, It.Is((SagaContext context) => !context.TimeoutChanged)), Times.Once); } Assert.Null(saga.Timeout); Assert.False(Handled); }
public void IgnoreTimeoutIfTimeoutDoesNotMatchScheduled() { var timeout = SystemTime.Now.Subtract(TimeSpan.FromSeconds(1)); var saga = ConfigureSagaTimeout(timeout); using (var eventContext = CreateEventContext(saga, SystemTime.Now)) { SagaEventHandler.Handle(eventContext); SagaStore.Verify(mock => mock.Save(saga, It.Is((SagaContext context) => !context.TimeoutChanged)), Times.Once); } Assert.Equal(timeout, saga.Timeout); Assert.False(Handled); }
public async Task <ISaga> Get(Guid id) { /*ISaga saga = await weakInMemorySagaPersistance.Get(id); * if (saga != null) * return saga;*/ using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions)) { var saga = await sagaStore.Get(id); await messageBus. Publish(new SagaAfterRetrivedMessage(saga)); return(saga); } }
public async Task SagaStore_SaveAsyncWhenPendingCommandsPutThemToBus() { var options = PopulateContext(); using (var context = new InfrastructureContext(options)) { var mockBus = new Mock <ICommandBus>(); var saga = new FakeSaga { Id = Guid.Empty, PendingCommands = { new FakeCommand() } }; var sut = new SagaStore(mockBus.Object, Mock.Of <ISagaSerializer>(), context); await sut.SaveAsync(saga); mockBus.Verify(s => s.SendCommandAsync <Command>(It.IsAny <FakeCommand>())); } }
public void ThrowKeyNotFoundIfSagaTypeUnknown() { var timeout = DateTime.Now.AddMinutes(20); var saga = new FakeSaga { CorrelationId = GuidStrategy.NewGuid(), Version = 0, Timeout = timeout }; var state = Serializer.Serialize(saga); using (var command = Dialect.CreateCommand(Dialect.InsertSaga)) { command.Parameters.Add(Dialect.CreateTypeIdParameter(Guid.NewGuid())); command.Parameters.Add(Dialect.CreateIdParameter(saga.CorrelationId)); command.Parameters.Add(Dialect.CreateTimeoutParameter(timeout)); command.Parameters.Add(Dialect.CreateStateParameter(state)); Dialect.ExecuteNonQuery(command); } Assert.Throws <KeyNotFoundException>(() => SagaStore.GetScheduledTimeouts(timeout.AddMinutes(1))); }
public async Task SagaStore_SaveAsyncPersistChangesInContext() { var options = PopulateContext(); using (var context = new InfrastructureContext(options)) { var saga = new FakeSaga { Id = Guid.Empty }; var sut = new SagaStore(Mock.Of <ICommandBus>(), Mock.Of <ISagaSerializer>(), context); await sut.SaveAsync(saga); } using (var context = new InfrastructureContext(options)) { var sagaEntity = context.Sagas.FindAsync(Guid.Empty, typeof(FakeSaga).FullName); Assert.NotNull(sagaEntity); } }
protected override void Establish_context() { base.Establish_context(); using (var session = SagaStore.OpenSession()) { var saga = new FakeSaga() { CorrelationId = Guid.NewGuid(), Property = FilteredPropertyValue }; session.Store(saga); saga = new FakeSaga() { CorrelationId = Guid.NewGuid(), Property = FilteredPropertyValue }; session.Store(saga); saga = new FakeSaga() { CorrelationId = Guid.NewGuid(), Property = "filtered" }; session.Store(saga); session.SaveChanges(); } }
public Task <IList <Guid> > GetUnfinished() { using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions)) return(sagaStore.GetUnfinished()); }
public void SagaIdExtractedFromEventConfiguration() { SagaEventHandler.Handle(EventContext); SagaStore.Verify(mock => mock.CreateSaga(typeof(FakeSaga), SagaId), Times.Once()); }
public SimpleSagaWorker(SagaStore sagaStore, ILogger <SimpleSagaWorker> logger) { this.sagaStore = sagaStore; this._logger = logger; this._workerId = Guid.NewGuid().ToString(); }
public void VersionAssignedZeroValue() { var saga = SagaStore.CreateSaga(typeof(FakeSaga), GuidStrategy.NewGuid()); Assert.Equal(0, saga.Version); }