Пример #1
0
        /// <inheritdoc />
        public async Task SendAsync <TCommand, TAggregate>(TCommand command)
            where TCommand : IDomainCommand
            where TAggregate : IAggregateRoot
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var handler = _handlerResolver.ResolveHandler <IDomainCommandHandlerAsync <TCommand> >();

            var aggregateTask = _aggregateStore.SaveAggregateAsync <TAggregate>(command.AggregateRootId);
            var commandTask   = _commandStore.SaveCommandAsync <TAggregate>(command);
            var eventsTask    = handler.HandleAsync(command);

            await Task.WhenAll(aggregateTask, commandTask, eventsTask);

            var publishEvents = PublishEvents(command);
            var events        = await eventsTask;

            foreach (var @event in events)
            {
                @event.Update(command);
                var concreteEvent = _eventFactory.CreateConcreteEvent(@event);

                await _eventStore.SaveEventAsync <TAggregate>((IDomainEvent)concreteEvent, command.ExpectedVersion);

                if (publishEvents)
                {
                    await _eventPublisher.PublishAsync(concreteEvent);
                }
            }
        }
        public async Task <CommandResponse> SendAsync(ICommand command)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            _userContext = command.UserContext;

            var handler      = _handlerResolver.ResolveHandler(command, typeof(ICommandHandlerAsync <>));
            var handleMethod = handler.GetType().GetMethod("HandleAsync", new[] { command.GetType() });
            var response     = await(Task <CommandResponseWithEvents>) handleMethod.Invoke(handler, new object[] { command });

            if (response == null)
            {
                return(null);
            }

            if (response.Events == null)
            {
                return(new CommandResponse(response.ValidationResult, response.ValidationResult));
            }

            await _eventProcessor.Process(response.Events, command);

            return(new CommandResponse(response.ValidationResult, response.ValidationResult));
        }
Пример #3
0
        public IHaveFulfilledSubscriptionRequirements WithMessageHandler <T>(IHandlerResolver handlerResolver) where T : Message
        {
            var thing = _subscriptionConfig.SubscriptionType == SubscriptionType.PointToPoint
                ? PointToPointHandler <T>()
                : TopicHandler <T>();

            Bus.SerialisationRegister.AddSerialiser <T>(_serialisationFactory.GetSerialiser <T>());

            var resolutionContext = new HandlerResolutionContext(_subscriptionConfig.QueueName);
            var proposedHandler   = handlerResolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException($"There is no handler for '{typeof(T).Name}' messages.");
            }

            foreach (var region in Bus.Config.Regions)
            {
                Bus.AddMessageHandler(region, _subscriptionConfig.QueueName, () => handlerResolver.ResolveHandler <T>(resolutionContext));
            }

            _log.LogInformation($"Added a message handler - Topic: {_subscriptionConfig.Topic}, QueueName: {_subscriptionConfig.QueueName}, HandlerName: IHandler<{typeof(T)}>");

            return(thing);
        }
Пример #4
0
        public IHaveFulfilledSubscriptionRequirements WithMessageHandler <T>(IHandlerResolver handlerResolver) where T : Message
        {
            if (handlerResolver is null)
            {
                throw new ArgumentNullException(nameof(handlerResolver));
            }

            _subscriptionConfig.TopicName = GetOrUseTopicNamingConvention <T>(_subscriptionConfig.TopicName);
            _subscriptionConfig.QueueName = GetOrUseQueueNamingConvention <T>(_subscriptionConfig.QueueName);
            _subscriptionConfig.SubscriptionGroupName ??= _subscriptionConfig.QueueName;

            var thing = _subscriptionConfig.SubscriptionType == SubscriptionType.PointToPoint
                ? PointToPointHandler <T>()
                : TopicHandler <T>();

            var resolutionContext = new HandlerResolutionContext(_subscriptionConfig.QueueName);
            var proposedHandler   = handlerResolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException($"There is no handler for '{typeof(T)}' messages.");
            }

            Bus.AddMessageHandler(_subscriptionConfig.QueueName, () => handlerResolver.ResolveHandler <T>(resolutionContext));

            _log.LogInformation(
                "Added a message handler for message type for '{MessageType}' on topic '{TopicName}' and queue '{QueueName}'.",
                typeof(T),
                _subscriptionConfig.TopicName,
                _subscriptionConfig.QueueName);

            return(thing);
        }
Пример #5
0
        public IHaveFulfilledSubscriptionRequirements WithMessageHandler <T>(IHandlerResolver handlerResolver) where T : Message
        {
            if (_serializationFactory == null)
            {
                throw new InvalidOperationException($"No {nameof(IMessageSerializationFactory)} has been configured.");
            }

            var thing = _subscriptionConfig.SubscriptionType == SubscriptionType.PointToPoint
                ? PointToPointHandler <T>()
                : TopicHandler <T>();

            Bus.SerializationRegister.AddSerializer <T>(_serializationFactory.GetSerializer <T>());

            var resolutionContext = new HandlerResolutionContext(_subscriptionConfig.QueueName);
            var proposedHandler   = handlerResolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException($"There is no handler for '{typeof(T)}' messages.");
            }

            foreach (var region in Bus.Config.Regions)
            {
                Bus.AddMessageHandler(region, _subscriptionConfig.QueueName, () => handlerResolver.ResolveHandler <T>(resolutionContext));
            }

            _log.LogInformation(
                "Added a message handler for message type for '{MessageType}' on topic '{TopicName}' and queue '{QueueName}'.",
                typeof(T),
                _subscriptionConfig.Topic,
                _subscriptionConfig.QueueName);

            return(thing);
        }
Пример #6
0
        public async Task <ValidationResponse> ValidateAsync(ICommand command)
        {
            var validator        = _handlerResolver.ResolveHandler(command, typeof(IValidator <>));
            var validateMethod   = validator.GetType().GetMethod("ValidateAsync", new [] { command.GetType(), typeof(CancellationToken) });
            var validationResult = await(Task <ValidationResult>) validateMethod.Invoke(validator, new object[] { command, default(CancellationToken) });

            return(BuildValidationResponse(validationResult));
        }
Пример #7
0
        public async Task <ValidationResponse> ValidateAsync <TCommand>(TCommand command)
            where TCommand : ICommand
        {
            var validator        = _handlerResolver.ResolveHandler <IValidator <TCommand> >();
            var validationResult = await validator.ValidateAsync(command);

            return(BuildValidationResponse(validationResult));
        }
Пример #8
0
        public void TestQueueAResolution()
        {
            var context = new HandlerResolutionContext("QueueA");
            var handler = _handlerResolver.ResolveHandler <TestMessage>(context);

            Assert.That(handler, Is.Not.Null);
            Assert.That(handler, Is.InstanceOf <HandlerA>());
        }
Пример #9
0
        public void TestQueueAResolution()
        {
            var context = new HandlerResolutionContext("QueueA");
            var handler = _handlerResolver.ResolveHandler <TestMessage>(context);

            handler.ShouldNotBeNull();
            handler.ShouldBeAssignableTo <HandlerA>();
        }
Пример #10
0
        /// <inheritdoc />
        void ISubscriptionBuilder <T> .Configure(
            JustSayingBus bus,
            IHandlerResolver resolver,
            IVerifyAmazonQueues creator,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <TopicSubscriptionBuilder <T> >();

            var subscriptionConfig = new SqsReadConfiguration(SubscriptionType.ToTopic)
            {
                QueueName = TopicName
            };

            ConfigureReads?.Invoke(subscriptionConfig);

            var config = bus.Config;

            subscriptionConfig.ApplyTopicNamingConvention <T>(config.TopicNamingConvention);
            subscriptionConfig.ApplyQueueNamingConvention <T>(config.QueueNamingConvention);
            subscriptionConfig.SubscriptionGroupName ??= subscriptionConfig.QueueName;
            subscriptionConfig.PublishEndpoint = subscriptionConfig.TopicName;
            subscriptionConfig.Validate();

            var queueWithStartup = creator.EnsureTopicExistsWithQueueSubscribed(
                config.Region,
                bus.SerializationRegister,
                subscriptionConfig,
                config.MessageSubjectProvider);

            bus.AddStartupTask(queueWithStartup.StartupTask);

            bus.AddQueue(subscriptionConfig.SubscriptionGroupName, queueWithStartup.Queue);

            logger.LogInformation(
                "Created SQS topic subscription on topic '{TopicName}' and queue '{QueueName}'.",
                subscriptionConfig.TopicName,
                subscriptionConfig.QueueName);

            var resolutionContext = new HandlerResolutionContext(subscriptionConfig.QueueName);
            var proposedHandler   = resolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException(
                          $"There is no handler for '{typeof(T)}' messages.");
            }

            bus.AddMessageHandler(subscriptionConfig.QueueName,
                                  () => resolver.ResolveHandler <T>(resolutionContext));

            logger.LogInformation(
                "Added a message handler for message type for '{MessageType}' on topic '{TopicName}' and queue '{QueueName}'.",
                typeof(T),
                subscriptionConfig.TopicName,
                subscriptionConfig.QueueName);
        }
Пример #11
0
        /// <inheritdoc />
        public Task SendAsync <TCommand>(TCommand command) where TCommand : ICommand
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var handler = _handlerResolver.ResolveHandler <ICommandHandlerAsync <TCommand> >();

            return(handler.HandleAsync(command));
        }
Пример #12
0
        /// <summary>
        /// Sends the specified command.
        /// The command handler must implement OpenCqrs.Commands.ICommandHandler.
        /// </summary>
        /// <typeparam name="TCommand">The type of the command.</typeparam>
        /// <param name="command">The command.</param>
        /// <inheritdoc />
        public void Send <TCommand>(TCommand command) where TCommand : ICommand
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var handler = _handlerResolver.ResolveHandler <ICommandHandler <TCommand> >();

            handler.Handle(command);
        }
Пример #13
0
        public Task <TResult> ProcessAsync <TQuery, TResult>(TQuery query) where TQuery : IQuery
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            var handler = _handlerResolver.ResolveHandler <IQueryHandlerAsync <TQuery, TResult> >();

            return(handler.RetrieveAsync(query));
        }
        /// <inheritdoc />
        void ISubscriptionBuilder <T> .Configure(
            JustSayingBus bus,
            IHandlerResolver resolver,
            IVerifyAmazonQueues creator,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <QueueSubscriptionBuilder <T> >();

            var subscriptionConfig = new SqsReadConfiguration(SubscriptionType.PointToPoint)
            {
                QueueName = QueueName
            };

            ConfigureReads?.Invoke(subscriptionConfig);

            var config = bus.Config;

            subscriptionConfig.ApplyTopicNamingConvention <T>(config.TopicNamingConvention);
            subscriptionConfig.ApplyQueueNamingConvention <T>(config.QueueNamingConvention);
            subscriptionConfig.SubscriptionGroupName ??= subscriptionConfig.QueueName;
            subscriptionConfig.Validate();

            var queue = creator.EnsureQueueExists(config.Region, subscriptionConfig);

            bus.AddStartupTask(
                queue.Queue.EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdatedAsync(subscriptionConfig));

            bus.AddQueue(subscriptionConfig.SubscriptionGroupName, queue.Queue);

            logger.LogInformation(
                "Created SQS subscriber for message type '{MessageType}' on queue '{QueueName}'.",
                typeof(T),
                subscriptionConfig.QueueName);

            var resolutionContext = new HandlerResolutionContext(subscriptionConfig.QueueName);
            var proposedHandler   = resolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException(
                          $"There is no handler for '{typeof(T)}' messages.");
            }

            bus.AddMessageHandler(subscriptionConfig.QueueName,
                                  () => resolver.ResolveHandler <T>(resolutionContext));

            logger.LogInformation(
                "Added a message handler for message type for '{MessageType}' on topic '{TopicName}' and queue '{QueueName}'.",
                typeof(T),
                subscriptionConfig.TopicName,
                subscriptionConfig.QueueName);
        }
Пример #15
0
        public async Task ProcessMessageAsync(BasicDeliverEventArgs ea)
        {
            _Logger.LogInformation("ProcessMessageAsync. body", ea.Body);
            var          body       = ea.Body;
            QueueMessage message    = null;
            var          messageStr = string.Empty;

            try
            {
                messageStr = Encoding.UTF8.GetString(body);
                message    = JsonConvert.DeserializeObject <QueueMessage>(messageStr);
                var handler = _HandlerResolver.ResolveHandler(message);
                if (handler is null)
                {
                    var errorMessage = $"Handler for {Enum.GetName(typeof(SystemEventType), message.EventType)} is not defined";
                    _Logger.LogError(errorMessage, ea.Body);
                    throw new NotSupportedException(errorMessage);
                }

                await handler.HandleMessage(message);
            }
            catch (Exception e)
            {
                if (message != null && ++message.ReceiveCount < MaxReceiveCount)
                {
                    _MessageProducer.Send(message);
                    _Logger.LogError(e, "ProcessMessageAsync. Message processing failed. Body: {0}", messageStr);
                }
                else
                {
                    _MessageProducer.Send(SystemEventType.DeadEnd, body, JsonConvert.SerializeObject(e));
                    _Logger.LogError(e, "ProcessMessageAsync. Message not processed at all. body: {0}", messageStr);
                }
            }
        }
Пример #16
0
        /// <inheritdoc />
        public async Task SendAsync<TCommand>(TCommand command) where TCommand : ICommand
        {
            if (command == null)
                throw new ArgumentNullException(nameof(command));

            var handler = _handlerResolver.ResolveHandler<ICommandHandlerAsync<TCommand>>();

            var events = await handler.HandleAsync(command);

            if (PublishEvents(command))
            {
                foreach (var @event in events)
                {
                    var concreteEvent = _eventFactory.CreateConcreteEvent(@event);
                    await _eventPublisher.PublishAsync(concreteEvent);
                }
            }
        }
Пример #17
0
        public object ResolveHandler(object query, Type type)
        {
            var queryType      = query.GetType();
            var queryInterface = queryType.GetInterfaces()[0];
            var resultType     = queryInterface.GetGenericArguments().FirstOrDefault();
            var handlerType    = type.MakeGenericType(queryType, resultType);

            return(_handlerResolver.ResolveHandler(handlerType));
        }
        /// <inheritdoc />
        void ISubscriptionBuilder <T> .Configure(
            JustSayingBus bus,
            IHandlerResolver handlerResolver,
            IServiceResolver serviceResolver,
            IVerifyAmazonQueues creator,
            IAwsClientFactoryProxy awsClientFactoryProxy,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <QueueSubscriptionBuilder <T> >();

            var attachedQueueConfig = new QueueAddressConfiguration();

            ConfigureReads?.Invoke(attachedQueueConfig);

            IAmazonSQS sqsClient = awsClientFactoryProxy
                                   .GetAwsClientFactory()
                                   .GetSqsClient(RegionEndpoint.GetBySystemName(_queueAddress.RegionName));

            var queue = new QueueAddressQueue(_queueAddress, sqsClient);

            attachedQueueConfig.SubscriptionGroupName ??= queue.QueueName;
            attachedQueueConfig.Validate();

            bus.AddQueue(attachedQueueConfig.SubscriptionGroupName, queue);

            logger.LogInformation(
                "Created SQS queue subscription for '{MessageType}' on '{QueueName}'",
                typeof(T), queue.QueueName);

            var resolutionContext = new HandlerResolutionContext(queue.QueueName);
            var proposedHandler   = handlerResolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException(
                          $"There is no handler for '{typeof(T)}' messages.");
            }

            var middlewareBuilder = new HandlerMiddlewareBuilder(handlerResolver, serviceResolver);
            var handlerMiddleware = middlewareBuilder
                                    .Configure(MiddlewareConfiguration ?? (b => b.UseDefaults <T>(proposedHandler.GetType())))
                                    .Build();

            bus.AddMessageMiddleware <T>(queue.QueueName, handlerMiddleware);

            logger.LogInformation(
                "Added a message handler for message type for '{MessageType}' on queue '{QueueName}'",
                typeof(T), queue.QueueName);
        }
Пример #19
0
        public async Task PublishAsync <TEvent>(TEvent @event) where TEvent : IEvent
        {
            if (@event == null)
            {
                throw new ArgumentNullException(nameof(@event));
            }

            _userContext = @event.UserContext;

            //TODO there is a probability to have multiple handlers
            var handler = _handlerResolver.ResolveHandler(@event, typeof(IEventHandlerAsync <>));

            //TODO inmemory handler is not triggering
            if (handler != null)
            {
                await handler.AsDynamic().HandleAsync(@event);
            }

            if (@event is IBusTopicMessage message)
            {
                await _busMessageDispatcher.DispatchAsync(message);
            }
        }
Пример #20
0
        private async Task <bool> ProcessEvent(string eventName, string message)
        {
            var processed = false;

            if (_subscriptionManager.HasSubscriptionsForEvent(eventName))
            {
                var subscriptions = _subscriptionManager.GetSubscriptionsForEvent(eventName);
                foreach (var subscription in subscriptions)
                {
                    var handler = _handlerResolver?.ResolveHandler(subscription.HandlerType);
                    if (handler == null)
                    {
                        continue;
                    }

                    var integrationEvent = JsonConvert.DeserializeObject(message, subscription.EventType);
                    var concreteType     = typeof(IEventHandler <>).MakeGenericType(subscription.EventType);
                    await(Task) concreteType.GetMethod("HandleAsync").Invoke(handler, new object[] { integrationEvent });
                    processed = true;
                }
            }

            return(processed);
        }
Пример #21
0
 private Task<CommandResponse> GetCommandResponseAsync<TCommand>(TCommand command)
     where TCommand : ICommand
 {
     var handler = _handlerResolver.ResolveHandler<ICommandHandlerAsync<TCommand>>();
     return handler.HandleAsync(command);
 }
Пример #22
0
 protected static THandler GetHandler <THandler>(IHandlerResolver handlerResolver)
 {
     return(handlerResolver.ResolveHandler <THandler>());
 }