/// <inheritdoc/>
        public Task BeforeHandleAsync(MessageHandlingContext context)
        {
            if (MessageType.GQL_CONNECTION_INIT.Equals(context.Message?.Type))
            {
                var payload = context.Message?.Payload;
                if (payload != null)
                {
                    var authorizationTokenObject = ((JObject)payload)["Authorization"];

                    if (authorizationTokenObject != null)
                    {
                        var token            = authorizationTokenObject.ToString().Replace("Bearer ", string.Empty);
                        var jwtSecurityToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
                        this.httpContextAccessor.HttpContext.User =
                            new ClaimsPrincipal(new ClaimsIdentity(jwtSecurityToken.Claims));
                    }
                }
            }

            var user = this.httpContextAccessor.HttpContext.User;

            context.Properties["GraphQLUserContext"] = new GraphQLUserContext()
            {
                User = user
            };

            return(Task.CompletedTask);
        }
예제 #2
0
        public async Task ShouldProperlyExecuteFailurePipelineWhenMessageHandlingServiceThrowsException()
        {
            var argsMock  = new Mock <BasicDeliverEventArgs>();
            var exception = new Exception();
            var messageHandlingServiceMock = new Mock <IMessageHandlingService>();

            messageHandlingServiceMock.Setup(x => x.HandleMessageReceivingEvent(It.IsAny <MessageHandlingContext>()))
            .ThrowsAsync(exception);
            var errorProcessingServiceMock = new Mock <IErrorProcessingService>();

            var middlewareOrderingMap = new Dictionary <int, int>();
            var firstMiddleware       = new StubMessageHandlingMiddleware(1, new Dictionary <int, int>(), middlewareOrderingMap);
            var secondMiddleware      = new StubMessageHandlingMiddleware(2, new Dictionary <int, int>(), middlewareOrderingMap);
            var thirdMiddleware       = new StubMessageHandlingMiddleware(3, new Dictionary <int, int>(), middlewareOrderingMap);
            var middlewares           = new List <IMessageHandlingMiddleware>
            {
                firstMiddleware,
                secondMiddleware,
                thirdMiddleware
            };

            var service = CreateService(
                messageHandlingServiceMock.Object,
                errorProcessingServiceMock.Object,
                middlewares);
            var context = new MessageHandlingContext(argsMock.Object, AckAction, false);
            await service.Execute(context);

            errorProcessingServiceMock.Verify(x => x.HandleMessageProcessingFailure(It.IsAny <MessageHandlingContext>(), exception), Times.Once);
            Assert.Equal(1, middlewareOrderingMap[thirdMiddleware.Number]);
            Assert.Equal(2, middlewareOrderingMap[secondMiddleware.Number]);
            Assert.Equal(3, middlewareOrderingMap[firstMiddleware.Number]);
        }
예제 #3
0
        public async Task when_executed_with_message_type_within_context_it_should_find_handlers_for_this_message_and_store_them_in_context()
        {
            var container = new Container();

            container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
            container.AddLogging(_testOutput);

            var handlersRegistry = new VentureServiceHandlersRegistry(new[] { typeof(Message01Handler).Assembly });
            var handlers         = handlersRegistry.HandlersGroupedByMessageType[typeof(Message01)];

            foreach (var handler in handlers)
            {
                container.Register(handler);
            }

            var sut     = new FindMessageHandlersStep(new SimpleInjectorAdapter(container));
            var context = new MessageHandlingContext
            {
                MessageType = typeof(Message01),
                Api         = new FakeIngressApi {
                    HandlerRegistry = handlersRegistry
                }
            };

            await sut.Execute(context);

            var foundHandlers = (IEnumerable <HandlerDescriptor>)context.Handlers;
            var singleHandler = foundHandlers.Single();

            singleHandler.Should().BeOfType <HandlerDescriptor>("should find the handler for the message");
        }
    public async Task Failed_Subscribe_writes_error()
    {
        /* Given */
        string id      = "1";
        var    payload = new GraphQLRequest();
        var    context = new MessageHandlingContext(_server, null);

        _executer.ExecuteAsync(null).ReturnsForAnyArgs(
            new ExecutionResult
        {
            Errors = new ExecutionErrors
            {
                new ExecutionError("error")
            }
        });

        /* When */
        await _sut.SubscribeOrExecuteAsync(id, payload, context);

        /* Then */
        await _writer.Received().SendAsync(
            Arg.Is <OperationMessage>(
                message => message.Id == id &&
                message.Type == MessageType.GQL_ERROR));
    }
        private static MessageHandlingContext CreateContext()
        {
            var typesRegistry = new IngressApiMessageTypesRegistry1();

            typesRegistry.Initialize();

            var context = new MessageHandlingContext
            {
                Payload       = new byte[1],
                QueueName     = "queue name",
                ReceivedOnUtc = DateTimeOffset.UtcNow,
                Metadata      = new Dictionary <string, string>
                {
                    { VentureApi.Headers.MessageId, "VentureApi.Headers.MessageId" },
                    { VentureApi.Headers.CorrelationId, "VentureApi.Headers.CorrelationId" },
                    { VentureApi.Headers.CausationId, "VentureApi.Headers.CausationId" },
                    { VentureApi.Headers.MessageTypeName, nameof(Message1) }
                },
                Api = new FakeIngressApi {
                    MessageTypesRegistry = typesRegistry, HandlerRegistry = new HandlerRegistry()
                }
            };

            return(context);
        }
예제 #6
0
        public async Task BeforeHandleAsync(MessageHandlingContext context)
        {
            var httpContext = _httpContextAccessor.HttpContext;

            if (httpContext != null)
            {
                if (httpContext.WebSockets.IsWebSocketRequest && (!httpContext.User.Identity.IsAuthenticated))
                {
                    await _webSocketPreHandler.PrepareContext(httpContext);
                }

                var userContext = new GraphQLUserContext
                {
                    User = httpContext.User
                };
                // if the default auth scheme is cookies
                // users from remote clients that pass bearer token are not automatically authenticated
                if (!httpContext.User.Identity.IsAuthenticated)
                {
                    var result = await httpContext.AuthenticateAsync("Bearer");

                    if (result.Succeeded)
                    {
                        userContext.User = result.Principal;
                    }
                }
                context.Properties.TryAdd("UserContext", userContext);
            }
        }
예제 #7
0
 private async Task OnAfterHandleAsync(MessageHandlingContext context)
 {
     foreach (var listener in _messageListeners)
     {
         await listener.AfterHandleAsync(context).ConfigureAwait(false);
     }
 }
예제 #8
0
        public async Task Handle(MessageHandlingContext context, Func <Task> next)
        {
            var order = _orderingMap.Values.Max();

            _orderingMap[Number] = order + 1;
            await next();
        }
        public void when_executed_with_context_with_wrong_message_type_within_broker_message_metadata_it_should_fail()
        {
            var registry = new CaseOfficeIngressApiMessageTypesRegistry();

            registry.Initialize();
            var context = new MessageHandlingContext {
                Api = new FakeIngressApi {
                    MessageTypesRegistry = registry
                }
            };
            var step = new ExtractMessageTypeStep();

            // ReSharper disable once JoinDeclarationAndInitializer - it's a way to test.
            Func <Task> sut;

            context.Metadata = new Dictionary <string, string> {
                { VentureApi.Headers.MessageTypeName, null }
            };
            sut = () => step.Execute(context);
            sut.Should().Throw <PoezdOperationException>("null is a wrong message type value");

            context.Metadata = new Dictionary <string, string> {
                { VentureApi.Headers.MessageTypeName, string.Empty }
            };
            sut = () => step.Execute(context);
            sut.Should().Throw <PoezdOperationException>("an empty string is a wrong message type value");

            context.Metadata = new Dictionary <string, string> {
                { VentureApi.Headers.MessageTypeName, WhitespaceString }
            };
            sut = () => step.Execute(context);
            sut.Should().Throw <PoezdOperationException>("a whitespace string is a wrong message type value");
        }
예제 #10
0
        public async Task HandleError(MessageHandlingContext context, Exception exception, Func <Task> next)
        {
            var order = _errorOrderingMap.Values.Max();

            _errorOrderingMap[Number] = order + 1;
            await next();
        }
    public async Task Failed_Subscribe_with_null_stream()
    {
        /* Given */
        string id      = "1";
        var    payload = new GraphQLRequest();
        var    context = new MessageHandlingContext(_server, null);

        _executer.ExecuteAsync(null).ReturnsForAnyArgs(
            new ExecutionResult
        {
            Streams = new Dictionary <string, IObservable <ExecutionResult> >
            {
                { "1", null }
            }
        });

        /* When */
        await _sut.SubscribeOrExecuteAsync(id, payload, context);

        /* Then */
        await _writer.Received().SendAsync(
            Arg.Is <OperationMessage>(
                message => message.Id == id &&
                message.Type == MessageType.GQL_ERROR));
    }
        public async Task BeforeHandleAsync(MessageHandlingContext context)
        {
            if (context.Terminated)
            {
                return;
            }

            var message = context.Message;

            if (message.Type == MessageType.GQL_CONNECTION_INIT)
            {
                JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();

                string token = ((string)((dynamic)message.Payload)
                                ?.Authorization)
                               ?.Replace("Bearer ", "");

                if (token == null)
                {
                    return;
                }

                var user = _jwtValidator.ValidateJwt(token);

                _contextAccessor.HttpContext.User = user;
            }
        }
예제 #13
0
 private void RunMessageHandler(IMessageHandler handler, MessageHandlingContext context, string matchingRoute)
 {
     ValidateMessageHandler(handler);
     _loggingService.LogDebug($"Starting processing the message by message handler {handler.GetType().Name}");
     handler.Handle(context, matchingRoute);
     _loggingService.LogDebug($"The message has been processed by message handler {handler.GetType().Name}");
 }
예제 #14
0
        private async Task RunAsyncMessageHandler(IAsyncMessageHandler handler, MessageHandlingContext context, string matchingRoute)
        {
            ValidateMessageHandler(handler);
            _loggingService.LogDebug($"Starting processing the message by async message handler {handler.GetType().Name}");
            await handler.Handle(context, matchingRoute);

            _loggingService.LogDebug($"The message has been processed by async message handler {handler.GetType().Name}");
        }
        public async Task when_executed_with_context_containing_no_message_metadata_it_should_skip()
        {
            var sut     = new ExtractRelationMetadataStep();
            var context = new MessageHandlingContext();
            await sut.Execute(context);

            context.CorrelationId.Should().BeNull("this header not present");
        }
예제 #16
0
        /// <inheritdoc />
        public virtual async Task HandleMessageProcessingFailure(MessageHandlingContext context, Exception exception)
        {
            var eventArgs = context.Message;

            context.AckAction?.Invoke(eventArgs);

            _loggingService.LogError(exception, $"An error occurred while processing received message with the delivery tag {eventArgs.DeliveryTag}.");
            await HandleFailedMessageProcessing(eventArgs).ConfigureAwait(false);
        }
        public async Task when_executed_with_context_containing_message_metadata_with_missing_causation_id_it_should_skip()
        {
            var sut     = new ExtractRelationMetadataStep();
            var context = new MessageHandlingContext {
                Metadata = new Dictionary <string, string>()
            };
            await sut.Execute(context);

            context.CausationId.Should().BeNull("this header not present");
        }
예제 #18
0
        private async Task ProcessMessageEvent(MessageHandlingContext context, IEnumerable <string> matchingRoutes)
        {
            var container = _messageHandlerContainers.FirstOrDefault(x => x.Exchange == context.Message.Exchange) ??
                            _messageHandlerContainers.FirstOrDefault(x => x.IsGeneral);

            if (container is null)
            {
                return;
            }

            var messageHandlerOrderingContainers = new List <MessageHandlerOrderingContainer>();

            foreach (var matchingRoute in matchingRoutes)
            {
                if (!container.MessageHandlers.ContainsKey(matchingRoute))
                {
                    continue;
                }

                var orderingContainers = container.MessageHandlers[matchingRoute]
                                         .Select(handler => new MessageHandlerOrderingContainer(handler, matchingRoute, container.GetOrderForHandler(handler)));
                messageHandlerOrderingContainers.AddRange(orderingContainers);
            }

            var executedHandlers  = new List <Type>();
            var orderedContainers = messageHandlerOrderingContainers.OrderByDescending(x => x.Order)
                                    .ThenByDescending(x => x.MessageHandler.GetHashCode())
                                    .ToList();

            foreach (var orderedContainer in orderedContainers)
            {
                var handlerType = orderedContainer.MessageHandler.GetType();
                if (executedHandlers.Contains(handlerType))
                {
                    continue;
                }

                switch (orderedContainer.MessageHandler)
                {
                case IMessageHandler messageHandler:
                    RunMessageHandler(messageHandler, context, orderedContainer.MatchingRoute);
                    break;

                case IAsyncMessageHandler asyncMessageHandler:
                    await RunAsyncMessageHandler(asyncMessageHandler, context, orderedContainer.MatchingRoute).ConfigureAwait(false);

                    break;

                default:
                    throw new NotSupportedException($"The type {orderedContainer.MessageHandler.GetType()} of message handler is not supported.");
                }

                executedHandlers.Add(handlerType);
            }
        }
예제 #19
0
 /// <inheritdoc/>
 public async Task Execute(MessageHandlingContext context)
 {
     try
     {
         await ExecutePipeline(context).ConfigureAwait(false);
     }
     catch (Exception exception)
     {
         await ExecuteFailurePipeline(context, exception).ConfigureAwait(false);
     }
 }
예제 #20
0
        /// <inheritdoc />
        public async Task HandleMessageReceivingEvent(MessageHandlingContext context)
        {
            var eventArgs = context.Message;

            _loggingService.LogInformation($"A new message received with deliveryTag {eventArgs.DeliveryTag}.");
            var matchingRoutes = GetMatchingRoutePatterns(eventArgs.Exchange, eventArgs.RoutingKey);

            await ProcessMessageEvent(eventArgs, matchingRoutes).ConfigureAwait(false);

            context.AckAction?.Invoke(eventArgs);
            _loggingService.LogInformation($"Message processing finished successfully. Acknowledge has been sent with deliveryTag {eventArgs.DeliveryTag}.");
        }
        public async Task when_executed_with_context_containing_causation_id_within_broker_message_metadata_it_should_store_it_in_context()
        {
            var          sut                 = new ExtractRelationMetadataStep();
            var          context             = new MessageHandlingContext();
            const string expectedCausationId = "expected";

            context.Metadata = new Dictionary <string, string> {
                { VentureApi.Headers.CausationId, expectedCausationId }
            };
            await sut.Execute(context);

            context.CausationId.Should().Be(expectedCausationId, "this header should be copied");
        }
    public async Task Subscribe_adds()
    {
        /* Given */
        string id      = "1";
        var    payload = new GraphQLRequest();
        var    context = new MessageHandlingContext(_server, null);

        /* When */
        await _sut.SubscribeOrExecuteAsync(id, payload, context);

        /* Then */
        Assert.Single(_sut, sub => sub.Id == id);
    }
예제 #23
0
        /// <inheritdoc/>
        public async Task Execute(BasicDeliverEventArgs eventArgs, Action <BasicDeliverEventArgs>?ackAction)
        {
            var context = new MessageHandlingContext(eventArgs, ackAction);

            try
            {
                await ExecutePipeline(context).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                await ExecuteFailurePipeline(context, exception).ConfigureAwait(false);
            }
        }
    public async Task Subscribe_executes()
    {
        /* Given */
        string id      = "1";
        var    payload = new GraphQLRequest();
        var    context = new MessageHandlingContext(_server, null);

        /* When */
        await _sut.SubscribeOrExecuteAsync(id, payload, context);

        /* Then */
        await _executer.Received().ExecuteAsync(
            Arg.Any <ExecutionOptions>());
    }
    public async Task Unsubscribe_removes()
    {
        /* Given */
        string id      = "1";
        var    payload = new GraphQLRequest();
        var    context = new MessageHandlingContext(_server, null);

        await _sut.SubscribeOrExecuteAsync(id, payload, context);

        /* When */
        await _sut.UnsubscribeAsync(id);

        /* Then */
        Assert.Empty(_sut);
    }
예제 #26
0
    public Task HandleAsync(MessageHandlingContext context)
    {
        if (context.Terminated)
        {
            return(Task.CompletedTask);
        }

        return(context.Message.Type switch
        {
            MessageType.GQL_CONNECTION_INIT => HandleInitAsync(context),
            MessageType.GQL_START => HandleStartAsync(context),
            MessageType.GQL_STOP => HandleStopAsync(context),
            MessageType.GQL_CONNECTION_TERMINATE => HandleTerminateAsync(context),
            _ => HandleUnknownAsync(context),
        });
예제 #27
0
        public async Task ShouldProperlyExecutePipelineWithNoAdditionalMiddlewares()
        {
            var argsMock = new Mock <BasicDeliverEventArgs>();
            var messageHandlingServiceMock = new Mock <IMessageHandlingService>();
            var errorProcessingServiceMock = new Mock <IErrorProcessingService>();

            var service = CreateService(
                messageHandlingServiceMock.Object,
                errorProcessingServiceMock.Object,
                Enumerable.Empty <IMessageHandlingMiddleware>());

            var context = new MessageHandlingContext(argsMock.Object, AckAction, false);
            await service.Execute(context);

            messageHandlingServiceMock.Verify(x => x.HandleMessageReceivingEvent(It.IsAny <MessageHandlingContext>()), Times.Once);
        }
예제 #28
0
        public async Task Subscribe_executes()
        {
            /* Given */
            var id      = "1";
            var payload = new OperationMessagePayload();
            var context = new MessageHandlingContext(_server, null);

            /* When */
            await _sut.SubscribeOrExecuteAsync(id, payload, context);

            /* Then */
            await _executer.Received().ExecuteAsync(
                Arg.Is(payload.OperationName),
                Arg.Is(payload.Query),
                Arg.Any <dynamic>(),
                context);
        }
        public void when_executed_with_message_type_and_message_payload_but_without_message_type_descriptor_within_context_it_should_fail()
        {
            var(_, messageBytes) = CreateSerializedMessage();
            var registry = new CaseOfficeIngressApiMessageTypesRegistry();

            registry.Initialize();

            var messageType = typeof(CreateJusticeCase);
            var context     = new MessageHandlingContext {
                MessageType = messageType, Payload = messageBytes
            };

            var         step = new ParseBrokerMessageStep();
            Func <Task> sut  = () => step.Execute(context);

            sut.Should().Throw <KeyNotFoundException>("impossible to parse message without its message type descriptor");
        }
        public void when_executed_with_context_without_message_type_registry_it_should_fail()
        {
            var registry = new CaseOfficeIngressApiMessageTypesRegistry();

            registry.Initialize();
            const string expectedTypeName = "Venture.CaseOffice.Messages.V1.Commands.CreateCase";
            var          context          = new MessageHandlingContext
            {
                Metadata = new Dictionary <string, string> {
                    { VentureApi.Headers.MessageTypeName, expectedTypeName }
                }
            };
            var step = new ExtractMessageTypeStep();

            Func <Task> sut = () => step.Execute(context);

            sut.Should().Throw <KeyNotFoundException>("it can not work without message types registry");
        }