/// <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)); }
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); } }
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); }