public async Task <TView> UpdateAsync(string subject, Func <TView, TView> update, CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                _logger.LogInformation($"{nameof(RedisProjectionWriter<TView>)}.{nameof(UpdateAsync)} was cancelled before execution");
                cancellationToken.ThrowIfCancellationRequested();
            }

            var view = _eventDeserializer.Deserialize <TView>(await _cache.GetAsync(BuildKey(subject), cancellationToken));

            update(view);
            await _cache.SetAsync(BuildKey(subject), _eventSerializer.Serialize(view), cancellationToken);

            return(view);
        }
        public async Task <Page> TryGetEventsAsync(long offset)
        {
            var results = new List <IEvent>();

            using (var context = _dbContextFactory.Create())
            {
                var events = await context.Events
                             .AsNoTracking()
                             .OrderBy(x => x.SequenceNo)
                             .Skip((int)offset)
                             .Take(250)
                             .ToListAsync();

                foreach (var @event in events)
                {
                    if (!_eventTypeCache.TryGet(@event.Type, out var type))
                    {
                        continue;
                    }

                    var result = (IEvent)_eventDeserializer.Deserialize(@event.Data, type);

                    results.Add(result);
                }

                return(new Page(offset + events.Count, offset, results));
            }
        }
        public IEventContext <IEvent> CreateContext(Entities.Event dbEvent)
        {
            if (dbEvent == null)
            {
                throw new ArgumentNullException(nameof(dbEvent));
            }

            if (!_eventTypeCache.TryGet(dbEvent.Type, out var type))
            {
                throw new ArgumentException($"Could not find event type for '{dbEvent.Type}'");
            }

            var @event = (IEvent)_eventDeserializer.Deserialize(dbEvent.Data, type);

            if (_cache.TryGetValue(type, out var activator))
            {
                return(activator(dbEvent.StreamId, @event, dbEvent.CorrelationId, dbEvent.CausationId, @event.Timestamp, Actor.From(dbEvent.Actor)));
            }

            activator = BuildActivator(typeof(EventContext <>).MakeGenericType(type));

            _cache.TryAdd(type, activator);

            var correlationId = dbEvent.CorrelationId != null?CorrelationId.From(dbEvent.CorrelationId) : (CorrelationId?)null;

            var causationId = dbEvent.CausationId != null?CausationId.From(dbEvent.CorrelationId) : (CausationId?)null;

            return(activator(dbEvent.StreamId, @event, correlationId, causationId, @event.Timestamp, Actor.From(dbEvent.Actor)));
        }
Exemple #4
0
        private Task On(RawEvent rawEvent, Position?position, DateTime eventCreationTime)
        {
            var @event = _deserializer.Deserialize(rawEvent);

            _log.Debug("Projecting event {event}", rawEvent.Body.ToString());
            try
            {
                // return Measure(() =>// Should be moved to a messenger decorator
                //     {
                var envelopedEvent = new EventEnvelope(
                    new MessageChainInfo(@event.Id.ToString()
                                         , @event.Metadata.CorrelationId
                                         , @event.Metadata.CausationId)
                    , @event.Body);
                _messenger.Dispatch(envelopedEvent);
                return(_checkpointStore.StoreCheckpoint(position));
                // }, rawEvent.EventType
                // , eventCreationTime
                // , _subscriptionName);
            }
            catch (Exception exception)
            {
                _log.Error(exception
                           , "Error occured when projecting the event {event} from {subscriptionName}"
                           , @event
                           , _subscriptionName);
                throw;
            }
        }
        public void ShouldDeserializeEvent()
        {
            var registrationId = new RegistrationId(1);
            var publishedOn    = DateTime.UtcNow;
            var domainEvent    = new RegistrationPaid(registrationId, new ExternalRegistrationId(), publishedOn);

            var serialized = _eventSerializer.Serialize(domainEvent);

            var deserialized = _eventDeserializer.Deserialize(serialized.Value);

            deserialized.IsSuccess.Should().BeTrue();

            var deserializedEvent = deserialized.Value as IEvent;

            deserializedEvent.Should().NotBeNull();
            deserializedEvent.GetType().Should().Be <RegistrationPaid>();
            deserializedEvent.PublishedOn.Should().Be(publishedOn);
        }
        public IEventContext <IEvent> CreateContext(ReceivedMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (!_eventTypeCache.TryGet(message.RoutingKey, out var type))
            {
                throw new ArgumentException($"Could not find event type for '{message.RoutingKey}'");
            }

            var eventData = Encoding.UTF8.GetString(message.Body);
            var @event    = (IEvent)_eventDeserializer.Deserialize(eventData, type);

            string        streamId      = null;
            CorrelationId?correlationId = null;
            CausationId?  causationId   = null;
            string        actor         = null;

            if (message.BasicProperties.Headers != null)
            {
                if (message.BasicProperties.Headers.ContainsKey(nameof(IEventContext <IEvent> .StreamId)))
                {
                    streamId = message.BasicProperties.Headers[nameof(IEventContext <IEvent> .StreamId)]?.ToString();
                }

                if (message.BasicProperties.Headers.ContainsKey(nameof(IEventContext <IEvent> .CorrelationId)))
                {
                    var value = message.BasicProperties.Headers[nameof(IEventContext <IEvent> .CorrelationId)]?.ToString();
                    correlationId = value != null?CorrelationId.From(value) : (CorrelationId?)null;
                }

                if (message.BasicProperties.Headers.ContainsKey(nameof(IEventContext <IEvent> .CausationId)))
                {
                    var value = message.BasicProperties.Headers[nameof(IEventContext <IEvent> .CausationId)]?.ToString();
                    causationId = value != null?CausationId.From(value) : (CausationId?)null;
                }

                if (message.BasicProperties.Headers.ContainsKey(nameof(IEventContext <IEvent> .Actor)))
                {
                    actor = message.BasicProperties.Headers[nameof(IEventContext <IEvent> .Actor)]?.ToString();
                }
            }

            if (_cache.TryGetValue(type, out var activator))
            {
                return(activator(streamId, @event, correlationId, causationId, @event.Timestamp, Actor.From(actor ?? "<Unknown>")));
            }

            activator = BuildActivator(typeof(EventContext <>).MakeGenericType(type));

            _cache.TryAdd(type, activator);

            return(activator(streamId, @event, correlationId, causationId, @event.Timestamp, Actor.From(actor ?? "<Unknown>")));
        }
Exemple #7
0
        public async Task <Optional <Snapshot> > GetLastSnapshot(string snapshotStream)
        {
            var existingSnapshot = await GetLastSnapshotStreamDocumentByIdAsync(snapshotStream);

            if (!existingSnapshot.HasValue)
            {
                return(Optional <Snapshot> .Empty);
            }

            var eState = _deserializer.Deserialize(Type.GetType(existingSnapshot.Value.Type, true), existingSnapshot.Value.State);

            return(new Optional <Snapshot>(new Snapshot(int.Parse(existingSnapshot.Value.EventPosition), eState)));
        }
Exemple #8
0
 public IStreamEvent Deserialize(ReadOnlySpan <byte> data, bool isNull, SerializationContext context)
 {
     try
     {
         return(_deserializer.Deserialize(data));
     }
     catch (Exception ex)
     {
         throw new InvalidEventException(
                   context.Topic,
                   $"Can't deserialize event. Deserializer type {_deserializer.GetType().Name}",
                   ex);
     }
 }
        // ReSharper disable once CognitiveComplexity
        public Task ConsumeAsync(CancellationToken cancellationToken)
        {
            return(Task.Run(
                       async() =>
            {
                var topics = string.Join(",", _eventConsumer.Subscription);

                _logger.LogInformation(
                    "started Kafka consumer {ConsumerName} on {ConsumerTopic}",
                    _eventConsumer.Name,
                    topics);

                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        ConsumeResult <TAggregateId, string> cr = _eventConsumer.Consume(cancellationToken);

                        if (cr.IsPartitionEOF)
                        {
                            continue;
                        }

                        var messageTypeHeader = cr.Message.Headers.First(h => h.Key == "type");
                        var eventType = Encoding.UTF8.GetString(messageTypeHeader.GetValueBytes());

                        IDomainEvent <TAggregateId> @event =
                            _eventDeserializer.Deserialize <TAggregateId>(eventType, cr.Message.Value);

                        await OnEventReceivedAsync(@event, cancellationToken)
                        .ConfigureAwait(false);
                    }
                    catch (OperationCanceledException ex)
                    {
                        _logger.LogWarning(
                            ex,
                            "consumer {ConsumerName} on {ConsumerTopic} was stopped: {StopReason}",
                            _eventConsumer.Name,
                            topics,
                            ex.Message);
                        OnConsumerStopped();
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"an exception has occurred while consuming a message: {ex.Message}");
                    OnExceptionThrown(ex);
                }
            },
        private async Task OnEventDelivered(EventStoreSubscription subscription, ResolvedEvent resolvedEvent)
        {
            if (!_typeResolver.TryGetType(resolvedEvent.Event.EventType, out var eventType))
            {
                return;
            }
            if (!_subscribedEventTypes.Contains(eventType))
            {
                return;
            }
            var @event = _deserializer.Deserialize(resolvedEvent, eventType);

            foreach (var eventProcessor in _eventProcessors)
            {
                await eventProcessor.ProcessAsync(@event);
            }
        }
        public void AssertEvents(string scopeIdentity, string stream, params Event[] expected)
        {
            _streamPositions.TryGetValue(stream, out int position);

            Assert.True(Streams.TryGetValue(stream, out IReadOnlyList <SerializedEvent> actual), $"Expected stream '{stream}' was not found");
            var doesntMatter = new Dictionary <string, long>()
            {
                [stream] = ExpectedVersion.Exists
            };

            _streamPositions.TryGetValue(stream, out var start);
            List <Event> actualEvents = new List <Event>();

            _eventDeserializer.Deserialize(scopeIdentity, typeof(object), doesntMatter,
                                           ReadEventsForward(stream, start, 1000, _ => { }, true), e => actualEvents.Add(e)).Wait();
            Assert.Equal(EventsToString(expected),
                         EventsToString(actualEvents));
        }
Exemple #12
0
        public Task ConsumeAsync(CancellationToken stoppingToken)
        {
            return(Task.Run(async() =>
            {
                var topics = string.Join(",", _consumer.Subscription);
                _logger.LogInformation("started Kafka consumer {ConsumerName} on {ConsumerTopic}", _consumer.Name, topics);

                while (!stoppingToken.IsCancellationRequested)
                {
                    try
                    {
                        var cr = _consumer.Consume(stoppingToken);
                        if (cr.IsPartitionEOF)
                        {
                            continue;
                        }

                        var messageTypeHeader = cr.Message.Headers.First(h => h.Key == "type");
                        var eventType = Encoding.UTF8.GetString(messageTypeHeader.GetValueBytes());

                        var @event = _eventDeserializer.Deserialize <TKey>(eventType, cr.Message.Value);
                        if (null == @event)
                        {
                            throw new SerializationException($"unable to deserialize event {eventType} : {cr.Message.Value}");
                        }

                        await OnEventReceived(@event);
                    }
                    catch (OperationCanceledException ex)
                    {
                        _logger.LogWarning(ex, "consumer {ConsumerName} on {ConsumerTopic} was stopped: {StopReason}", _consumer.Name, topics, ex.Message);
                        OnConsumerStopped();
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"an exception has occurred while consuming a message: {ex.Message}");
                        OnExceptionThrown(ex);
                    }
                }
            }, stoppingToken));
        }
Exemple #13
0
        public void Setup()
        {
            if (Complexity == "Simple")
            {
                _ev = TestData.SimpleEventInstance();
            }
            else
            {
                _ev = TestData.ComplexEventInstance();
            }

            // BTDB Setup
            _eventSerializer   = new EventSerializer();
            _eventDeserializer = new EventDeserializer();
            bool hasMedataData;
            var  meta = _eventSerializer.Serialize(out hasMedataData, _ev).ToAsyncSafe();

            _eventSerializer.ProcessMetadataLog(meta);
            _eventDeserializer.ProcessMetadataLog(meta);
            _btdbSerializedData = _eventSerializer.Serialize(out hasMedataData, _ev).ToAsyncSafe();
            BtdbByteSize        = _btdbSerializedData.Length;
            object obj;

            _eventDeserializer.Deserialize(out obj, _btdbSerializedData);
            obj.Should().BeEquivalentTo(_ev);

            // ProtoBuf Setup
            Serializer = ModelFactory.CreateModel();
            _eventType = typeof(Event);
            _memStream = new MemoryStream();
            Serializer.Serialize(_memStream, _ev);
            ProtoBufByteSize    = (int)_memStream.Length;
            _memStream.Position = 0;
            Serializer.Deserialize(_memStream, null, _eventType).Should().BeEquivalentTo(_ev);

            BtdbSerialization();
            BtdbDeserialization();
            ProtoBufSerialization();
            ProtoBufDeserialization();
        }
Exemple #14
0
        public Task ConsumeAsync(CancellationToken stoppingToken)
        {
            return(Task.Run(async() =>
            {
                var topics = string.Join(",", _consumer.Subscription);

                while (!stoppingToken.IsCancellationRequested)
                {
                    try
                    {
                        ConsumeResult <TKey, string> cr = _consumer.Consume(stoppingToken);
                        if (cr.IsPartitionEOF)
                        {
                            continue;
                        }

                        IHeader messageTypeHeader = cr.Message.Headers.First(h => h.Key == "type");
                        string eventType = Encoding.UTF8.GetString(messageTypeHeader.GetValueBytes());

                        IDomainEvent <TKey> @event = _eventDeserializer.Deserialize <TKey>(eventType, cr.Message.Value);
                        if (@event == null)
                        {
                            throw new SerializationException($"unable to deserialize event {eventType} : {cr.Message.Value}");
                        }

                        await OnEventReceived(@event);
                    }
                    catch (OperationCanceledException ex)
                    {
                        OnConsumerStopped(ex);
                        throw;
                    }
                    catch (Exception ex)
                    {
                        OnExceptionThrown(ex);
                    }
                }
            }, stoppingToken));
        }
        private Action <EventStoreCatchUpSubscription, ResolvedEvent> EventAppeared(
            Projector <TConnection> projection,
            string projectionName
            ) => async(_, e) =>
        {
            // check system event
            if (e.OriginalEvent.EventType.StartsWith("$"))
            {
                return;
            }

            // get the configured clr type name for deserializing the event
            //var eventType = _typeMapper.GetType(e.Event.EventType);

            // try to execute the projection
            await projection.ProjectAsync(_getConnection(), ComposeEnvelope(_serializer.Deserialize(e), e.OriginalPosition.Value.CommitPosition));

            Log.Debug("{projection} projected {eventType}({eventId})", projectionName, e.Event.EventType, e.Event.EventId);

            //**** Storing Checkpoint ****/
            //1.Way
            // await projection.ProjectAsync(_getConnection(), new SetProjectionPosition(e.OriginalPosition));
            //2.Way
            await _checkpointStore.SetLastCheckpoint(projectionName, e.OriginalPosition);

            var          metadata    = JsonConvert.DeserializeObject <EventMetadata>(Encoding.UTF8.GetString(e.Event.Metadata));
            ISnapshotter snapshotter = _snapshotters.FirstOrDefault(
                x => x.ShouldTakeSnapshot(Type.GetType(metadata.AggregateAssemblyQualifiedName), e) && !metadata.IsSnapshot);

            if (snapshotter != null)
            {
                await snapshotter.Take(e.OriginalStreamId);

                Log.Debug("Snapshot was taken for {aggregate} on event{eventType}{eventId} at number {eventNumber}",
                          metadata.AggregateType, e.Event.EventType, e.Event.EventId, e.Event.EventNumber);
            }
        };
Exemple #16
0
        private async Task <bool> PublishAsync(CancellationToken stoppingToken)
        {
            using var scopedContainer = _serviceProvider.CreateScope();
            var transactionProvider =
                scopedContainer.ServiceProvider.GetRequiredService <ITransactionProvider>();
            var serializedEventRepository = scopedContainer.ServiceProvider
                                            .GetRequiredService <ISerializedEventRepository>();

            await transactionProvider.BeginTransactionAsync();

            Console.WriteLine(
                $"{DateTime.UtcNow} Publishing (batch size: {_settings.BatchSize})...");
            var eventsToPublish =
                await serializedEventRepository.GetUnpublishedEventsAsync(_settings.BatchSize);

            var publishActions = eventsToPublish
                                 .Select(serializedEventEntity => _eventDeserializer.Deserialize(serializedEventEntity.SerializedEvent)
                                         .OnSuccess(@event => _busControl.Publish(@event,
                                                                                  context => AssignMessageId(context, serializedEventEntity), stoppingToken)));

            Result.Combine(await Task.WhenAll(publishActions))
            .OnSuccess(() => serializedEventRepository.RemoveRange(eventsToPublish))
            .OnFailure(errors => throw new InvalidOperationException(JsonConvert.SerializeObject(errors)));

            await transactionProvider.CommitTransactionAsync();

            Console.WriteLine(
                $"{DateTime.UtcNow} Publish completed (events: {eventsToPublish.Count}, batch size: {_settings.BatchSize})...");

            return(eventsToPublish.Count < _settings.BatchSize);

            void AssignMessageId(PublishContext context, SerializedEventEntity serializedEventEntity)
            {
                context.MessageId = serializedEventEntity.MessageId;
            }
        }
Exemple #17
0
        public void BtdbDeserialization()
        {
            object obj;

            _eventDeserializer.Deserialize(out obj, _btdbSerializedData);
        }