public MqttAdapter(
            Settings settings,
            ISessionStatePersistenceProvider sessionStateManager,
            IDeviceIdentityProvider authProvider,
            IQos2StatePersistenceProvider qos2StateProvider,
            MessagingBridgeFactoryFunc messagingBridgeFactory)
        {
            Contract.Requires(settings != null);
            Contract.Requires(sessionStateManager != null);
            Contract.Requires(authProvider != null);
            Contract.Requires(messagingBridgeFactory != null);

            this.lifetimeCancellation = new CancellationTokenSource();

            if (qos2StateProvider != null)
            {
                this.maxSupportedQosToClient = QualityOfService.ExactlyOnce;
                this.qos2StateProvider       = qos2StateProvider;
            }
            else
            {
                this.maxSupportedQosToClient = QualityOfService.AtLeastOnce;
            }

            this.settings               = settings;
            this.sessionStateManager    = sessionStateManager;
            this.authProvider           = authProvider;
            this.messagingBridgeFactory = messagingBridgeFactory;
        }
        /// <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);
        }
        public MqttIotHubAdapter(Settings settings, DeviceClientFactoryFunc deviceClientFactory, ISessionStatePersistenceProvider sessionStateManager, IAuthenticationProvider authProvider,
            ITopicNameRouter topicNameRouter, IQos2StatePersistenceProvider qos2StateProvider)
        {
            Contract.Requires(settings != null);
            Contract.Requires(sessionStateManager != null);
            Contract.Requires(authProvider != null);
            Contract.Requires(topicNameRouter != null);

            if (qos2StateProvider != null)
            {
                this.maxSupportedQosToClient = QualityOfService.ExactlyOnce;
                this.qos2StateProvider = qos2StateProvider;
            }
            else
            {
                this.maxSupportedQosToClient = QualityOfService.AtLeastOnce;
            }

            this.settings = settings;
            this.deviceClientFactory = deviceClientFactory;
            this.sessionStateManager = sessionStateManager;
            this.authProvider = authProvider;
            this.topicNameRouter = topicNameRouter;

            this.publishProcessor = new PacketAsyncProcessor<PublishPacket>(this.PublishToServerAsync);
            this.publishProcessor.Completion.OnFault(ShutdownOnPublishToServerFaultAction);

            TimeSpan? ackTimeout = this.settings.DeviceReceiveAckCanTimeout ? this.settings.DeviceReceiveAckTimeout : (TimeSpan?)null;
            this.publishPubAckProcessor = new RequestAckPairProcessor<AckPendingMessageState, PublishPacket>(this.AcknowledgePublishAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubAckProcessor.Completion.OnFault(ShutdownOnPubAckFaultAction);
            this.publishPubRecProcessor = new RequestAckPairProcessor<AckPendingMessageState, PublishPacket>(this.AcknowledgePublishReceiveAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubRecProcessor.Completion.OnFault(ShutdownOnPubRecFaultAction);
            this.pubRelPubCompProcessor = new RequestAckPairProcessor<CompletionPendingMessageState, PubRelPacket>(this.AcknowledgePublishCompleteAsync, this.RetransmitNextPublishRelease, ackTimeout);
            this.pubRelPubCompProcessor.Completion.OnFault(ShutdownOnPubCompFaultAction);
        }
        /// <summary>
        /// Called by the service fabric when the listener is to be started
        /// </summary>
        /// <param name="cancellationToken">A token to monitor for abort requests</param>
        /// <returns>A task that completes when the service is openned</returns>
        public async Task <string> OpenAsync(CancellationToken cancellationToken)
        {
            string publishAddress = null;
            Guid   traceId        = Guid.NewGuid();
            int    threadCount    = Environment.ProcessorCount;

            this.serverControl = new CancellationTokenSource();
            GatewayConfiguration configuration = this.configurationProvider.Config;

            this.logger.Informational(traceId, this.componentName, "OpenAsync() invoked.");

            var iotHubConfigurationProvider = new ConfigurationProvider <IoTHubConfiguration>(traceId, this.serviceContext.ServiceName, this.serviceContext.CodePackageActivationContext, this.logger, "IoTHubClient");

            iotHubConfigurationProvider.ConfigurationChangedEvent         += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();
            iotHubConfigurationProvider.ConfigurationPropertyChangedEvent += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();
            IoTHubConfiguration iotHubConfiguration = iotHubConfigurationProvider.Config;

            X509Certificate2 certificate = this.GetServerCertificate(configuration);

            this.logger.Informational(traceId, this.componentName, "Certificate retrieved.");

            var mqttConfigurationProvider = new ConfigurationProvider <MqttServiceConfiguration>(traceId, this.serviceContext.ServiceName, this.serviceContext.CodePackageActivationContext, this.logger, "Mqtt");

            mqttConfigurationProvider.ConfigurationChangedEvent         += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();
            mqttConfigurationProvider.ConfigurationPropertyChangedEvent += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();
            MqttServiceConfiguration mqttConfiguration = mqttConfigurationProvider.Config;

            if (mqttConfiguration != null)
            {
                var mqttInboundTemplates  = new List <string>(mqttConfiguration.MqttInboundTemplates);
                var mqttOutboundTemplates = new List <string>(mqttConfiguration.MqttOutboundTemplates);

                ISessionStatePersistenceProvider qosSessionProvider = await this.GetSessionStateProviderAsync(traceId, mqttConfiguration).ConfigureAwait(false);

                IQos2StatePersistenceProvider qos2SessionProvider = await this.GetQos2StateProvider(traceId, mqttConfiguration).ConfigureAwait(false);

                this.logger.Informational(traceId, this.componentName, "QOS Providers instantiated.");

                var settingsProvider = new ServiceFabricConfigurationProvider(traceId, this.componentName, this.logger, configuration, iotHubConfiguration, mqttConfiguration);
                this.bootStrapper = new Bootstrapper(settingsProvider, qosSessionProvider, qos2SessionProvider, mqttInboundTemplates, mqttOutboundTemplates);
                this.runTask      = this.bootStrapper.RunAsync(certificate, threadCount, this.serverControl.Token);

                publishAddress = this.BuildPublishAddress(configuration);

                this.logger.Informational(traceId, this.componentName, "Bootstrapper instantiated.");
            }
            else
            {
                this.logger.Critical(traceId, this.componentName, "Failed to start endpoint because Mqtt service configuration is missing.");
            }

            return(publishAddress);
        }
        public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider)
        {
            Contract.Requires(settingsProvider != null);
            Contract.Requires(sessionStateManager != null);

            this.closeCompletionSource = new TaskCompletionSource();

            this.settingsProvider    = settingsProvider;
            this.settings            = new Settings(this.settingsProvider);
            this.sessionStateManager = sessionStateManager;
            this.qos2StateProvider   = qos2StateProvider;
            this.authProvider        = new SasTokenDeviceIdentityProvider();
            this.iotHubMessageRouter = new ConfigurableMessageRouter();
        }
Example #6
0
        public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider)
        {
            Contract.Requires(settingsProvider != null);
            Contract.Requires(sessionStateManager != null);

            this.closeCompletionSource = new TaskCompletionSource();

            this.settingsProvider    = settingsProvider;
            this.settings            = new Settings(this.settingsProvider);
            this.sessionStateManager = sessionStateManager;
            this.qos2StateProvider   = qos2StateProvider;
            this.authProvider        = new SasTokenAuthenticationProvider();
            this.topicNameRouter     = new TopicNameRouter();
        }
        public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider)
        {
            Contract.Requires(settingsProvider != null);
            Contract.Requires(sessionStateManager != null);

            this.closeCompletionSource = new TaskCompletionSource();

            this.settingsProvider = settingsProvider;
            this.settings = new Settings(this.settingsProvider);
            this.sessionStateManager = sessionStateManager;
            this.qos2StateProvider = qos2StateProvider;
            this.authProvider = new SasTokenAuthenticationProvider();
            this.topicNameRouter = new TopicNameRouter();
        }
        Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider, IMessageAddressConverter addressConverter)
        {
            Contract.Requires(settingsProvider != null);
            Contract.Requires(sessionStateManager != null);

            this.closeCompletionSource = new TaskCompletionSource();

            this.settingsProvider     = settingsProvider;
            this.settings             = new Settings(this.settingsProvider);
            this.iotHubClientSettings = new IotHubClientSettings(this.settingsProvider);
            this.sessionStateManager  = sessionStateManager;
            this.qos2StateProvider    = qos2StateProvider;
            this.authProvider         = new SasTokenDeviceIdentityProvider();
            this.topicNameConverter   = addressConverter;
        }
        Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider, IMessageAddressConverter addressConverter)
        {
            Contract.Requires(settingsProvider != null);
            Contract.Requires(sessionStateManager != null);

            this.closeCompletionSource = new TaskCompletionSource();

            this.settingsProvider = settingsProvider;
            this.settings = new Settings(this.settingsProvider);
            this.iotHubClientSettings = new IotHubClientSettings(this.settingsProvider);
            this.sessionStateManager = sessionStateManager;
            this.qos2StateProvider = qos2StateProvider;
            this.authProvider = new SasTokenDeviceIdentityProvider();
            this.topicNameConverter = addressConverter;
        }
        public MqttIotHubAdapter(
            Settings settings,
            ISessionStatePersistenceProvider sessionStateManager,
            IDeviceIdentityProvider authProvider,
            IQos2StatePersistenceProvider qos2StateProvider,
            IMessagingFactory messagingFactory,
            IMessageRouter messageRouter)
        {
            Contract.Requires(settings != null);
            Contract.Requires(sessionStateManager != null);
            Contract.Requires(authProvider != null);
            Contract.Requires(messageRouter != null);

            if (qos2StateProvider != null)
            {
                this.maxSupportedQosToClient = QualityOfService.ExactlyOnce;
                this.qos2StateProvider       = qos2StateProvider;
            }
            else
            {
                this.maxSupportedQosToClient = QualityOfService.AtLeastOnce;
            }

            this.settings            = settings;
            this.sessionStateManager = sessionStateManager;
            this.authProvider        = authProvider;
            this.messagingFactory    = messagingFactory;
            this.messageRouter       = messageRouter;

            this.publishProcessor = new MessageAsyncProcessor <PublishPacket>(this.PublishToServerAsync);
            this.publishProcessor.Completion.OnFault(ShutdownOnPublishToServerFaultAction);

            TimeSpan?ackTimeout = this.settings.DeviceReceiveAckCanTimeout ? this.settings.DeviceReceiveAckTimeout : (TimeSpan?)null;

            this.publishPubAckProcessor = new RequestAckPairProcessor <AckPendingMessageState, PublishPacket>(this.AcknowledgePublishAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubAckProcessor.Completion.OnFault(ShutdownOnPubAckFaultAction);
            this.publishPubRecProcessor = new RequestAckPairProcessor <AckPendingMessageState, PublishPacket>(this.AcknowledgePublishReceiveAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubRecProcessor.Completion.OnFault(ShutdownOnPubRecFaultAction);
            this.pubRelPubCompProcessor = new RequestAckPairProcessor <CompletionPendingMessageState, PubRelPacket>(this.AcknowledgePublishCompleteAsync, this.RetransmitNextPublishRelease, ackTimeout);
            this.pubRelPubCompProcessor.Completion.OnFault(ShutdownOnPubCompFaultAction);
        }
 public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider, List <string> inboundTemplates, List <string> outboundTemplates) :
     this(settingsProvider, sessionStateManager, qos2StateProvider, new ConfigurableMessageAddressConverter(inboundTemplates ?? new List <string>(), outboundTemplates ?? new List <string>()))
 {
 }
 public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider) :
     this(settingsProvider, sessionStateManager, qos2StateProvider, new ConfigurableMessageAddressConverter())
 {
 }
 public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider, List<string> inboundTemplates, List<string> outboundTemplates) : 
     this(settingsProvider, sessionStateManager, qos2StateProvider, new ConfigurableMessageAddressConverter(inboundTemplates ?? new List<string>(), outboundTemplates ?? new List<string>()))
 {
 }
 public Bootstrapper(ISettingsProvider settingsProvider, ISessionStatePersistenceProvider sessionStateManager, IQos2StatePersistenceProvider qos2StateProvider) : 
     this(settingsProvider, sessionStateManager, qos2StateProvider, new ConfigurableMessageAddressConverter())
 {
 }