コード例 #1
0
        public async ValueTask <bool> CallAsync(
            IMessageScope scope, IMessageHandlerFactory handlerFactory,
            IMessage message, IRichMessageDescriptor messageDescriptor,
            List <Exception> exceptions         = null,
            CancellationToken cancellationToken = default)
        {
            exceptions = exceptions ?? new List <Exception>();
            var handlerDescriptor = handlerFactory.GetHandlerDescriptor();

            if (handlerDescriptor.IsAsync)
            {
                if (handlerDescriptor.IsRich)
                {
                    await ProcessRichMessageHandlingExceptionAsync(scope, handlerFactory, handlerDescriptor.MessageType, message, messageDescriptor, exceptions);
                }
                else
                {
                    await ProcessMessageHandlingExceptionAsync(scope, handlerFactory, handlerDescriptor.MessageType, message, exceptions);
                }
            }
            else
            {
                if (handlerDescriptor.IsRich)
                {
                    ProcessRichMessageHandlingException(scope, handlerFactory, handlerDescriptor.MessageType, message, messageDescriptor, exceptions);
                }
                else
                {
                    ProcessMessageHandlingException(scope, handlerFactory, handlerDescriptor.MessageType, message, exceptions);
                }
            }

            return(true);
        }
コード例 #2
0
        private ICoreSession ParseSession(IRichMessageDescriptor messageDescriptor)
        {
            if (messageDescriptor.Headers is null)
            {
                return(null);
            }
            messageDescriptor.Headers.TryGetValue(SessionConsts.CityId, out var city);
            messageDescriptor.Headers.TryGetValue(SessionConsts.CompanyId, out var companyId);
            messageDescriptor.Headers.TryGetValue(SessionConsts.CompanyName, out var companyName);
            messageDescriptor.Headers.TryGetValue(SessionConsts.StoreId, out var storeId);
            messageDescriptor.Headers.TryGetValue(SessionConsts.StoreName, out var storeName);
            messageDescriptor.Headers.TryGetValue(SessionConsts.BrokerId, out var brokerId);
            messageDescriptor.Headers.TryGetValue(SessionConsts.BrokerName, out var brokerName);
            messageDescriptor.Headers.TryGetValue(SessionConsts.OrganizationId, out var organizationId);
            messageDescriptor.Headers.TryGetValue(SessionConsts.OrganizationName, out var organizationName);
            messageDescriptor.Headers.TryGetValue(SessionConsts.CurrentUserId, out var currentUserId);
            messageDescriptor.Headers.TryGetValue(SessionConsts.CurrentUserName, out var currentUserName);
            var session = new CoreSession(
                TryConvertFromBytes(city as byte[]),
                TryConvertFromBytes(companyId as byte[]).AsGuidOrNull(),
                TryUriDecode(TryConvertFromBytes(companyName as byte[])),
                TryConvertFromBytes(storeId as byte[]).AsGuidOrNull(),
                TryUriDecode(TryConvertFromBytes(storeName as byte[])),
                TryConvertFromBytes(brokerId as byte[]),
                TryUriDecode(TryConvertFromBytes(brokerName as byte[])),
                TryConvertFromBytes(organizationId as byte[]),
                TryUriDecode(TryConvertFromBytes(organizationName as byte[])),
                TryConvertFromBytes(currentUserId as byte[]),
                TryUriDecode(TryConvertFromBytes(currentUserName as byte[])));

            return(session);
        }
コード例 #3
0
 public void HandleMessage(WebTestMessage message, IRichMessageDescriptor descriptor)
 {
     if (_coreSessionProvider is MessageCoreSessionProvider provider)
     {
         if (provider.MessageDescriptor == descriptor)
         {
             return;
         }
     }
     throw new ApplicationException("Session错误");
 }
コード例 #4
0
        public IMessageScope CreateScope(IMessage message, IRichMessageDescriptor messageDescriptor)
        {
            var sessionProvider = new MessageCoreSessionProvider(message, messageDescriptor);
            var scope           = _lifetimeScope.BeginLifetimeScope(builder =>
            {
                builder.RegisterInstance(sessionProvider)
                .As <ICoreSessionProvider>()
                .PropertiesAutowired();
            });
            var messageScope = new MessageScope(scope);

            return(messageScope);
        }
コード例 #5
0
        private async ValueTask ProcessMessageAsync(
            IRichMessageDescriptor descriptor, byte[] message)
        {
            Logger.LogInformation($"ProcessMessageAsync: Exchange: {descriptor.MessageGroup}, Topic: {descriptor.MessageTopic}");
            if (!_subscribers.TryGetValue(descriptor, out var func))
            {
                Logger.LogWarning($"ProcessMessageAsync: Subscriber not exists");
                return;
            }
            var typedMessage = _messageConverter.Deserialize(descriptor, message);

            if (typedMessage == null)
            {
                Logger.LogWarning($"ProcessMessageAsync: Cannot convert message to a typed message");
                return;
            }
            await func(typedMessage, descriptor);
        }
コード例 #6
0
        public virtual async ValueTask OnMessageReceivedAsync(IMessage message, IRichMessageDescriptor descriptor)
        {
            if (message is null)
            {
                return;
            }
            using (var scope = _scopeCreator.CreateScope(message, descriptor))
            {
                var messageStore = scope.Resolve(typeof(IConsumedMessageStore)) as IConsumedMessageStore;

                if (await messageStore.IsConsumedAsync(descriptor, message))
                {
                    _logger.LogWarning($"[{descriptor.MessageGroup}][{descriptor.MessageTopic}][{descriptor.MessageId}]Message already consumed.");
                    return;
                }
                await ProcessMessageAsync(scope, message.GetType(), message, descriptor);

                await messageStore.StoreAsync(descriptor, message);
            }
        }
コード例 #7
0
        public IMessageScope CreateScope(IMessage message, IRichMessageDescriptor messageDescriptor)
        {
            var coreSessionProvider = new MessageCoreSessionProvider(message, messageDescriptor);

            return(new MessageScope(_iocManager, coreSessionProvider));
        }
コード例 #8
0
 public MessageCoreSessionProvider(IMessage message, IRichMessageDescriptor messageDescriptor)
 {
     _message          = message;
     MessageDescriptor = messageDescriptor;
 }
コード例 #9
0
 ValueTask IMessageBus.OnMessageReceivedAsync(IMessage message, IRichMessageDescriptor descriptor)
 {
     return(new ValueTask());
 }
コード例 #10
0
        public async ValueTask <bool> CallAsync(IMessageScope scope, IMessageHandlerFactory handlerFactory, IMessage message, IRichMessageDescriptor messageDescriptor, List <Exception> exceptions = null, CancellationToken cancellationToken = default)
        {
            var             handlerDescriptor = handlerFactory.GetHandlerDescriptor();
            IMessageHandler handler           = null;

            try
            {
                handler = handlerFactory.GetHandler(scope);

                if (handlerDescriptor.IsAsync)
                {
                    await GetOrCreateAsyncHandlerCallCache(handlerDescriptor).Invoke(handler, message, messageDescriptor);
                }
                else
                {
                    GetOrCreateSyncHandlerCallCache(handlerDescriptor).Invoke(handler, message, messageDescriptor);
                }
            }
            catch (TargetInvocationException e)
            {
                exceptions?.Add(e.InnerException);
                return(false);
            }
            catch (Exception e)
            {
                exceptions?.Add(e);
                return(false);
            }
            finally
            {
                if (handler != null)
                {
                    handlerFactory.ReleaseHandler(scope, handler);
                }
            }
            return(true);
        }
コード例 #11
0
        private async ValueTask ProcessRichMessageHandlingExceptionAsync(IMessageScope scope, IMessageHandlerFactory asyncHandlerFactory, Type messageType, IMessage message, IRichMessageDescriptor descriptor, List <Exception> exceptions)
        {
            var handlerInstance = asyncHandlerFactory.GetHandler(scope);

            try
            {
                if (handlerInstance == null)
                {
                    throw new ArgumentNullException($"Registered async rich message handler for message type {messageType.Name} is null!");
                }

                var ifType = typeof(IAsyncRichMessageHandler <>).MakeGenericType(messageType);

                var method = ifType.GetMethod(
                    nameof(IAsyncRichMessageHandler <IMessage> .HandleMessageAsync),
                    new[] { messageType, typeof(IRichMessageDescriptor) }
                    );



                await(ValueTask) method.Invoke(handlerInstance, new object[] { message, descriptor });
            }
            catch (TargetInvocationException ex)
            {
                exceptions.Add(ex.InnerException);
            }
            catch (Exception ex)
            {
                exceptions.Add(ex);
            }
            finally
            {
                asyncHandlerFactory.ReleaseHandler(scope, handlerInstance);
            }
        }
コード例 #12
0
        private void ProcessRichMessageHandlingException(IMessageScope scope, IMessageHandlerFactory handlerFactory, Type messageType, IMessage message, IRichMessageDescriptor descriptor, List <Exception> exceptions)
        {
            var eventHandler = handlerFactory.GetHandler(scope);

            try
            {
                if (eventHandler == null)
                {
                    throw new ArgumentNullException($"Registered rich message handler for message type {messageType.Name} is null!");
                }

                var handlerType = typeof(IRichMessageHandler <>).MakeGenericType(messageType);

                var method = handlerType.GetMethod(
                    nameof(IRichMessageHandler <IMessage> .HandleMessage),
                    new[] { messageType, typeof(IRichMessageDescriptor) }
                    );

                method.Invoke(eventHandler, new object[] { message, descriptor });
            }
            catch (TargetInvocationException ex)
            {
                exceptions.Add(ex.InnerException);
            }
            catch (Exception ex)
            {
                exceptions.Add(ex);
            }
            finally
            {
                handlerFactory.ReleaseHandler(scope, eventHandler);
            }
        }
コード例 #13
0
 public IMessageScope CreateScope(IMessage message, IRichMessageDescriptor messageDescriptor)
 {
     return(new NullMessageScope());
 }
コード例 #14
0
        protected async ValueTask ProcessMessageAsync(IMessageScope scope, Type messageType, IMessage message, IRichMessageDescriptor descriptor)
        {
            var exceptions = new List <Exception>();

            await new SynchronizationContextRemover();

            foreach (var handlerFactories in _messageHandlerFactoryStore.GetHandlerFactories(messageType).ToList())
            {
                foreach (var handlerFactory in handlerFactories.MessageHandlerFactories)
                {
                    var isCallSuccess = await _messageHandlerCaller.CallAsync(scope, handlerFactory, message, descriptor, exceptions);

                    if (!isCallSuccess)
                    {
                        var errorMessage = $"Call message handler error";
                        exceptions.Add(new MessageBusException(errorMessage));
                    }
                }
            }

            //Implements generic argument inheritance. See IMessageWithInheritableGenericArgument
            if (messageType.IsGenericType &&
                messageType.GenericTypeArguments.Length == 1 &&
                typeof(IMessageWithInheritableGenericArgument).IsAssignableFrom(messageType))
            {
                var genericArg = messageType.GetGenericArguments()[0];
                var baseArg    = genericArg.BaseType;
                if (baseArg != null)
                {
                    var baseMessageType = messageType.GetGenericTypeDefinition().MakeGenericType(baseArg);
                    var constructorArgs = ((IMessageWithInheritableGenericArgument)messageType).GetConstructorArgs();
                    //TODO: Use Expression Tree instead / or do Inheritable Abstractions
                    var baseMessage = (IMessage)Activator.CreateInstance(baseMessageType, constructorArgs);
                    await ProcessMessageAsync(scope, baseMessageType, baseMessage, descriptor);
                }
            }

            if (exceptions.Any())
            {
                if (exceptions.Count == 1)
                {
                    ExceptionDispatchInfo.Capture(exceptions[0]).Throw();
                }

                throw new AggregateException("More than one error has occurred while handling the message: " + messageType, exceptions);
            }
        }