コード例 #1
0
        public void MutateIncoming(TransportMessage transportMessage)
        {
            var messageTypeString = GetSubscriptionMessageTypeFrom(transportMessage);

            var intent = transportMessage.MessageIntent;

            if (string.IsNullOrEmpty(messageTypeString) && intent != MessageIntentEnum.Subscribe && intent != MessageIntentEnum.Unsubscribe)
            {
                return;
            }

            if (string.IsNullOrEmpty(messageTypeString))
            {
                throw new InvalidOperationException("Message intent is Subscribe, but the subscription message type header is missing!");
            }

            if (intent != MessageIntentEnum.Subscribe && intent != MessageIntentEnum.Unsubscribe)
            {
                throw new InvalidOperationException("Subscription messages need to have intent set to Subscribe/Unsubscribe");
            }

            var subscriberAddress = transportMessage.ReplyToAddress;

            if (subscriberAddress == null || subscriberAddress == Address.Undefined)
            {
                throw new InvalidOperationException("Subscription message arrived without a valid ReplyToAddress");
            }


            if (SubscriptionStorage == null)
            {
                var warning = string.Format("Subscription message from {0} arrived at this endpoint, yet this endpoint is not configured to be a publisher. To avoid this warning make this endpoint a publisher by configuring a subscription storage or using the AsA_Publisher role.", subscriberAddress);
                Logger.WarnFormat(warning);

                if (Debugger.IsAttached)                          // only under debug, so that we don't expose ourselves to a denial of service
                {
                    throw new InvalidOperationException(warning); // and cause message to go to error queue by throwing an exception
                }
                return;
            }

            //service locate to avoid a circular dependency
            Builder.Build <IBus>().DoNotContinueDispatchingCurrentMessageToHandlers();

            if (transportMessage.MessageIntent == MessageIntentEnum.Subscribe)
            {
                if (!SubscriptionAuthorizer.AuthorizeSubscribe(messageTypeString, subscriberAddress.ToString(), transportMessage.Headers))
                {
                    Logger.Debug(string.Format("Subscription request from {0} on message type {1} was refused.", subscriberAddress, messageTypeString));
                }
                else
                {
                    Logger.Info("Subscribing " + subscriberAddress + " to message type " + messageTypeString);

                    var mt = new MessageType(messageTypeString);

                    SubscriptionStorage.Subscribe(transportMessage.ReplyToAddress, new[] { mt });
                    if (ClientSubscribed != null)
                    {
                        ClientSubscribed(this, new SubscriptionEventArgs
                        {
                            MessageType             = messageTypeString,
                            SubscriberReturnAddress = subscriberAddress
                        });
                    }
                }

                return;
            }


            if (!SubscriptionAuthorizer.AuthorizeUnsubscribe(messageTypeString, subscriberAddress.ToString(), transportMessage.Headers))
            {
                Logger.Debug(string.Format("Unsubscribe request from {0} on message type {1} was refused.", subscriberAddress, messageTypeString));
                return;
            }

            Logger.Info("Unsubscribing " + subscriberAddress + " from message type " + messageTypeString);
            SubscriptionStorage.Unsubscribe(subscriberAddress, new[] { new MessageType(messageTypeString) });
        }
コード例 #2
0
        /// <summary>
        /// Set a <see cref="SubscriptionAuthorizer"/> to be used when verifying a <see cref="MessageIntentEnum.Subscribe"/> or <see cref="MessageIntentEnum.Unsubscribe"/> message.
        /// </summary>
        /// <remarks>This is a "single instance" extension point. So calling this api multiple time will result in only the last one added being executed at message receive time.</remarks>
        /// <param name="transportExtensions">The <see cref="TransportExtensions"/> to extend.</param>
        /// <param name="authorizer">The <see cref="SubscriptionAuthorizer"/> to execute.</param>
        public static void SubscriptionAuthorizer(this TransportExtensions transportExtensions, SubscriptionAuthorizer authorizer)
        {
            Guard.AgainstNull(nameof(authorizer), authorizer);
            var settings  = transportExtensions.Settings;
            var transport = settings.Get <TransportDefinition>();

            if (transport.GetOutboundRoutingPolicy(settings).Publishes == OutboundRoutingType.Multicast)
            {
                var message = $"The transport {transport.GetType().Name} supports native publish-subscribe so subscriptions are not managed by the transport in the publishing endpoint. Use the native transport tools managing subscritions.";
                throw new ArgumentException(message, nameof(authorizer));
            }

            settings.Set <SubscriptionAuthorizer>(authorizer);
        }