public override void Events_that_cannot_be_deserialized_due_to_unknown_member_do_not_cause_sourcing_to_fail() { Guid orderId = Guid.NewGuid(); var goodEvent = new Order.CustomerInfoChanged { CustomerName = "Waylon Jennings", AggregateId = orderId, SequenceNumber = 1 }.ToStorableEvent(); var badEvent = new StorableEvent { StreamName = goodEvent.StreamName, Type = goodEvent.Type, AggregateId = goodEvent.AggregateId, SequenceNumber = 2, Body = new { CustomerName = "Willie Nelson", HairColor = "red" }.ToJson(), UtcTime = DateTime.UtcNow }; SaveEventsDirectly(goodEvent, badEvent); var repository = CreateRepository <Order>(); var order = repository.GetLatest(orderId); order.CustomerName.Should().Be("Willie Nelson"); }
public async Task A_DuckTypeProjector_can_access_the_metadata_of_unknown_event_types_dynamically() { StorableEvent storableEvent = null; using (var db = EventStoreDbContext()) { storableEvent = new StorableEvent { AggregateId = Guid.NewGuid(), StreamName = Any.CamelCaseName(), Type = Any.CamelCaseName(), Body = new { }.ToJson() }; db.Events.Add(storableEvent); await db.SaveChangesAsync(); } IEvent receivedEvent = null; var projector = Projector.CreateFor <dynamic>(e => receivedEvent = e); using (var catchup = CreateReadModelCatchup(projector)) { await catchup.Run(); } long absoluteSequenceNumber = ((IHaveExtensibleMetada)receivedEvent).Metadata.AbsoluteSequenceNumber; absoluteSequenceNumber.Should().Be(storableEvent.Id); }
public static InMemoryStoredEvent ToInMemoryStoredEvent(this StorableEvent e) => new InMemoryStoredEvent { SequenceNumber = e.SequenceNumber, AggregateId = e.AggregateId.ToString(), Timestamp = e.Timestamp, Type = e.Type, Body = e.Body, ETag = e.ETag, StreamName = e.StreamName };
public void UtcTime_setter_accurately_converts_values_forwarded_to_TimeStamp_setter() { var now = DateTime.UtcNow; var e = new StorableEvent { UtcTime = now }; e.Timestamp.Should().Be(now); }
public void UtcTime_getter_accurately_converts_values_set_via_TimeStamp_setter() { var now = DateTime.UtcNow; var e = new StorableEvent { Timestamp = now }; e.UtcTime.Should().Be(now); }
/// <summary> /// Creates an in-memory stored event from the specified <see cref="StorableEvent" />. /// </summary> /// <param name="e">The event from which to create an in-memory stored event.</param> public static InMemoryStoredEvent ToInMemoryStoredEvent(this StorableEvent e) { var @event = new InMemoryStoredEvent { SequenceNumber = e.SequenceNumber, AggregateId = e.AggregateId.ToString(), Timestamp = e.Timestamp, Type = e.Type, Body = e.Body, ETag = e.ETag, StreamName = e.StreamName }; @event.Metadata.AbsoluteSequenceNumber = e.Id; return(@event); }
public void Repository_will_not_try_to_source_events_from_a_different_aggregate_type() { Guid id = Guid.NewGuid(); var e = new StorableEvent { AggregateId = id, Type = "SomeEventType", StreamName = "SomeAggregateType", Body = new { Something = Any.Words() }.ToJson() }; SaveEventsDirectly(e); var repository = CreateRepository <Order>(); var order = repository.GetLatest(id); order.Should().BeNull(); }
public async Task ReadModelCatchup_does_not_query_events_that_no_subscribed_projector_is_interested_in() { Events.Write(100, _ => Events.Any()); Events.Write(1, _ => new Order.Created()); var projector2 = Projector.Create <CustomerAccount.Created>(e => { }); StorableEvent extraneousEvent = null; using (var catchup = CreateReadModelCatchup(projector2)) using (var eventStore = EventStoreDbContext()) { var eventsQueried = 0; catchup.Progress .Where(s => !s.IsStartOfBatch) .ForEachAsync(s => { var eventId = s.CurrentEventId; var @event = eventStore.Events.Single(e => e.Id == eventId); if (@event.StreamName != "CustomerAccount" || @event.Type != "Created") { extraneousEvent = @event; catchup.Dispose(); } eventsQueried++; }); await catchup.Run() .ContinueWith(r => catchup.Dispose()); Console.WriteLine(new { eventsQueried }); } if (extraneousEvent != null) { Assert.Fail(string.Format("Found an event that should not have been queried from the event store: {0}:{1} (#{2})", extraneousEvent.StreamName, extraneousEvent.Type, extraneousEvent.Id)); } }
public async Task Events_that_cannot_be_deserialized_to_the_expected_type_are_logged_as_EventHandlingErrors() { var badEvent = new StorableEvent { Actor = Any.Email(), StreamName = typeof(Order).Name, Type = typeof(Order.ItemAdded).Name, Body = new { Price = "oops this is not a number" }.ToJson(), SequenceNumber = Any.PositiveInt(), AggregateId = Any.Guid(), UtcTime = DateTime.UtcNow }; using (var eventStore = EventStoreDbContext()) { eventStore.Events.Add(badEvent); await eventStore.SaveChangesAsync(); } using (var catchup = CreateReadModelCatchup(new Projector1())) { await catchup.Run(); } using (var readModels = ReadModelDbContext()) { var failure = readModels.Set <EventHandlingError>() .OrderByDescending(e => e.Id) .First(e => e.AggregateId == badEvent.AggregateId); failure.Error.Should().Contain("JsonReaderException"); failure.SerializedEvent.Should().Contain(badEvent.Body); failure.Actor.Should().Be(badEvent.Actor); failure.OriginalId.Should().Be(badEvent.Id); failure.AggregateId.Should().Be(badEvent.AggregateId); failure.SequenceNumber.Should().Be(badEvent.SequenceNumber); failure.StreamName.Should().Be(badEvent.StreamName); failure.EventTypeName.Should().Be(badEvent.Type); } }