private async Task <long> Dispatch <TProjection, TState>(string streamId, long version, Dictionary <string, TState> result) where TProjection : ProjectionBase <TProjection, TState>, new() where TState : new() { StreamEventsSlice eventsSlice; var p = new TProjection(); do { eventsSlice = await _connection.ReadStreamEventsForwardAsync(streamId, version, _configuration.SnapchotLimit, false).ConfigureAwait(false); var events = eventsSlice.Events.Select(e => EventSerializer.Deserialize(e.Event.Data, new Guid(e.Event.EventType))); foreach (var @event in events) { var type = @event.GetType(); var attr = type.GetCustomAttribute <EventTypeIdAttribute>(); if (attr == null) { throw new ArgumentException($"Mark e '{type.FullName}' with {nameof(EventTypeIdAttribute)}"); } var id = attr.Id; var dispatchedEvent = new DispatchedEvent { Event = @event, Metadata = new Metadata { EventId = Guid.NewGuid(), EventTypeId = id, StreamId = streamId } }; var partition = p.GetPartitioningKey(dispatchedEvent); if (string.IsNullOrWhiteSpace(partition) == false) { if (result.TryGetValue(partition, out var state) == false) { result[partition] = state = new TState(); } await p.Dispatch(dispatchedEvent, state).ConfigureAwait(false); } version++; } } while (!eventsSlice.IsEndOfStream); return(version); }
/// <summary> /// DispatchedEventをRmsEventに変換する。必要なデータが不足している場合nullを返す。 /// </summary> /// <param name="eventData">EventData</param> /// <returns>RmsEvent。必要な値が不足している場合、null。</returns> private RmsEvent ConvertEventDataToRmsEvent(DispatchedEvent eventData) { if (!eventData.HasNecessary()) { return(null); } return(new RmsEvent() { EdgeId = eventData.EdgeId, MessageId = eventData.MessageId, MessageDateTime = eventData.Enqueuedtime, MessageBody = eventData.Body, }); }
public override void OnDispatchedEvent(DispatchedEvent dispatchedEvent) { switch (dispatchedEvent.EventName) { case "start": { Start(); break; } case "retry": { Initialize(); break; } } }
public async Task TearDown() { var result = new Dictionary <string, TState>(); var p = new TProjection(); foreach (var @event in given) { var e = @event.Item2; var type = e.GetType(); var attr = type.GetCustomAttribute <EventTypeIdAttribute>(); if (attr == null) { throw new ArgumentException($"Mark e '{type.FullName}' with {nameof(EventTypeIdAttribute)}"); } var id = attr.Id; var dispatchedEvent = new DispatchedEvent { Event = e, Metadata = new Metadata { EventId = Guid.NewGuid(), EventTypeId = id, StreamId = @event.Item1 } }; var partition = p.GetPartitioningKey(dispatchedEvent); TState state; if (result.TryGetValue(partition, out state) == false) { result[partition] = state = new TState(); } await p.Dispatch(dispatchedEvent, state).ConfigureAwait(false); } var expected = Serialize(then); var observed = Serialize(result); var areEqual = expected.SequenceEqual(observed); if (areEqual == false) { Console.WriteLine("GIVEN:"); using (ConsoleExtensions.Indent()) { Write(given); } Console.WriteLine("THEN should be:"); using (ConsoleExtensions.Indent()) { Write(then); } Console.WriteLine("BUT was:"); using (ConsoleExtensions.Indent()) { Write(result); } TestExecutionContext.CurrentContext.CurrentResult. SetResult(ResultState.ChildFailure, "The state was different from expected.", " "); } }
/// <summary> /// EventDataから取得したRowBodyをDispatchedEventに変換する /// </summary> /// <param name="body">EventDataのBodyプロパティ</param> /// <param name="logger">ロガー</param> /// <returns>DispatchedEvent配列</returns> private DispatchedEvent[] GetDispatchedEvents(string body, ILogger logger) { return(DispatchedEvent.DeserializeIfInvalidThrowEx(body, logger)); }
public void Enqueue(DispatchedEvent ev) { eventQueue.Add(ev); }