/// <summary>
        /// Request a responses from your service, this will invoke the request handler registered on your service as if it was called from another service.<br/>
        /// </summary>
        /// <param name="config">Request/Response Configuration</param>
        /// <param name="request">Request message</param>
        /// <typeparam name="TRequest">Type of Request Message</typeparam>
        /// <typeparam name="TResponse">Type of Response Message</typeparam>
        /// <returns>Response Message</returns>
        public TResponse Request <TRequest, TResponse>(RequestResponseConfig config, TRequest request)
        {
            var queue = _requestQueues.FirstOrDefault(q => q.Key == config.Name);

            var replyQueue = UniqueKeyUtility.Generate();

            if (queue.Value != null)
            {
                MockMessage(queue.Value, new RequestMessage
                {
                    MessageBody  = SerializeToJson(request),
                    RequestType  = typeof(TRequest).FullName,
                    ResponseType = typeof(TResponse).FullName,
                    Name         = config.Name,
                    ReplyQueue   = replyQueue
                }, true);

                // ReSharper disable once ImplicitlyCapturedClosure
                TimerUtility.WaitForIt(() => _responses.Any(r => r.ReplyQueue == replyQueue), Debugger.IsAttached ? 360000 : config.MillisecondsTimeout);
            }

            Thread.Sleep(100);

            var response = _responses.FirstOrDefault(r => r.ReplyQueue == replyQueue);

            return(JsonConvert.DeserializeObject <TResponse>(response?.MessageBody));
        }
Example #2
0
        public void CanCreateConfig()
        {
            var cut = new RequestResponseConfig
            {
                Name = "MyRequest",
                MillisecondsTimeout = 1000
            };

            cut.Name.Should().Be("MyRequest");
            cut.MillisecondsTimeout.Should().Be(1000);
        }
        /// <summary>
        /// Mock a response from a request handler in another service, use this for handling any request that user services need to be tested. This is a default Responses in all cases. Add this last if you have multiple mocks for same request.
        /// </summary>
        /// <param name="config">Request/Response Configuration</param>
        /// <param name="response">Response Message</param>
        /// <typeparam name="TResponse">Type of Response Message</typeparam>
        public void MockResponse <TResponse>(RequestResponseConfig config, TResponse response)
        {
            if (!_requestMocks.ContainsKey(config.Name))
            {
                _requestMocks.Add(config.Name, new List <RequestMock>());
            }

            _requestMocks[config.Name].Add(new RequestMock {
                Function = a => true, Response = response, ResponseType = typeof(TResponse)
            });
        }
        /// <inheritdoc />
        public void RequestHandler <TRequest, TResponse>(RequestResponseConfig config, Func <TRequest, TResponse> handler, bool multiThreaded)
        {
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            var requestHandler = CreateRequestHandler(config).Set(typeof(TRequest), typeof(TResponse), multiThreaded, m => handler((TRequest)m));

            if (_cancellationTokenSource != null)
            {
                StartRequestHandler(requestHandler);
            }
        }
Example #5
0
        private void Request <TReq, TRes>(RequestResponseConfig config, TReq request)
        {
            Console.WriteLine();
            Console.WriteLine($"Request/Response - Name: {config.Name}");
            Console.WriteLine("Request: " + request.SerializeToJson());

            try
            {
                var response = _messageBus.Request <TReq, TRes>(config, request);
                Console.WriteLine("Response: " + response.SerializeToJson());
            }
            catch (Exception exception)
            {
                Console.WriteLine("Exception requesting: " + exception.SerializeToJson());
            }
        }
        /// <inheritdoc />
        public async Task <TResponse> RequestAsync <TRequest, TResponse>(RequestResponseConfig config, TRequest request)
        {
            if (_cancellationTokenSource == null)
            {
                throw new ArgumentException("Cannot Request before Start");
            }

            ValidateRequestResponseConfig(config);

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return(await _messageBroker.RequestResponseAsync <TRequest, TResponse>(config.Name, request, config.MillisecondsTimeout, _cancellationTokenSource.Token));
        }
        /// <inheritdoc />
        public TResponse Request <TRequest, TResponse>(RequestResponseConfig config, TRequest request)
        {
            try
            {
                return(RequestAsync <TRequest, TResponse>(config, request).Result);
            }
            catch (AggregateException exception)
            {
                if (exception.InnerException != null)
                {
                    throw exception.InnerException;
                }

                throw;
            }
        }
        private static void ValidateRequestResponseConfig(RequestResponseConfig config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            if (config.MillisecondsTimeout <= 0)
            {
                throw new ArgumentException("Request timeout must be larger than zero", nameof(config.MillisecondsTimeout));
            }

            if (config.Name.NullOrWhiteSpace())
            {
                throw new ArgumentException("Request name is invalid", nameof(config.Name));
            }
        }
        private RequestHandler CreateRequestHandler(RequestResponseConfig config)
        {
            ValidateRequestResponseConfig(config);

            var requestHandler = new RequestHandler(_logger, _messageBroker, _queueHandlerFactory, config.Name, _queueNameUtility);

            lock (_requestHandlers)
            {
                if (_requestHandlers.Any(h => h.Name == config.Name))
                {
                    throw new DoubleRequestHandlerException(config);
                }

                _requestHandlers.Add(requestHandler);
            }

            return(requestHandler);
        }
 /// <inheritdoc />
 public void RequestHandler <TRequest, TResponse>(RequestResponseConfig config, Func <TRequest, TResponse> handler)
 {
     RequestHandler(config, handler, false);
 }
 /// <inheritdoc />
 /// <summary>
 /// You can not register two request handlers with same name
 /// </summary>
 /// <param name="config">Request/Response Configuration</param>
 /// <exception cref="T:System.NotImplementedException"></exception>
 public DoubleRequestHandlerException(RequestResponseConfig config) : base("Double Request Handler Exception")
 {
     Data.Add(nameof(config), config?.TrySerializeToJson());
 }
        /// <summary>
        /// Register Request Handler
        /// </summary>
        /// <param name="messageBus">The Message Bus</param>
        /// <param name="config">Request/Response Configuration</param>
        /// <param name="handler">Request handler</param>
        /// <param name="multiThreaded">Can request handler, handle multi threaded messages, multiple messages in parallel</param>
        /// <typeparam name="TRequest">Type of Request Message</typeparam>
        /// <typeparam name="TResponse">Type of Response massage</typeparam>
        /// <returns>The Message Bus</returns>
        public static IMessageBus AddRequestHandler <TRequest, TResponse>(this IMessageBus messageBus, RequestResponseConfig config, Func <TRequest, TResponse> handler, bool multiThreaded)
        {
            messageBus.RequestHandler(config, handler, multiThreaded);

            return(messageBus);
        }
        /// <summary>
        /// Register Request Handler
        /// </summary>
        /// <param name="messageBus">The Message Bus</param>
        /// <param name="config">Request/Response Configuration</param>
        /// <param name="handler">Request handler</param>
        /// <typeparam name="TRequest">Type of Request Message</typeparam>
        /// <typeparam name="TResponse">Type of Response massage</typeparam>
        /// <returns>The Message Bus</returns>
        public static IMessageBus AddRequestHandler <TRequest, TResponse>(this IMessageBus messageBus, RequestResponseConfig config, Func <TRequest, CancellationToken, TResponse> handler)
        {
            messageBus.RequestHandler(config, handler);

            return(messageBus);
        }