private async Task SubscribePeriodically()
        {
            while (!_stopRequested)
            {
                var subscribeTasks = new List <Task>();

                var events = _eventSubscriber.SubscribedEvents.ToList();
                foreach (var eventDesc in events)
                {
                    if (!IsExternal(eventDesc))
                    {
                        continue;
                    }

                    var client      = GetEventingClient(eventDesc.Service);
                    var subscribers = _eventSubscriber.GetSubscribers(eventDesc);

                    subscribeTasks.Add(client.SubscribeAsync(eventDesc, subscribers));
                }

                try
                {
                    await Task.WhenAll(subscribeTasks);
                }
                catch
                {
                }

                await Task.Delay(5_000);
            }
        }
Exemplo n.º 2
0
        public async Task PublishAsync(EventPublishData data, PublishPreferences preferences)
        {
            var eventDesc = new EventDescriptor {
                Service = data.Service, Event = data.Event
            };
            var subscribers = _eventSubscriber.GetSubscribers(eventDesc).ToList();

            if (subscribers.Count == 0)
            {
                return;
            }

            foreach (var subscriber in subscribers)
            {
                var invokeData = new MethodInvocationData
                {
                    IntentId    = _idGenerator.NewId(),
                    Service     = subscriber.Service,
                    Method      = subscriber.Method,
                    Parameters  = data.Parameters,
                    FlowContext = data.FlowContext,
                    Caller      = new CallerDescriptor(data.Service, data.Event, data.IntentId)
                };

                InvokeInBackground(invokeData, preferences);
            }
        }
Exemplo n.º 3
0
        public Task <IEnumerable <IMessageListener> > StartListeningAsync(
            IConfiguration configuration,
            IServiceDefinition serviceDefinition,
            IDictionary <IEventDefinition, IConfiguration> eventConfigMap,
            CancellationToken ct)
        {
            // TODO: there are many scenarios that are not supported by the following code.
            // For example, exchange's connection is different from services' queues.

            var baseConnectionSettings = new ConnectionSettings();

            configuration.Bind(baseConnectionSettings);

            var baseConnection = _connectionManager.GetConnection(baseConnectionSettings);
            var baseChannel    = baseConnection.CreateModel();

            foreach (var eventDefinition in serviceDefinition.Events)
            {
                if (!eventConfigMap.TryGetValue(eventDefinition, out var eventConfiguration))
                {
                    eventConfiguration = configuration;
                }

                var listenerSettings = RabbitMQCommunicationMethod.CreateEventsDefaultSettings();
                eventConfiguration.Bind(listenerSettings);

                var exchangeName = listenerSettings.ExchangeName
                                   .Replace("{serviceName}", serviceDefinition.Name)
                                   .Replace("{eventName}", eventDefinition.Name);

                // TODO: declare once? what's the penalty?
                baseChannel.ExchangeDeclare(
                    exchangeName,
                    type: "fanout",
                    durable: true,
                    autoDelete: false,
                    arguments: null);

                var eventDesc = new EventDescriptor
                {
                    Service = new ServiceId {
                        Name = serviceDefinition.Name
                    },
                    Event = _eventIdProvider.GetId(eventDefinition.EventInfo)
                };

                foreach (var subscriber in _eventSubscriber.GetSubscribers(eventDesc))
                {
                    if (!_serviceResolver.TryResolve(subscriber.Service, out var subscriberServiceReference))
                    {
                        continue;
                    }

                    if (!_methodResolver.TryResolve(subscriberServiceReference.Definition, subscriber.Method, out var subscriberMethodReference))
                    {
                        continue;
                    }

                    var subscriberMethodConfiguration = _communicationModelConfiguration.GetMethodConfiguration(subscriberMethodReference.Definition, "communication");

                    var subscriberSettings = RabbitMQCommunicationMethod.CreateMethodsDefaultSettings();
                    subscriberMethodConfiguration.Bind(subscriberSettings);

                    var subscriberQueueName = subscriberSettings.QueueName
                                              .Replace("{serviceName}", subscriberServiceReference.Definition.Name)
                                              .Replace("{methodName}", subscriberMethodReference.Definition.Name);

                    // TODO: declare once? what's the penalty?
                    baseChannel.QueueBind(
                        queue: subscriberQueueName,
                        exchange: exchangeName,
                        routingKey: "",
                        arguments: null);
                }
            }

            // No direct listeners to RabbitMQ Exchanges, just configure exchange-queue bindings.

            // TODO: if events (or subscribers) use a different connection,
            // need to create a queue and a listener in that RabbitMQ instance.
            return(Task.FromResult <IEnumerable <IMessageListener> >(Array.Empty <IMessageListener>()));
        }
Exemplo n.º 4
0
        public async Task StartAsync(CancellationToken ct)
        {
            foreach (var serviceDefinition in _communicationModel.Services)
            {
                if (serviceDefinition.Type == ServiceType.External)
                {
                    var serviceConfig            = _communicationModelConfiguration.GetEventsConfiguration(serviceDefinition, CommunicationSectionName);
                    var serviceCommunicationType = GetCommunicationType(serviceConfig);

                    var serviceId = new ServiceId {
                        Name = serviceDefinition.Name
                    };

                    var anySubscriberToAnyEvent = false;

                    var eventOverridesMap = new Dictionary <string, Dictionary <IEventDefinition, IConfiguration> >(StringComparer.OrdinalIgnoreCase);

                    foreach (var eventDefinition in serviceDefinition.Events)
                    {
                        var eventId   = _eventIdProvider.GetId(eventDefinition.EventInfo);
                        var eventDesc = new EventDescriptor {
                            Service = serviceId, Event = eventId
                        };

                        var subscribers = _eventSubscriber.GetSubscribers(eventDesc).ToList();

                        if (subscribers.Count == 0)
                        {
                            continue;
                        }

                        var anySubscriberToThisEvent = false;

                        foreach (var subscriber in subscribers)
                        {
                            if (_serviceResolver.TryResolve(subscriber.Service, out _))
                            {
                                anySubscriberToThisEvent = true;
                                anySubscriberToAnyEvent  = true;
                                break;
                            }
                        }

                        if (!anySubscriberToThisEvent)
                        {
                            continue;
                        }

                        if (_communicationModelConfiguration
                            .GetEventOverrideLevels(eventDefinition, CommunicationSectionName)
                            .HasFlag(ConfigOverrideLevels.Primitive))
                        {
                            var eventConfig            = _communicationModelConfiguration.GetEventConfiguration(eventDefinition);
                            var eventCommunicationType = GetCommunicationType(eventConfig);

                            if (!eventOverridesMap.TryGetValue(eventCommunicationType, out var configMap))
                            {
                                configMap = new Dictionary <IEventDefinition, IConfiguration>();
                                eventOverridesMap.Add(eventCommunicationType, configMap);
                            }

                            configMap.Add(eventDefinition, eventConfig);
                        }
                    }

                    if (anySubscriberToAnyEvent)
                    {
                        if (!eventOverridesMap.TryGetValue(serviceCommunicationType, out var configMap))
                        {
                            configMap = new Dictionary <IEventDefinition, IConfiguration>();
                        }
                        await StartListeningEventsAsync(serviceCommunicationType, serviceDefinition, serviceConfig, configMap, ct);

                        var extraCommTypes = eventOverridesMap.Keys.Where(c => !string.Equals(c, serviceCommunicationType, StringComparison.OrdinalIgnoreCase));
                        foreach (var extraCommType in extraCommTypes)
                        {
                            configMap = eventOverridesMap[extraCommType];
                            await StartListeningEventsAsync(extraCommType, serviceDefinition, serviceConfig, configMap, ct);
                        }
                    }
                }
                else
                {
                    var methodOverridesMap = new Dictionary <string, Dictionary <IMethodDefinition, IConfiguration> >(StringComparer.OrdinalIgnoreCase);
                    var eventOverridesMap  = new Dictionary <string, Dictionary <IEventDefinition, IConfiguration> >(StringComparer.OrdinalIgnoreCase);

                    foreach (var methodDefinition in serviceDefinition.Methods)
                    {
                        if (_communicationModelConfiguration
                            .GetMethodOverrideLevels(methodDefinition, CommunicationSectionName)
                            .HasFlag(ConfigOverrideLevels.Primitive))
                        {
                            var methodConfig            = _communicationModelConfiguration.GetMethodConfiguration(methodDefinition);
                            var methodCommunicationType = GetCommunicationType(methodConfig);

                            if (!methodOverridesMap.TryGetValue(methodCommunicationType, out var configMap))
                            {
                                configMap = new Dictionary <IMethodDefinition, IConfiguration>();
                                methodOverridesMap.Add(methodCommunicationType, configMap);
                            }

                            configMap.Add(methodDefinition, methodConfig);
                        }
                    }

                    foreach (var eventDefinition in serviceDefinition.Events)
                    {
                        if (_communicationModelConfiguration
                            .GetEventsOverrideLevels(serviceDefinition, CommunicationSectionName)
                            .HasFlag(ConfigOverrideLevels.Primitive))
                        {
                            var eventConfig            = _communicationModelConfiguration.GetEventConfiguration(eventDefinition);
                            var eventCommunicationType = GetCommunicationType(eventConfig);

                            if (!eventOverridesMap.TryGetValue(eventCommunicationType, out var configMap))
                            {
                                configMap = new Dictionary <IEventDefinition, IConfiguration>();
                                eventOverridesMap.Add(eventCommunicationType, configMap);
                            }

                            configMap.Add(eventDefinition, eventConfig);
                        }
                    }

                    var hasQueriesOverride = (_communicationModelConfiguration
                                              .GetQueriesOverrideLevels(serviceDefinition, CommunicationSectionName)
                                              & (ConfigOverrideLevels.BasePrimitives | ConfigOverrideLevels.ServiceTypePrimitives | ConfigOverrideLevels.ServicePrimitives)) != default;

                    var hasCommandsOverride = (_communicationModelConfiguration
                                               .GetCommandsOverrideLevels(serviceDefinition, CommunicationSectionName)
                                               & (ConfigOverrideLevels.BasePrimitives | ConfigOverrideLevels.ServiceTypePrimitives | ConfigOverrideLevels.ServicePrimitives)) != default;

                    if (hasQueriesOverride || hasCommandsOverride)
                    {
                        var allQueriesConfig            = _communicationModelConfiguration.GetQueriesConfiguration(serviceDefinition, CommunicationSectionName);
                        var allQueriesCommunicationType = GetCommunicationType(allQueriesConfig);

                        if (!methodOverridesMap.TryGetValue(allQueriesCommunicationType, out var methodConfigMap))
                        {
                            methodConfigMap = new Dictionary <IMethodDefinition, IConfiguration>();
                        }
                        await StartHadlingMethodsAsync(allQueriesCommunicationType, serviceDefinition, allQueriesConfig, methodConfigMap, ct);

                        var allCommandsConfig            = _communicationModelConfiguration.GetCommandsConfiguration(serviceDefinition, CommunicationSectionName);
                        var allCommandsCommunicationType = GetCommunicationType(allCommandsConfig);

                        if (!methodOverridesMap.TryGetValue(allCommandsCommunicationType, out methodConfigMap))
                        {
                            methodConfigMap = new Dictionary <IMethodDefinition, IConfiguration>();
                        }
                        await StartHadlingMethodsAsync(allCommandsCommunicationType, serviceDefinition, allCommandsConfig, methodConfigMap, ct);

                        var methodsExtraCommTypes = methodOverridesMap.Keys.Where(c =>
                                                                                  !string.Equals(c, allQueriesCommunicationType, StringComparison.OrdinalIgnoreCase) &&
                                                                                  !string.Equals(c, allCommandsCommunicationType, StringComparison.OrdinalIgnoreCase));
                        foreach (var methodExtraCommType in methodsExtraCommTypes)
                        {
                            methodConfigMap = methodOverridesMap[methodExtraCommType];

                            var queryConfigMap   = new Dictionary <IMethodDefinition, IConfiguration>();
                            var commandConfigMap = new Dictionary <IMethodDefinition, IConfiguration>();
                            foreach (var pair in methodConfigMap)
                            {
                                if (pair.Key.IsQuery)
                                {
                                    queryConfigMap.Add(pair.Key, pair.Value);
                                }
                                else
                                {
                                    commandConfigMap.Add(pair.Key, pair.Value);
                                }
                            }

                            if (queryConfigMap.Count > 0)
                            {
                                await StartHadlingMethodsAsync(methodExtraCommType, serviceDefinition, allQueriesConfig, queryConfigMap, ct);
                            }
                            if (commandConfigMap.Count > 0)
                            {
                                await StartHadlingMethodsAsync(methodExtraCommType, serviceDefinition, allCommandsConfig, commandConfigMap, ct);
                            }
                        }
                    }
                    else
                    {
                        var serviceConfig            = _communicationModelConfiguration.GetServiceConfiguration(serviceDefinition, CommunicationSectionName);
                        var serviceCommunicationType = GetCommunicationType(serviceConfig);

                        if (!methodOverridesMap.TryGetValue(serviceCommunicationType, out var methodConfigMap))
                        {
                            methodConfigMap = new Dictionary <IMethodDefinition, IConfiguration>();
                        }
                        await StartHadlingMethodsAsync(serviceCommunicationType, serviceDefinition, serviceConfig, methodConfigMap, ct);

                        var methodsExtraCommTypes = methodOverridesMap.Keys.Where(c => !string.Equals(c, serviceCommunicationType, StringComparison.OrdinalIgnoreCase));
                        foreach (var methodExtraCommType in methodsExtraCommTypes)
                        {
                            methodConfigMap = methodOverridesMap[methodExtraCommType];
                            await StartHadlingMethodsAsync(methodExtraCommType, serviceDefinition, serviceConfig, methodConfigMap, ct);
                        }
                    }

                    var allEventsConfig            = _communicationModelConfiguration.GetEventsConfiguration(serviceDefinition, CommunicationSectionName);
                    var allEventsCommunicationType = GetCommunicationType(allEventsConfig);

                    if (!eventOverridesMap.TryGetValue(allEventsCommunicationType, out var eventConfigMap))
                    {
                        eventConfigMap = new Dictionary <IEventDefinition, IConfiguration>();
                    }
                    await StartListeningEventsAsync(allEventsCommunicationType, serviceDefinition, allEventsConfig, eventConfigMap, ct);

                    var eventsExtraCommTypes = eventOverridesMap.Keys.Where(c => !string.Equals(c, allEventsCommunicationType, StringComparison.OrdinalIgnoreCase));
                    foreach (var eventExtraCommType in eventsExtraCommTypes)
                    {
                        eventConfigMap = eventOverridesMap[eventExtraCommType];
                        await StartListeningEventsAsync(eventExtraCommType, serviceDefinition, allEventsConfig, eventConfigMap, ct);
                    }
                }
            }
        }