Exemple #1
0
        public TAggregate GetById <TAggregate>(Guid id, int version = int.MaxValue) where TAggregate : class, IEventSource
        {
            if (version <= 0)
            {
                throw new InvalidOperationException("Cannot get version <= 0");
            }

            var streamName = _streamNameBuilder.GenerateForAggregate(typeof(TAggregate), id);
            var aggregate  = ConstructAggregate <TAggregate>();


            long sliceStart = 0;
            StreamEventsSlice currentSlice;
            var appliedEventCount = 0;

            do
            {
                long sliceCount = sliceStart + ReadPageSize <= version
                    ? ReadPageSize
                    : version - sliceStart;

                currentSlice = _streamStoreConnection.ReadStreamForward(streamName, sliceStart, (int)sliceCount);

                if (currentSlice is StreamNotFoundSlice)
                {
                    throw new AggregateNotFoundException(id, typeof(TAggregate));
                }

                if (currentSlice is StreamDeletedSlice)
                {
                    throw new AggregateDeletedException(id, typeof(TAggregate));
                }

                sliceStart = currentSlice.NextEventNumber;

                appliedEventCount += currentSlice.Events.Length;
                aggregate.RestoreFromEvents(currentSlice.Events.Select(evt => _eventSerializer.Deserialize(evt)));
            } while (version > currentSlice.NextEventNumber && !currentSlice.IsEndOfStream);

            if (version != Int32.MaxValue && version != appliedEventCount)
            {
                throw new AggregateVersionException(id, typeof(TAggregate), version, aggregate.ExpectedVersion);
            }

            if (version != Int32.MaxValue && aggregate.ExpectedVersion != version - 1)
            {
                throw new AggregateVersionException(id, typeof(TAggregate), version, aggregate.ExpectedVersion);
            }

            return(aggregate);
        }
        public IReadOnlyList <IDomainEvent> GetEvents(Guid aggregateId)
        {
            var events = new List <IDomainEvent>();

            using (var context = new EventStoreContext(ConnectionString.Get()))
            {
                foreach (var dbEvent in context.Events.Where(a => a.AggregateId == aggregateId))
                {
                    events.Add(_eventSerializer.Deserialize <IDomainEvent>(dbEvent.Data));
                }
            }

            return(events);
        }
Exemple #3
0
 private IRecordedEvent Transform(ReactiveEventEntity entity)
 {
     return(new RecordedEvent(
                entity.EventNumber,
                entity.EventId,
                entity.EventType,
                entity.AggregateId,
                entity.AggregateType,
                entity.AggregateVersion,
                _serializer.Deserialize(entity.SerializedData, _typeMapper.GetEventType(entity.EventType)) as IEvent,
                _serializer.Deserialize(entity.SerializedMetadata, _typeMapper.GetMetadataType(entity.EventType)) as IMetadata,
                DateTimeOffset.Parse(entity.Recorded)
                ));
 }
Exemple #4
0
        public async Task <TA> RehydrateAsync(TKey key)
        {
            var partitionKey = new PartitionKey(key.ToString());

            var events = new List <IDomainEvent <TKey> >();

            using var setIterator = _container.GetItemQueryIterator <EventData <TKey> >(requestOptions: new QueryRequestOptions { MaxItemCount = 100, PartitionKey = partitionKey });
            while (setIterator.HasMoreResults)
            {
                foreach (var item in await setIterator.ReadNextAsync())
                {
                    var @event = _eventSerializer.Deserialize <TKey>(item.Type, item.Data);
                    events.Add(@event);
                }
            }

            if (!events.Any())
            {
                return(null);
            }

            var result = BaseAggregateRoot <TA, TKey> .Create(events.OrderBy(e => e.AggregateVersion));

            return(result);
        }
 public static IObservable <EventWithPosition <TEvent> > DeserializeWithPosition <TEvent>(
     this IObservable <Event> source,
     Action <Exception> exceptionHandler = null,
     IEventSerializer serializer         = null)
 {
     serializer       = serializer ?? new EventSerializer();
     exceptionHandler = exceptionHandler ?? (_ => { });
     return
         (source.Select(@event =>
     {
         if ([email protected](typeof(TEvent).Name))
         {
             return default(EventWithPosition <TEvent>);
         }
         try
         {
             return new EventWithPosition <TEvent>(
                 serializer.Deserialize <TEvent>(@event),
                 @event.Position);
         }
         catch (Exception e)
         {
             exceptionHandler(e);
             return default(EventWithPosition <TEvent>);
         }
     })
          .Where(e => !Equals(e, default(EventWithPosition <TEvent>))));
 }
Exemple #6
0
        public async Task <T> Load <T>(string id) where T : Aggregate, new()
        {
            Ensure.NotEmptyString(id, nameof(id));

            var stream    = StreamName.For <T>(id);
            var aggregate = new T();

            try {
                await _eventStore.ReadStream(stream, StreamReadPosition.Start, Fold);
            }
            catch (Exceptions.StreamNotFound e) {
                throw new Exceptions.AggregateNotFound <T>(id, e);
            }

            return(aggregate);

            void Fold(StreamEvent streamEvent)
            {
                var evt = Deserialize(streamEvent);

                if (evt == null)
                {
                    return;
                }

                aggregate !.Fold(evt);
            }

            object?Deserialize(StreamEvent streamEvent)
            => _serializer.Deserialize(streamEvent.Data.AsSpan(), streamEvent.EventType);
        }
        private void Run_ShouldWriteEventData(IEventSerializer serializer)
        {
            var configuration = SetupDatabase();

            var subscriber = new DatabaseEventSubscriber <IEvent>(configuration, serializer);

            var aggregateId  = Guid.NewGuid().ToString();
            var expectedData = $"This is my random data {Guid.NewGuid()}";
            var testEvent    = new EventWithData(aggregateId, expectedData);

            subscriber.OnEvent(testEvent);

            var connection = configuration.CreateConnection();

            connection.Open();
            var command = connection.CreateCommand();

            command.CommandText = $"select data from {configuration.TableName}";

            var actualBytes = command.ExecuteScalar();
            var actual      = serializer.Deserialize(testEvent.Type, (byte[])actualBytes);

            Assert.IsType <EventWithData>(actual);
            Assert.Equal(expectedData, ((EventWithData)actual).Data);
        }
        protected async Task Handler(StreamSubscription sub, ResolvedEvent re, CancellationToken cancellationToken) {
            _debugLog?.Invoke(
                "Subscription {Subscription} got an event {@Event}",
                sub.SubscriptionId,
                re
            );

            _lastProcessedPosition = GetPosition(re);

            if (re.Event.EventType.StartsWith("$")) {
                await Store();
            }

            try {
                var evt = _eventSerializer.Deserialize(re.Event.Data.Span, re.Event.EventType);

                if (evt != null) {
                    _debugLog?.Invoke("Handling event {Event}", evt);

                    await Task.WhenAll(
                        _projections.Select(
                            x => x.HandleEvent(evt, (long?) re.OriginalPosition?.CommitPosition)
                        )
                    );
                }
            }
            catch (Exception e) {
                _log.LogWarning(e, "Error when handling the event {Event}", re.Event.EventType);
            }

            await Store();

            Task Store() => StoreCheckpoint(GetPosition(re), cancellationToken);
        }
        public async Task HandleAsync(Event @event)
        {
            _context.KeepAlive();
            await _handler.HandleAsync(_context, _serializer.Deserialize(@event));

            _context.KeepAlive();
        }
 public async Task HandleAsync(Event @event)
 {
     var command = _serializer.Deserialize(@event);
     await _handler.HandleAsync(
         new DomainCommandContext(_queryEndpointId, command.CreateEventContext(_hubClientFactory)),
         command.Data);
 }
Exemple #11
0
        public async Task <KeyValuePair <int, GrainState <T> > > ReadStateFromStorage()
        {
            _stream = $"{typeof(T).Name}:{ModelVersion()}:{this.GrainId()}";

            var stream = _eventStore.ReadStreamAsync(
                Direction.Forwards,
                _stream,
                StreamPosition.Start);

            var state   = new GrainState <T>();
            var version = 0;

            if (await stream.ReadState != ReadState.StreamNotFound)
            {
                await foreach (var resolvedEvent in stream)
                {
                    var json = Encoding.UTF8.GetString(resolvedEvent.Event.Data.Span);

                    try
                    {
                        var eventObj = _eventSerializer.Deserialize(typeof(T), resolvedEvent.Event.EventType, json);

                        state = state.Apply(eventObj);
                        version++;
                    }
                    catch (Exception ex)
                    {
                        _logger.LogCritical(5004, ex, ex.Message);
                        return(new KeyValuePair <int, GrainState <T> >(-1, new GrainState <T>()));
                    }
                }
            }

            return(new KeyValuePair <int, GrainState <T> >(version, state));
        }
        public IDisposable SubscribeToStreamFrom(
            string stream,
            long?lastCheckpoint,
            bool resolveLinkTos,
            Action <Message> eventAppeared,
            Action liveProcessingStarted = null,
            Action <SubscriptionDropReason, Exception> subscriptionDropped = null,
            UserCredentials userCredentials = null,
            int readBatchSize = 500)
        {
            var settings = new CatchUpSubscriptionSettings(10, readBatchSize, false);

            StreamName = stream;
            var sub = _eventStoreConnection.SubscribeToStreamFrom(
                stream,
                lastCheckpoint,
                settings,
                resolvedEvent => {
                Interlocked.Exchange(ref _position, resolvedEvent.EventNumber);
                eventAppeared(_serializer.Deserialize(resolvedEvent) as Message);
            },
                _ => liveProcessingStarted?.Invoke(),
                (reason, exception) => subscriptionDropped?.Invoke(reason, exception),
                userCredentials);

            return(new Disposer(() => { sub.Dispose(); return Unit.Default; }));
        }
Exemple #13
0
        private async Task HandleEvent(StreamSubscription subscription, ResolvedEvent resolvedEvent,
                                       CancellationToken cancellationToken)
        {
            var domainEvent = _eventSerializer.Deserialize(resolvedEvent);

            if (domainEvent == null)
            {
                return;
            }

            _logger.LogInformation($"PullRequestCommentsProjector handled event: {domainEvent}");
            switch (domainEvent)
            {
            case SingleCommentWasAdded added:
                var comment = new PullRequestComment
                {
                    PullRequestId = added.PullRequestId,
                    CommentId     = added.CommentId,
                    PostedAt      = added.OccurredAt,
                    Author        = added.Author,
                    Text          = added.Text
                };
                await _repository.Save(comment);

                break;
            }
        }
Exemple #14
0
 private IEnumerable <IRecordedEvent> Transform(IEnumerable <RecordedEventEntity> entities)
 {
     foreach (var entity in entities)
     {
         yield return(new RecordedEvent(
                          entity.EventNumber,
                          entity.EventId,
                          entity.EventType,
                          entity.AggregateId,
                          entity.AggregateType,
                          entity.AggregateVersion,
                          _eventSerializer.Deserialize(entity.SerializedData, _typeMapper.GetEventType(entity.EventType)) as IEvent,
                          _eventSerializer.Deserialize(entity.SerializedMetadata, _typeMapper.GetMetadataType(entity.EventType)) as IMetadata,
                          entity.Recorded
                          ));
     }
 }
Exemple #15
0
 private StoredEvent ToStoredEvent(RecordedEvent recordedEvent)
 => new StoredEvent(
     recordedEvent.StreamId,
     recordedEvent.Id,
     recordedEvent.Number,
     recordedEvent.Type,
     recordedEvent.Created,
     (IDomainEvent)_serializer.Deserialize(recordedEvent));
 protected virtual void GotEvent(RecordedEvent recordedEvent)
 {
     Interlocked.Exchange(ref StreamPosition, recordedEvent.EventNumber);
     if (Serializer.Deserialize(recordedEvent) is IMessage @event)
     {
         Bus.Publish(@event);
     }
 }
        public T Load(int id)
        {
            IList <Event> result = _session.QueryOver <Event>().Where(f => f.AggregateId == id).List();
            IEnumerable <IDomainEvent> domainEvents = result.Select(f => _serializer.Deserialize(Type.GetType(f.Type, true), f.Data));
            T o = new T();

            o.LoadFromHistory(domainEvents);
            return(o);
        }
 private DomainEventStream ConvertFrom(EventStream record)
 {
     return(new DomainEventStream(
                record.CommandId,
                record.AggregateRootId,
                record.AggregateRootTypeName,
                record.Version,
                record.CreatedOn,
                _eventSerializer.Deserialize <IDomainEvent>(_jsonSerializer.Deserialize <IDictionary <string, string> >(record.Events))));
 }
Exemple #19
0
        Event Deserialize(ResolvedEvent @event, IEventSerializer serializer)
        {
            var e = serializer.Deserialize(
                new EventData(
                    @event.OriginalEvent.EventId, @event.OriginalEvent.EventType,
                    false, @event.OriginalEvent.Data,
                    @event.OriginalEvent.Metadata));

            e.Version = @event.Event.EventNumber;
            return(e);
        }
Exemple #20
0
        public IEnumerable <IDomainEvent> GetEventsFor(Guid aggregateId)
        {
            var results = _repository.Get(x => x.AggregateId == aggregateId).ToList();

            foreach (var eventEntity in results)
            {
                var type        = _typeFactory.GetFor(eventEntity.EventName);
                var domainEvent = _serializer.Deserialize(eventEntity.EventData, type);
                yield return(domainEvent);
            }
        }
Exemple #21
0
        private IDomainEvent Deserialize(Models.Event entity)
        {
            var domainEvent = _eventSerializer.Deserialize(entity.Data, Type.GetType(entity.Type));

            domainEvent.AggregateId     = entity.AggregateId;
            domainEvent.AppliedByUserId = entity.AppliedByUserId;
            domainEvent.Version         = entity.AggregateVersion;
            domainEvent.Timestamp       = entity.Timestamp;
            domainEvent.Id = entity.EventId;

            return(domainEvent);
        }
Exemple #22
0
        protected async Task HandleMessage(Message msg)
        {
            var eventType   = msg.UserProperties["type"] as string;
            var domainEvent = _eventSerializer.Deserialize <Guid>(eventType, msg.Body);

            if (null == domainEvent)
            {
                throw new SerializationException($"unable to deserialize event {eventType} : {msg.Body}");
            }

            var @event = EventReceivedFactory.Create((dynamic)domainEvent);
            await _mediator.Publish(@event, CancellationToken.None);
        }
Exemple #23
0
        public void OnRelayMessage(byte[] data)
        {
            var remoteEvt = _serializer.Deserialize(data);

            if (_callbacks.ContainsKey(remoteEvt.Type))
            {
                _callbacks[remoteEvt.Type](remoteEvt);
            }
            else
            {
                Debug.Log($"No follow up for relayed message of type {remoteEvt.Type}");
            }
        }
Exemple #24
0
        private IEnumerable <IRecordedEvent> QueryEvents(string query)
        {
            using (var connection = new SqlConnection(_options.ConnectionString))
            {
                var command = new SqlCommand(query, connection);

                connection.Open();

                var reader = command.ExecuteReader();

                while (reader.Read())
                {
                    var eventNumber        = reader.GetInt64(0);
                    var eventId            = reader.GetGuid(1);
                    var eventType          = reader.GetString(2);
                    var aggregateId        = reader.GetGuid(3);
                    var aggregateType      = reader.GetString(4);
                    var aggregateVersion   = reader.GetInt64(5);
                    var serializedData     = reader.GetString(6);
                    var serializedMetadata = reader.GetString(7);
                    var recorded           = reader.GetDateTimeOffset(8);

                    yield return(new RecordedEvent(
                                     eventNumber,
                                     eventId,
                                     eventType,
                                     aggregateId,
                                     aggregateType,
                                     aggregateVersion,
                                     _serializer.Deserialize(serializedData, _typeMapper.GetEventType(eventType)) as IEvent,
                                     _serializer.Deserialize(serializedMetadata, _typeMapper.GetMetadataType(eventType)) as IMetadata,
                                     recorded
                                     ));
                }
            }
        }
        protected virtual void EventRead(RecordedEvent recordedEvent)
        {
            // do not publish or increase counters if cancelled
            if (_cancelled)
            {
                return;
            }

            Interlocked.Exchange(ref StreamPosition, recordedEvent.EventNumber);
            firstEventRead = true;

            if (Serializer.Deserialize(recordedEvent) is IMessage @event)
            {
                Bus.Publish(@event);
            }
        }
        private void Process <TEvent>(Action <TEvent> handle, BrokeredMessage brokeredMessage) where TEvent : DomainEvent
        {
            var jsonEvent           = brokeredMessage.GetBody <string>();
            var productDeletedEvent = _eventSerializer.Deserialize <TEvent>(jsonEvent);

            handle(productDeletedEvent);

            try
            {
                brokeredMessage.Complete();
            }
            catch (Exception ex)
            {
                //do something else, e.g log
                brokeredMessage.DeadLetter();                //move to dead letter queue to inspect later
            }
        }
Exemple #27
0
        public static TEvent ToDomainEvent <TEvent>(
            StoredDomainEvent storedEvent,
            IEventSerializer serializer)
            where TEvent : IDomainEvent
        {
            var eventType = default(Type);

            try
            {
                eventType = Type.GetType(storedEvent.AggregateRootTypeName);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(string.Format("Domain event type load error, because: {0}", ex));
            }

            return(serializer.Deserialize <TEvent>(storedEvent.EventBody));
        }
        public async Task Handle(NotificationMessage <string> notificationMessage, CancellationToken cancellationToken)
        {
            if (notificationMessage == null)
            {
                throw new ArgumentNullException(nameof(notificationMessage));
            }
            var eventStore = _jsonSerializer.Deserialize <EventStore>(notificationMessage.Message);
            var @event     = _eventSerializer.Deserialize <Event>(eventStore.TypeName, eventStore.PayLoad);
            var projection = Invoker.CreateInstanceOfProjection <SpeechProjection>();

            projection.Project(@event);
            if (projection.IsDeleted)
            {
                await _elasticSearchClient.DeleteAsync(projection).ContinueWith(
                    result =>
                {
                    if (result.Status == TaskStatus.RanToCompletion)
                    {
                        Console.WriteLine($"**ElasticSearchNotifer::Handle - DeleteAsync {projection.Id} ");
                        _publisher.PublishAsync(Topics.ReadModelAcknowledged, projection);
                    }
                    else if (result.Status == TaskStatus.Faulted)
                    {
                        Console.WriteLine($"**ElasticSearchNotifer::Handle - DeleteAsync {result.Exception?.GetBaseException().Message}");
                    }
                }, cancellationToken);
            }
            else
            {
                await _elasticSearchClient.CreateAsync(projection).ContinueWith(
                    result =>
                {
                    if (result.Status == TaskStatus.RanToCompletion)
                    {
                        Console.WriteLine($"**ElasticSearchNotifer::Handle - CreateAsync {projection.Id} ");
                        _publisher.PublishAsync(Topics.ReadModelAcknowledged, projection);
                    }
                    else if (result.Status == TaskStatus.Faulted)
                    {
                        Console.WriteLine($"**ElasticSearchNotifer::Handle - CreateAsync {result.Exception?.GetBaseException().Message}");
                    }
                }, cancellationToken);
            }
        }
        public MockRepositorySpecification()
        {
            StreamNameBuilder     = new PrefixedCamelCaseStreamNameBuilder();
            StreamStoreConnection = new MockStreamStoreConnection("Test");
            StreamStoreConnection.Connect();
            EventSerializer = new JsonMessageSerializer();
            MockRepository  = new StreamStoreRepository(StreamNameBuilder, StreamStoreConnection, EventSerializer);

            var connectorBus = new InMemoryBus("connector");

            StreamStoreConnection.SubscribeToAll(evt => {
                if (evt is ProjectedEvent)
                {
                    return;
                }
                connectorBus.Publish((IMessage)EventSerializer.Deserialize(evt));
            });
            RepositoryEvents = new TestQueue(connectorBus, new[] { typeof(Event) });
        }
Exemple #30
0
        Task OnEventReceived(string eventName, byte[] @event)
        {
            if (SubscriptionsManager.IsEmpty)
            {
                return(Task.CompletedTask);
            }

            var eventType = _eventNameTypeResolver.GetEventType(eventName);
            var eo        = _eventSerializer.Deserialize(eventType, @event);

            var handlers = SubscriptionsManager.GetHandlers(eventType, _serviceProvider);

            if (handlers == null)
            {
                return(Task.CompletedTask);
            }

            return(_eventReceiver.Invoke(eventType, eo, handlers));
        }
Exemple #31
0
 Event Deserialize(ResolvedEvent @event, IEventSerializer serializer) {
   var e = serializer.Deserialize(
     new EventData(
       @event.OriginalEvent.EventId, @event.OriginalEvent.EventType,
       false, @event.OriginalEvent.Data,
       @event.OriginalEvent.Metadata));
   e.Version = @event.Event.EventNumber;
   return e;
 }