private IMessageInvoker MessageInvokerFactory(IHandlerScope arg)
        {
            var invoker = new MessageInvoker(arg);

            invoker.HandlerMissing += (sender, args) =>
            {
                _log.Warn("Handler missing for " + args.Message.Body.GetType());
            };
            invoker.Logger          = DiagnosticLog;
            invoker.HandlerInvoked += (sender, args) =>
            {
                _log.Debug(args.Message.Body);
                if (args.Exception == null)
                {
                    return;
                }

                Err.Report(args.Exception, new
                {
                    args.Message.Body,
                    HandlerType = args.Handler.GetType(),
                    args.ExecutionTime
                });
                _log.Error(
                    $"Ran {args.Handler}, took {args.ExecutionTime.TotalMilliseconds}ms, but FAILED.",
                    args.Exception);
            };
            return(invoker);
        }
Ejemplo n.º 2
0
        private void RegisterHandler(Type handlerType)
        {
            IEnumerable <MethodInfo> actions = GetHandlerActions(handlerType);

            foreach (MethodInfo action in actions)
            {
                Type           messageType = action.GetParameters()[0].ParameterType;
                MessageInvoker invoker     = CreateInvoker(messageType, handlerType, action);

                var subscription = new Subscription
                {
                    MessageType = messageType,
                    HandlerType = handlerType,
                    Invoker     = invoker,
                    Priority    = GetDispatchingPriority(handlerType, action)
                };

                if (!_store.ContainsKey(subscription.MessageType))
                {
                    var comparer = Comparer <Subscription> .Create((d1, d2) => d1.Priority.CompareTo(d2.Priority));

                    _store[subscription.MessageType] = new SortedSet <Subscription>(comparer);
                }

                _store[subscription.MessageType].Add(subscription);
            }
        }
Ejemplo n.º 3
0
        private IMessageInvoker MessageInvokerFactory(IHandlerScope arg)
        {
            var k       = arg.ResolveDependency <IMessageHandler <FeedbackAttachedToIncident> >();
            var invoker = new MessageInvoker(arg);

            invoker.HandlerMissing += (sender, args) =>
            {
                _logger.Warn(
                    "Failed to find a handler for " + args.Message.Body.GetType());
            };
            invoker.HandlerInvoked += (sender, args) =>
            {
                if (args.Exception == null)
                {
                    return;
                }

                Err.Report(args.Exception,
                           new { args.Message, HandlerType = args.Handler.GetType(), args.ExecutionTime });
                _logger.Error(
                    $"Ran {args.Handler}, took {args.ExecutionTime.TotalMilliseconds}ms, but FAILED.",
                    args.Exception);
            };
            return(invoker);
        }
Ejemplo n.º 4
0
        private QueueListener ConfigureQueueListener(ConfigurationContext context, string inboundQueueName,
                                                     string outboundQueueName)
        {
            var inboundQueue  = _messageQueueProvider.Open(inboundQueueName);
            var outboundQueue = inboundQueueName == outboundQueueName
                ? inboundQueue
                : _messageQueueProvider.Open(outboundQueueName);
            var scopeFactory = new ScopeWrapper(context.ServiceProvider);
            var router       = new MessageRouter
            {
                ReportAnalyzerQueue = outboundQueue,
                AppQueue            = _messageQueueProvider.Open("Messaging")
            };

            var listener = new QueueListener(inboundQueue, router, scopeFactory)
            {
                RetryAttempts = new[]
                { TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2) },
                MessageInvokerFactory = scope =>
                {
                    var invoker = new MessageInvoker(scope);
                    invoker.Logger          += (level, name, message) => _logger.Debug("[" + name + "] " + message);
                    invoker.InvokingHandler += (sender, args) =>
                    {
                        _logger.Debug(
                            $"Invoking {JsonConvert.SerializeObject(args.Message)} ({args.Handler.GetType()}).");
                    };
                    return(invoker);
                },
                Logger = DiagnosticLog
            };

            listener.PoisonMessageDetected += (sender, args) =>
            {
                Err.Report(args.Exception, new { args.Message.Body });
                _logger.Error(inboundQueueName + " Poison message: " + args.Message.Body, args.Exception);
            };
            listener.ScopeCreated += (sender, args) =>
            {
                args.Scope.ResolveDependency <IPrincipalAccessor>().First().Principal = args.Principal;

                _logger.Debug(inboundQueueName + " Running " + args.Message.Body + ", Credentials: " +
                              args.Principal.ToFriendlyString());
            };
            listener.ScopeClosing += (sender, args) =>
            {
                if (args.Exception != null)
                {
                    return;
                }

                var all = args.Scope.ResolveDependency <IAdoNetUnitOfWork>().ToList();
                all[0].SaveChanges();

                var queue = (DomainQueueWrapper)args.Scope.ResolveDependency <IDomainQueue>().First();
                queue.SaveChanges();
            };
            listener.MessageInvokerFactory = MessageInvokerFactory;
            return(listener);
        }
Ejemplo n.º 5
0
        public void CanInvokeProperly()
        {
            MessageInvoker <Test> .Invoke(this, new BaseMessage("a", new object[] { "abcd", "efgh" }))
            .Should().BeNull();

            _invokedOne.Should().BeTrue();

            ((bool)(MessageInvoker <Test> .Invoke(this, new BaseMessage("b", new object[] { 1234, 5678 }))))
            .Should().BeTrue();

            _invokedTwo.Should().BeTrue();
        }
Ejemplo n.º 6
0
        public void RegisterMethod(MethodInfo method, object target = null)
        {
            var invoker = MessageInvoker.Create(method, target);

#if UNITY_EDITOR
            if (items.ContainsKey(invoker.MessageType))
            {
                UnityEngine.Debug.LogError(string.Format("消息类型重复: {0}", invoker.MessageType));
            }
#endif
            items.Add(invoker.MessageType, invoker);
        }
Ejemplo n.º 7
0
        public void Should_require_a_query_handler()
        {
            var scope  = Substitute.For <IHandlerScope>();
            var result = new OneResult();

            scope.Create(typeof(IQueryHandler <OneQuery, OneResult>)).Returns(new object[0]);

            var         sut     = new MessageInvoker(scope);
            var         context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);
            Func <Task> actual  = () => sut.ProcessAsync(context, new OneQuery());

            actual.Should().Throw <NoHandlerRegisteredException>();
        }
Ejemplo n.º 8
0
        Should_be_able_to_reply_with_null_since_that_indicates_that_the_requested_resource_is_not_found()
        {
            var scope        = Substitute.For <IHandlerScope>();
            var handler      = new MyHandler();
            var msg          = new Message(new MyQuery());
            var sut          = new MessageInvoker(scope);
            var queryContext = new ExecuteQueriesInvocationContext(new ClaimsPrincipal(), sut);

            scope.Create(typeof(IQueryHandler <MyQuery, string>)).Returns(new object[] { handler });

            await sut.ProcessAsync(queryContext, msg);

            queryContext.Replies.Should().NotBeEmpty();
        }
Ejemplo n.º 9
0
        public async Task Should_be_able_to_execute_query_sucessfully()
        {
            var scope   = Substitute.For <IHandlerScope>();
            var result  = new OneResult();
            var handler = new OneQueryHandler(result);

            scope.Create(typeof(IQueryHandler <OneQuery, OneResult>)).Returns(new[] { handler });

            var sut     = new MessageInvoker(scope);
            var context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);
            await sut.ProcessAsync(context, new OneQuery());

            context.Replies.First().Body.Should().BeSameAs(result);
        }
Ejemplo n.º 10
0
        public async Task Should_invoke_message_handler()
        {
            var scope   = Substitute.For <IHandlerScope>();
            var handler = new TestHandler <Simple>();

            scope.Create(typeof(IMessageHandler <Simple>)).Returns(new[] { handler });
            var msg     = new Message(new Simple());
            var sut     = new MessageInvoker(scope);
            var context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);

            await sut.ProcessAsync(context, msg);

            handler.Invoked.Should().BeTrue();
        }
Ejemplo n.º 11
0
        public void Should_abort_if_multiple_query_handlers_have_been_registered()
        {
            var scope   = Substitute.For <IHandlerScope>();
            var result  = new OneResult();
            var handler = new OneQueryHandler(result);

            scope.Create(typeof(IQueryHandler <OneQuery, OneResult>)).Returns(new[] { handler, handler });

            var         sut     = new MessageInvoker(scope);
            var         context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);
            Func <Task> actual  = () => sut.ProcessAsync(context, new OneQuery());

            actual.Should().Throw <OnlyOneQueryHandlerAllowedException>();
        }
Ejemplo n.º 12
0
        public async Task Should_be_able_to_reply_with_a_message()
        {
            var scope   = Substitute.For <IHandlerScope>();
            var handler = new MyHandler {
                Result = "Word!"
            };
            var msg          = new Message(new MyQuery());
            var sut          = new MessageInvoker(scope);
            var queryContext = new ExecuteQueriesInvocationContext(new ClaimsPrincipal(), sut);

            scope.Create(typeof(IQueryHandler <MyQuery, string>)).Returns(new object[] { handler });

            await sut.ProcessAsync(queryContext, msg);

            queryContext.Replies[0].Body.Should().Be("Word!");
        }
Ejemplo n.º 13
0
        public void Should_report_all_failed_handlers_in_the_exception()
        {
            var scope    = Substitute.For <IHandlerScope>();
            var handler  = new TestHandler <Simple>((ctx, msg2) => throw new InvalidOperationException("No Data :("));
            var handler2 = new TestHandler <Simple>((ctx, msg2) => throw new DataException("Here comes Lore!"));

            scope.Create(typeof(IMessageHandler <Simple>)).Returns(new[] { handler, handler2 });
            var msg     = new Message(new Simple());
            var sut     = new MessageInvoker(scope);
            var context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);

            Func <Task> actual = () => sut.ProcessAsync(context, msg);

            actual.Should().Throw <HandlersFailedException>()
            .And.FailedHandlers.Count.Should().Be(2);
        }
Ejemplo n.º 14
0
        public void Should_let_exceptions_flow_to_allow_caller_to_decide_appropiate_response()
        {
            var scope    = Substitute.For <IHandlerScope>();
            var handler  = new TestHandler <Simple>();
            var handler2 = new TestHandler <Simple>((ctx, msg2) => throw new DataException("Here comes Lore!"));

            scope.Create(typeof(IMessageHandler <Simple>)).Returns(new[] { handler, handler2 });
            var msg     = new Message(new Simple());
            var sut     = new MessageInvoker(scope);
            var context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);

            Func <Task> actual = () => sut.ProcessAsync(context, msg);

            actual.Should().Throw <HandlersFailedException>()
            .And.FailedHandlers[0].Exception.Message.Should().Be("Here comes Lore!");
        }
Ejemplo n.º 15
0
        public async Task Should_be_able_To_query_and_get_a_result()
        {
            var serviceProvider = new ServiceCollection()
                                  .AddScoped <IQueryHandler <FindUser, FindUserResult>, FindUserHandler>()
                                  .BuildServiceProvider();
            var            scopeFactory = new MicrosoftHandlerScopeFactory(serviceProvider);
            FindUserResult actual;

            using (var scope = scopeFactory.CreateScope())
            {
                var invoker = new MessageInvoker(scope);
                var bus     = new ScopedQueryBus(invoker);
                actual = await bus.QueryAsync(new FindUser());
            }

            actual.Should().NotBeNull();
        }
Ejemplo n.º 16
0
        public bool RegisterMethod(MethodInfo method, object target = null)
        {
#if UNITY_EDITOR && !GX_UNITTEST
            if (IsValid(method) == false)
            {
                UnityEngine.Debug.LogWarning(string.Format("无法兼容的函数签名: {0}", method));
            }
#endif
            var invoker = MessageInvoker.Create(method, target);
#if UNITY_EDITOR
            if (items.ContainsKey(invoker.MessageType))
            {
                UnityEngine.Debug.LogWarning(string.Format("消息类型重复注册并覆盖: {0}", invoker.MessageType));
            }
#endif
            items[invoker.MessageType] = invoker;
            return(true);
        }
        private IMessageInvoker CreateMessageInvoker(IServiceProvider x)
        {
            var provider = (ServiceProvider)x;
            var invoker  = new MessageInvoker(new HandlerScopeWrapper(provider));

            invoker.HandlerMissing += (sender, args) =>
            {
                _log.Error("No handler for " + args.Message.Body.GetType());
                try
                {
                    throw new NoHandlerRegisteredException(
                              "Failed to find a handler for " + args.Message.Body.GetType());
                }
                catch (Exception ex)
                {
                    Err.Report(ex, new { args.Message.Body });
                }
            };

            invoker.InvokingHandler += (sender, args) =>
            {
                _log.Debug($"Invoking {JsonConvert.SerializeObject(args.Message)} ({args.Handler.GetType()}).");
            };
            invoker.HandlerInvoked += (sender, args) =>
            {
                _log.Debug($".. completed {args.Handler.GetType()}");
                if (args.Exception == null)
                {
                    return;
                }

                _log.Error(
                    $"Ran {args.Handler}, took {args.ExecutionTime.TotalMilliseconds}ms, but FAILED.",
                    args.Exception);

                Err.Report(args.Exception, new
                {
                    args.Message.Body,
                    HandlerType = args.Handler.GetType(),
                    args.ExecutionTime
                });
            };
            return(invoker);
        }
        internal static Task Execute(this MessageInvoker invoker, DispatchingContext context)
        {
            var invocationResult = invoker(context.HandlerInstance, context.MessageInstance);

            var awaitableResult = invocationResult as Task;

            if (awaitableResult == null)
            {
                context.Result = invocationResult;
                return(Task.CompletedTask);
            }

            if (awaitableResult.Status == TaskStatus.Created)
            {
                awaitableResult.Start();
            }

            return(awaitableResult.ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    //TODO throw appropriate exception!
                    //throw taskResult.Exception;
                }

                if (task.IsCanceled)
                {
                    throw new OperationCanceledException("The async Task operation was cancelled");
                }

                if (!task.IsCompleted)
                {
                    throw new InvalidOperationException("Unknown Task state");
                }

                context.Result = task.GetResult();
            }));
        }
Ejemplo n.º 19
0
        private IMessageInvoker CreateMessageInvoker(IServiceLocator x)
        {
            var scope   = new GriffinContainerScopeAdapter((IChildContainer)x);
            var invoker = new MessageInvoker(scope);

            invoker.HandlerMissing += (sender, args) =>
            {
                try
                {
                    throw new NoHandlerRegisteredException(
                              "Failed to find a handler for " + args.Message.Body.GetType());
                }
                catch (Exception ex)
                {
                    Err.Report(ex, new { args.Message });
                }
            };
            invoker.HandlerInvoked += (sender, args) =>
            {
                if (args.Exception == null)
                {
                    return;
                }

                Err.Report(args.Exception, new
                {
                    args.Message,
                    HandlerType = args.Handler.GetType(),
                    args.ExecutionTime
                });
                _log.Error(
                    $"Ran {args.Handler}, took {args.ExecutionTime.TotalMilliseconds}ms, but FAILED.",
                    args.Exception);
            };
            return(invoker);
        }
Ejemplo n.º 20
0
        public async Task Should_invoke_second_level_queries_directly()
        {
            var            scope    = Substitute.For <IHandlerScope>();
            var            result   = new OneResult();
            QueryTwoResult expected = null;
            var            handler  = new OneQueryHandler(result, (messageContext, query) =>
            {
                expected = messageContext.QueryAsync(new QueryTwo()).GetAwaiter().GetResult();
            });
            var result2  = new QueryTwoResult();
            var handler2 = new QueryTwoHandler(result2);

            scope.Create(typeof(IQueryHandler <OneQuery, OneResult>)).Returns(new[] { handler });
            scope.Create(typeof(IQueryHandler <QueryTwo, QueryTwoResult>)).Returns(new[] { handler2 });

            var sut     = new MessageInvoker(scope);
            var context = new ExecuteQueriesInvocationContext(ClaimsPrincipal.Current, sut);
            await sut.ProcessAsync(context, new OneQuery());

            expected.Should().BeSameAs(result2, "because it should not be enqueued as queries that comes from the queue");
            context.Replies.Count.Should().Be(1, "because only result from first queue should be enqueued");
            context.Replies.First().Body.Should().Be(result);
            context.Messages.Should().BeEmpty("because no messages were enqueued by the handlers");
        }
Ejemplo n.º 21
0
    public bool RegisterMethod(MethodInfo method, object target = null)
    {
        var invoker = MessageInvoker.Create(method, target);

        if (invoker == null)
        {
            return(false);
        }
#if UNITY_EDITOR
        if (items.ContainsKey(invoker.NetMessageType))
        {
            UnityEngine.Debug.LogError(string.Format("消息类型重复: {0}", invoker.NetMessageType));
        }
#endif
        try
        {
            items.Add(invoker.NetMessageType, invoker);
        }
        catch (System.Exception e)
        {
            Engine.Utility.Log.Error("{0}:{1}", invoker.NetMessageType.ToString(), e.ToString());
        }
        return(true);
    }