/// <summary>
        /// Populates from in process event processors through discovery
        /// </summary>
        public void Populate()
        {
            foreach (var processor in _processors)
            {
                _logger.Trace($"Processor '{processor.AssemblyQualifiedName}'");
                processor.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).ToList().ForEach(_ => _logger.Trace($"{_.Name} {_.EventProcessorId()}"));
                var methods = processor.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(m => m.EventProcessorId().Value != Guid.Empty).ToList();
                foreach (var method in methods)
                {
                    _logger.Trace($"Method found '{method} {method:EventProcessorId()}'");

                    var parameterType    = method.GetParameters()[0].ParameterType;
                    var eventIdentifier  = _artifactTypeMap.GetArtifactFor(parameterType);
                    var eventProcessorId = method.EventProcessorId();

                    _logger.Trace($"EventProcessor identifier '{eventProcessorId}'");

                    var processMethodEventProcessor = new ProcessMethodEventProcessor(
                        _objectFactory,
                        _container,
                        eventProcessorId,
                        eventIdentifier,
                        parameterType,
                        method,
                        _logger);

                    _eventProcessors.Add(processMethodEventProcessor);
                }
            }
        }
        /// <inheritdoc/>
        public CommandRequest Convert(CorrelationId correlationId, ICommand command)
        {
            var commandAsJson       = _serializer.ToJson(command);
            var commandAsDictionary = _serializer.GetKeyValuesFromJson(commandAsJson);
            var artifact            = _artifactsTypeMap.GetArtifactFor(command.GetType());

            return(new CommandRequest(correlationId, artifact.Id, artifact.Generation, commandAsDictionary));
        }
        VersionedEventSource ToVersionedEventSource(UncommittedEvents uncommittedEvents)
        {
            var commit   = Convert.ToUInt64(uncommittedEvents.EventSource.Version.Commit);
            var sequence = Convert.ToUInt32(uncommittedEvents.EventSource.Version.Sequence);
            var key      = new EventSourceKey(uncommittedEvents.EventSource.EventSourceId, _artifactMap.GetArtifactFor(uncommittedEvents.EventSource.GetType()).Id);

            return(new VersionedEventSource(new EventSourceVersion(commit, sequence), key));
        }
Example #4
0
        // void FastForward(ICommandContext commandContext, T aggregateRoot)
        // {
        //     _logger.Trace($"FastForward - {typeof(T).AssemblyQualifiedName}");
        //     var identifier = _artifactTypeMap.GetArtifactFor(typeof(T));
        //     _logger.Trace($"With identifier '{identifier?.ToString()??"<unknown identifier>"}'");

        //     var version = _eventSourceVersions.GetFor(identifier, aggregateRoot.EventSourceId);
        //     aggregateRoot.FastForward(version);
        // }

        void ReApplyEvents(ICommandContext commandContext, T aggregateRoot)
        {
            var identifier      = _artifactTypeMap.GetArtifactFor(typeof(T));
            var commits         = _eventStore.Fetch(new EventSourceKey(aggregateRoot.EventSourceId, identifier.Id));
            var committedEvents = new CommittedEvents(aggregateRoot.EventSourceId, FromCommits(commits));

            if (committedEvents.HasEvents)
            {
                aggregateRoot.ReApply(committedEvents);
            }
        }
Example #5
0
        /// <inheritdoc/>
        public Contracts.UncommittedAggregateEvents ToProtobuf(UncommittedAggregateEvents uncommittedEvents)
        {
            var aggregateRoot = _artifactTypeMap.GetArtifactFor(uncommittedEvents.AggregateRoot);
            var events        = new Contracts.UncommittedAggregateEvents
            {
                AggregateRootId = aggregateRoot.Id.ToProtobuf(),
                EventSourceId   = uncommittedEvents.EventSource.ToProtobuf(),
                ExpectedAggregateRootVersion = uncommittedEvents.ExpectedAggregateRootVersion,
            };

            foreach (var @event in uncommittedEvents)
            {
                events.Events.Add(new Contracts.UncommittedAggregateEvents.Types.UncommittedAggregateEvent
                {
                    Artifact = ToProtobuf(@event.GetType()),
                    Public   = IsPublicEvent(@event),
                    Content  = _serializer.EventToJson(@event),
                });
            }

            return(events);
        }
Example #6
0
        /// <summary>
        /// Register a command handler explicitly
        /// </summary>
        /// <param name="handlerType"></param>
        /// <remarks>
        /// The registration process will look into the handler and find methods that
        /// are called Handle() and takes a command as parameter
        /// </remarks>
        public void Register(Type handlerType)
        {
            var handleMethods = handlerType
                                .GetRuntimeMethods()
                                .Where(m => m.IsPublic || !m.IsStatic)
                                .Where(m => m.Name.Equals(HandleMethodName))
                                .Where(m => m.GetParameters().Length == 1)
                                .Where(m => typeof(ICommand).GetTypeInfo().IsAssignableFrom(m.GetParameters() [0].ParameterType));

            handleMethods.ForEach(method =>
            {
                var commandType = method.GetParameters() [0].ParameterType;
                var identifier  = _artifactTypeMap.GetArtifactFor(commandType);
                _commandHandlers[identifier] = method;
            });
        }
        /// <summary>
        /// Register a command handler explicitly.
        /// </summary>
        /// <param name="handlerType"><see cref="Type"/> holding the handler.</param>
        /// <remarks>
        /// The registration process will look into the handler and find methods that
        /// are called Handle() and takes a command as parameter.
        /// </remarks>
        public void Register(Type handlerType)
        {
            _logger.Trace("Registering command handler {CommandHandler}", handlerType);
            var handleMethods = handlerType
                                .GetRuntimeMethods()
                                .Where(m => m.IsPublic || !m.IsStatic)
                                .Where(m => m.Name.Equals(HandleMethodName, StringComparison.InvariantCulture))
                                .Where(m => m.GetParameters().Length == 1)
                                .Where(m => typeof(ICommand).GetTypeInfo().IsAssignableFrom(m.GetParameters()[0].ParameterType));

            handleMethods.ForEach(method =>
            {
                var commandType = method.GetParameters()[0].ParameterType;
                var identifier  = _artifactTypeMap.GetArtifactFor(commandType);
                _logger.Trace("Registering handle method for command {CommandType} on command handler {CommandHandler}", identifier, handlerType);
                _commandHandlers[identifier] = method;
            });
        }
        /// <inheritdoc/>
        protected override EventHandlerRegistrationRequest GetRegisterArguments()
        {
            var request = new EventHandlerRegistrationRequest
            {
                EventHandlerId = Identifier.ToProtobuf(),
                ScopeId        = _scope.ToProtobuf(),
                Partitioned    = _partitioned,
            };

            foreach (var eventType in _handler.HandledEventTypes)
            {
                var artifact = _artifacts.GetArtifactFor(eventType);
                request.Types_.Add(new Artifact
                {
                    Id         = artifact.Id.ToProtobuf(),
                    Generation = artifact.Generation,
                });
            }

            return(request);
        }
        /// <summary>
        /// Injects an event
        /// </summary>
        public void InjectEvent(TenantId tenant, EventSourceId eventSourceId, IEvent @event)
        {
            _logger.Information($"Injecting event!");

            _executionContextManager.CurrentFor(tenant);
            var executionContext = _executionContextManager.Current;

            using (var eventStore = _getEventStore())
            {
                var artifact       = _artifactTypeMap.GetArtifactFor(@event.GetType());
                var eventSourceKey = new EventSourceKey(eventSourceId, artifact.Id);
                var version        = eventStore.GetNextVersionFor(eventSourceKey);

                var uncommittedEventStream = new UncommittedEventStream(
                    CommitId.New(),
                    executionContext.CorrelationId,
                    new VersionedEventSource(version, eventSourceKey),
                    DateTimeOffset.Now,
                    EventStream.From(new [] {
                    new EventEnvelope(
                        new EventMetadata(
                            EventId.New(),
                            new VersionedEventSource(version, eventSourceKey),
                            executionContext.CorrelationId,
                            artifact,
                            DateTimeOffset.Now,
                            executionContext
                            ),
                        @event.ToPropertyBag()
                        )
                })
                    );

                _logger.Information("Commit events to store");
                var committedEventStream = eventStore.Commit(uncommittedEventStream);

                _logger.Information("Process committed events");
                _processingHub.Process(committedEventStream);
            }
        }
        /// <inheritdoc/>
        public async Task <CommittedAggregateEvents> FetchForAggregate(Type aggregateRoot, EventSourceId eventSource, CancellationToken cancellationToken)
        {
            _logger.Debug("Fetching events for aggregate");
            var request = new Contracts.FetchForAggregateRequest
            {
                CallContext = GetCurrentCallContext(),
                Aggregate   = new Contracts.Aggregate
                {
                    AggregateRootId = _artifactMap.GetArtifactFor(aggregateRoot).Id.ToProtobuf(),
                    EventSourceId   = eventSource.ToProtobuf(),
                },
            };
            var response = await _eventStoreClient.FetchForAggregateAsync(request, cancellationToken : cancellationToken);

            ThrowIfFailure(response.Failure);
            try
            {
                return(_eventConverter.ToSDK(response.Events));
            }
            catch (CouldNotDeserializeEvent ex)
            {
                throw new CouldNotDeserializeEventFromScope(ScopeId.Default, ex);
            }
        }
 /// <inheritdoc/>
 public Artifact GetArtifactFor(string path) => _artifactTypeMap.GetArtifactFor(GetTypeFor(path));