/// <summary>
        /// The settings provider used to bridge Service Fabric configuration information and DotNetty
        /// </summary>
        /// <param name="traceId">The unique identifier used to correlate debugging and diagnostics messages</param>
        /// <param name="componentName">The component name used for debug and diagnostics messages</param>
        /// <param name="logger">The service fabric logger to be used when writing debug and diagnostics information</param>
        /// <param name="gatewayConfiguration">The gateway configuration used to get current configuration information for DotNetty</param>
        /// <param name="iotHubConfiguration">The IotHub Client configuration used to get current configuration information for DotNetty</param>
        /// <param name="mqttConfiguration">The MQTT configuration used to get current configuration information for DotNetty</param>
        public ServiceFabricConfigurationProvider(Guid traceId, string componentName, IServiceLogger logger, GatewayConfiguration gatewayConfiguration, IoTHubConfiguration iotHubConfiguration, MqttServiceConfiguration mqttConfiguration)
        {
            this.componentName = componentName;
            this.logger = logger;

            this.logger.Verbose(traceId, this.componentName, "Initializing configuration provider.");

            var baseProperties = new Dictionary<string, string>();

            foreach (PropertyInfo element in typeof(GatewayConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!element.PropertyType.IsArray)
                {
                    object value = element.GetValue(gatewayConfiguration, null);
                    baseProperties.Add(element.Name, element.PropertyType == typeof(string) ? value as string : value.ToString());
                }
            }

            foreach (PropertyInfo element in typeof(MqttServiceConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!element.PropertyType.IsArray)
                {
                    object value = element.GetValue(mqttConfiguration, null);
                    baseProperties.Add(element.Name, element.PropertyType == typeof(string) ? value as string : value.ToString());
                }
            }

            foreach (PropertyInfo element in typeof(IoTHubConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!element.PropertyType.IsArray)
                {
                    object value = element.GetValue(iotHubConfiguration, null);
                    baseProperties.Add($"IotHubClient.{element.Name}", value?.ToString());
                }
            }



            this.configurationValues = baseProperties.ToImmutableDictionary();
            this.logger.Informational(traceId, this.componentName, "Initializing configuration provider complete.");
        }
Example #2
0
        /// <summary>
        /// The settings provider used to bridge Service Fabric configuration information and DotNetty
        /// </summary>
        /// <param name="traceId">The unique identifier used to correlate debugging and diagnostics messages</param>
        /// <param name="componentName">The component name used for debug and diagnostics messages</param>
        /// <param name="logger">The service fabric logger to be used when writing debug and diagnostics information</param>
        /// <param name="gatewayConfiguration">The gateway configuration used to get current configuration information for DotNetty</param>
        /// <param name="iotHubConfiguration">The IotHub Client configuration used to get current configuration information for DotNetty</param>
        /// <param name="mqttConfiguration">The MQTT configuration used to get current configuration information for DotNetty</param>
        public ServiceFabricConfigurationProvider(Guid traceId, string componentName, IServiceLogger logger, GatewayConfiguration gatewayConfiguration, IoTHubConfiguration iotHubConfiguration, MqttServiceConfiguration mqttConfiguration)
        {
            this.componentName = componentName;
            this.logger        = logger;

            this.logger.Verbose(traceId, this.componentName, "Initializing configuration provider.");

            var baseProperties = new Dictionary <string, string>();

            foreach (PropertyInfo element in typeof(GatewayConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!element.PropertyType.IsArray)
                {
                    object value = element.GetValue(gatewayConfiguration, null);
                    baseProperties.Add(element.Name, element.PropertyType == typeof(string) ? value as string : value.ToString());
                }
            }

            foreach (PropertyInfo element in typeof(MqttServiceConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!element.PropertyType.IsArray)
                {
                    object value = element.GetValue(mqttConfiguration, null);
                    baseProperties.Add(element.Name, element.PropertyType == typeof(string) ? value as string : value.ToString());
                }
            }

            foreach (PropertyInfo element in typeof(IoTHubConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!element.PropertyType.IsArray)
                {
                    object value = element.GetValue(iotHubConfiguration, null);
                    baseProperties.Add($"IotHubClient.{element.Name}", value?.ToString());
                }
            }



            this.configurationValues = baseProperties.ToImmutableDictionary();
            this.logger.Informational(traceId, this.componentName, "Initializing configuration provider complete.");
        }
        /// <summary>
        /// Retrieves the state provider for QoS 2 sessions
        /// </summary>
        /// <param name="traceId">A unique identifier used to correlate debugging and diagnostics messages</param>
        /// <param name="configuration">The gateway configuration</param>
        /// <returns>A Qos2 persistence  provider if available</returns>
        async Task<IQos2StatePersistenceProvider> GetQos2StateProvider(Guid traceId, MqttServiceConfiguration configuration)
        {
            IQos2StatePersistenceProvider stateProvider = null;

            this.logger.Informational(traceId, this.componentName, "QOS2 state provider requested.");

            switch (configuration.MqttQoS2StateProvider)
            {
                case MqttServiceConfiguration.QosStateType.AzureStorage:
                    this.logger.Informational(traceId, this.componentName, "QOS2 state provider requested was Azure Storage.");
                    AzureSessionStateConfiguration provider = new ConfigurationProvider<AzureSessionStateConfiguration>(traceId, this.serviceContext.ServiceName,
                                                                                this.serviceContext.CodePackageActivationContext, this.logger, "AzureState")?.Config;
                    if (provider == null)
                    {
                        this.logger.Critical(traceId, this.componentName, "QOS2 state provider or configuration could not be retrieved.");
                        throw new ApplicationException("Azure state QoS2 provider configuration could not be retrieved");
                    }

                    stateProvider = await TableQos2StatePersistenceProvider.CreateAsync(provider.TableConnectionString, provider.TableName).ConfigureAwait(false);
                    this.logger.Informational(traceId, this.componentName, "QOS2 state provider request complete.");
                    break;

                case MqttServiceConfiguration.QosStateType.ServiceFabricStateful:
                    this.logger.Critical(traceId, this.componentName, "QOS2 state provider requested was Service Fabric Stateful Service but it is not currently implemented.");
                    throw new NotImplementedException("Only azure storage provider is supported");

                default:
                    this.logger.Critical(traceId, this.componentName, "QOS2 state provider requested was unknown.");
                    throw new ApplicationException("MQTT state provider must be specified in configuration.");
            }


            return stateProvider;
        }
        /// <summary>
        /// Retrieves the session state provider to be used for MQTT Sessions
        /// </summary>
        /// <param name="traceId">A unique identifier used to correlate debugging and diagnostics messages</param>
        /// <param name="configuration">The gateway configuration</param>
        /// <returns>A session state persistence provider if available</returns>
        async Task<ISessionStatePersistenceProvider> GetSessionStateProviderAsync(Guid traceId, MqttServiceConfiguration configuration)
        {
            ISessionStatePersistenceProvider stateProvider = null;

            this.logger.Informational(traceId, this.componentName, "QOS state provider requested.");

            switch (configuration.MqttQoSStateProvider)
            {
                case MqttServiceConfiguration.QosStateType.AzureStorage:
                    this.logger.Informational(traceId, this.componentName, "QOS state provider requested was Azure Storage.");
                    var azureConfigurationProvider = new ConfigurationProvider<AzureSessionStateConfiguration>(traceId, this.serviceContext.ServiceName, this.serviceContext.CodePackageActivationContext, this.logger, "AzureState");

                    azureConfigurationProvider.ConfigurationChangedEvent += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();
                    azureConfigurationProvider.ConfigurationPropertyChangedEvent += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();

                    AzureSessionStateConfiguration azureConfiguration = azureConfigurationProvider.Config;

                    if (azureConfiguration == null)
                    {
                        this.logger.Critical(traceId, this.componentName, "QOS state provider or configuration could not be retrieved.");
                        throw new ApplicationException("Azure state QoS provider configuration could not be retrieved");
                    }

                    stateProvider = await BlobSessionStatePersistenceProvider.CreateAsync(azureConfiguration.BlobConnectionString, azureConfiguration.ContainerName).ConfigureAwait(false);
                    this.logger.Informational(traceId, this.componentName, "QOS state provider request complete.");
                    break;

                case MqttServiceConfiguration.QosStateType.ServiceFabricStateful:
                    this.logger.Critical(traceId, this.componentName, "QOS state provider requested was Service Fabric Stateful Service but it is not currently implemented.");
                    throw new NotImplementedException("Only azure storage provider is supported");

                default:
                    this.logger.Critical(traceId, this.componentName, "QOS state provider requested was unknown.");
                    throw new ApplicationException("MQTT state provider must be specified in configuration.");
            }


            return stateProvider;
        }