Esempio n. 1
0
        async Task CompletePublishAsync(IChannelHandlerContext context, PublishPacket will)
        {
            if (will == null)
            {
                return;
            }

            IMessagingServiceClient sendingClient = this.ResolveSendingClient(will.TopicName);

            MessageAsyncProcessor <PublishPacket> publishProcessor;

            if (this.publishProcessors.TryGetValue(sendingClient, out publishProcessor))
            {
                await publishProcessor.Completion;
            }

            try
            {
                await this.PublishToServerAsync(context, sendingClient, will, MessageTypes.Will);
            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Warning("Failed sending Will Message.", ex, this.ChannelId);
            }
        }
Esempio n. 2
0
        async void CloseIotHubConnection(IChannelHandlerContext context, PublishPacket will)
        {
            if (!this.ConnectedToHub)
            {
                // closure happened before IoT Hub connection was established or it was initiated due to disconnect
                return;
            }

            try
            {
                this.publishProcessor.Complete();
                this.publishPubAckProcessor.Complete();
                this.publishPubRecProcessor.Complete();
                this.pubRelPubCompProcessor.Complete();
                await Task.WhenAll(
                    this.CompletePublishAsync(context, will),
                    this.publishPubAckProcessor.Completion,
                    this.publishPubRecProcessor.Completion,
                    this.pubRelPubCompProcessor.Completion);

                IMessagingServiceClient hub = this.messagingServiceClient;
                this.messagingServiceClient = null;
                await hub.DisposeAsync();
            }
            catch (Exception ex)
            {
                MqttIotHubAdapterEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString());
            }
        }
Esempio n. 3
0
        public static void Main(string[] args)
        {
            //_messagingService = new PureDatabaseCalls();
            _messagingServiceClient = new PureDatabaseCallsPgSqlClient();
            //_messagingService = new InprocMessagingService();

            //_messagingService = new WebApiMessagingService();
            //_messagingService.Setup("http://localhost/msvc/v1/messaging", "bb9lWD60BTCBWJO0FlOwtVZxLn0lrC3/");

            _deviceIds = new List <long>();

            for (int i = 0; i < QueueSize; i++)
            {
                _deviceIds.Add(_messagingServiceClient.Initialize(Identity.Next()));
                if (i % _stepSize == 0)
                {
                    Console.WriteLine("Idx: " + i);
                }
            }

            _enc     = 0;
            _dec     = 0;
            _decI    = 0;
            _decIAll = 0;

            for (int inst = 0; inst < 10; inst++)
            {
                Task.Factory.StartNew(Enqueue);

                //Task.Factory.StartNew(DequeueMany);
            }

            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
        async Task CompletePublishAsync(IChannelHandlerContext context, PublishPacket will)
        {
            var completionTasks = new List <Task>();

            foreach (var publishProcessorRecord in this.publishProcessors)
            {
                publishProcessorRecord.Value.Close();
                completionTasks.Add(publishProcessorRecord.Value.Closed);
            }
            await Task.WhenAll(completionTasks);

            IMessagingServiceClient sendingClient = null;

            if (will != null)
            {
                sendingClient = this.ResolveSendingClient(will.TopicName);
                try
                {
                    await this.PublishToServerAsync(context, sendingClient, will, MessageTypes.Will);
                }
                catch (Exception ex)
                {
                    CommonEventSource.Log.Warning("Failed sending Will Message.", ex, this.ChannelId, this.Id);
                }
            }
        }
Esempio n. 5
0
 public DeviceService(IDeviceOperations deviceOperations, INetworkOperations networkOperations, IServiceOperations serviceOperations, ICompanyOperations companyOperations, IAuthenticationContext authenticationContext, IMessagingServiceClient messagingServiceClient) :
     base(companyOperations, authenticationContext)
 {
     _deviceOperations       = deviceOperations;
     _networkOperations      = networkOperations;
     _serviceOperations      = serviceOperations;
     _messagingServiceClient = messagingServiceClient;
 }
        async Task PublishToServerAsync(IChannelHandlerContext context, IMessagingServiceClient sendingClient, PublishPacket packet, string messageType)
        {
            if (!this.ConnectedToService)
            {
                packet.Release();
                return;
            }

            PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart;

            this.ResumeReadingIfNecessary(context);

            IMessage message = null;

            try
            {
                message = sendingClient.CreateMessage(packet.TopicName, packet.Payload);
                Util.CompleteMessageFromPacket(message, packet, this.settings);

                if (messageType != null)
                {
                    message.Properties[this.settings.ServicePropertyPrefix + MessagePropertyNames.MessageType] = messageType;
                }

                await sendingClient.SendAsync(message);

                PerformanceCounters.MessagesSentPerSecond.Increment();

                if (!this.IsInState(StateFlags.Closed))
                {
                    switch (packet.QualityOfService)
                    {
                    case QualityOfService.AtMostOnce:
                        // no response necessary
                        PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);
                        break;

                    case QualityOfService.AtLeastOnce:
                        Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(packet))
                        .OnFault(ShutdownOnWriteFaultAction, context);
                        PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);     // todo: assumes PUBACK is written out sync
                        break;

                    case QualityOfService.ExactlyOnce:
                        ShutdownOnError(context, InboundPublishProcessingScope, new ProtocolGatewayException(ErrorCode.ExactlyOnceQosNotSupported, "QoS 2 is not supported."));
                        break;

                    default:
                        throw new ProtocolGatewayException(ErrorCode.UnknownQosType, "Unexpected QoS level: " + packet.QualityOfService.ToString());
                    }
                }
                message = null;
            }
            finally
            {
                message?.Dispose();
            }
        }
        public async Task OpenAsync(string deviceId, string deviceKey)
        {
            this.deviceIdentity = this.GetDeviceIdentity(deviceId, deviceKey);
            if (this.deviceIdentity != UnauthenticatedDeviceIdentity.Instance)
            {
                this.deviceClient = await this.deviceClientFactory(this.deviceIdentity);

                this.deviceClient.BindMessagingChannel(this);
            }
        }
Esempio n. 8
0
        private void Initialize()
        {
            var environmentFactory = EnvironmentFactoryFactory.Create();

            _authenticationContext  = Substitute.For <IAuthenticationContext>();
            _messagingServiceClient = Substitute.For <IMessagingServiceClient>();

            var userOperations    = environmentFactory.ManagementEnvironment.MgmtUserOperations;
            var companyOperations = environmentFactory.ManagementEnvironment.MgmtCompanyOperations;
            var settingProvider   = new SettingProvider(environmentFactory.ManagementEnvironment.MgmtSettingOperations);

            var userService = new UserService(userOperations, _authenticationContext, settingProvider, null);

            _userId = userService.Register(new RegisterDto()
            {
                Name = "user", Email = EmailHelper.Generate(), Password = "******"
            }, null);

            _companyService = new CompanyService(companyOperations, _authenticationContext, null, new CapabilityProvider(settingProvider));

            _authenticationContext.GetContextUser().Returns(_userId);

            _companyId = _companyService.Create("new company");

            var serviceOperations = environmentFactory.ManagementEnvironment.MgmtServiceOperations;

            _serviceService = new ServiceService(serviceOperations, companyOperations, _authenticationContext, null, new CapabilityProvider(settingProvider));
            _serviceId      = _serviceService.Create(new ServiceDto()
            {
                CompanyId = _companyId, Name = "new service"
            });

            var networkOperations = environmentFactory.ManagementEnvironment.MgmtNetworkOperations;

            _networkService = new NetworkService(networkOperations, serviceOperations, companyOperations, _authenticationContext, null);

            var network = new NetworkDto()
            {
                Name            = "new network",
                ParentNetworkId = null,
                CompanyId       = _companyId,
                ServiceId       = _serviceId
            };

            _networkId = _networkService.Create(network);

            _messagingServiceClient.Initialize("1234").ReturnsForAnyArgs(1);

            var deviceOperations = environmentFactory.ManagementEnvironment.MgmtDeviceOperations;

            _deviceService = new DeviceService(deviceOperations, networkOperations, serviceOperations, companyOperations,
                                               _authenticationContext, _messagingServiceClient);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="VoucherDomainEventHandler" /> class.
 /// </summary>
 /// <param name="securityServiceClient">The security service client.</param>
 /// <param name="voucherAggregateRepository">The voucher aggregate repository.</param>
 /// <param name="dbContextFactory">The database context factory.</param>
 /// <param name="messagingServiceClient">The messaging service client.</param>
 /// <param name="fileSystem">The file system.</param>
 public VoucherDomainEventHandler(ISecurityServiceClient securityServiceClient,
                                  IAggregateRepository <VoucherAggregate, DomainEventRecord.DomainEvent> voucherAggregateRepository,
                                  IDbContextFactory <EstateReportingGenericContext> dbContextFactory,
                                  IMessagingServiceClient messagingServiceClient,
                                  IFileSystem fileSystem)
 {
     this.SecurityServiceClient      = securityServiceClient;
     this.VoucherAggregateRepository = voucherAggregateRepository;
     this.DbContextFactory           = dbContextFactory;
     this.MessagingServiceClient     = messagingServiceClient;
     this.FileSystem = fileSystem;
 }
        public bool TryResolveClient(string topicName, out IMessagingServiceClient sendingClient)
        {
            foreach (var route in routes)
            {
                if (route.Item1(topicName))
                {
                    sendingClient = route.Item2;
                    return(true);
                }
            }

            sendingClient = null;
            return(false);
        }
Esempio n. 11
0
        public static void Start(IBatchParameters batchParameters, IMessagingServiceClient messagingServiceClient)
        {
            var batchWorkerRecord           = new BatchWorkerRecord(messagingServiceClient);
            var batchWorkerReceiveAndForget = new BatchWorkerReceiveAndForget(messagingServiceClient);
            var batchWorkerPeek             = new BatchWorkerPeek(messagingServiceClient);
            var batchWorkerCommit           = new BatchWorkerCommit(messagingServiceClient);

            BatchRunnerReceiveAndForget = new BatchRunner <long, OutgoingMessageToStoreWithState>(
                batchParameters.MessagingReceiveAndForgetCollectionTime,
                batchParameters.MessagingReceiveAndForgetCollectionBatch,
                batchParameters.MessagingReceiveAndForgetFlushBatch,
                batchParameters.MessagingReceiveAndForgetOperationTimeout,
                batchParameters.MessagingReceiveAndForgetWorkerStopTimeout,
                batchWorkerReceiveAndForget);

            BatchRunnerPeek = new BatchRunner <long, OutgoingMessageToStoreWithState>(
                batchParameters.MessagingPeekCollectionTime,
                batchParameters.MessagingPeekCollectionBatch,
                batchParameters.MessagingPeekFlushBatch,
                batchParameters.MessagingPeekOperationTimeout,
                batchParameters.MessagingPeekWorkerStopTimeout,
                batchWorkerPeek);

            BatchRunnerCommit = new BatchRunner <long, OutgoingState>(
                batchParameters.MessagingCommitCollectionTime,
                batchParameters.MessagingCommitCollectionBatch,
                batchParameters.MessagingCommitFlushBatch,
                batchParameters.MessagingCommitOperationTimeout,
                batchParameters.MessagingCommitWorkerStopTimeout,
                batchWorkerCommit);

            BatchRunnerRecord =
                new BatchRunner <OutgoingMessageToStore, OutgoingState>(
                    batchParameters.MessagingRecordCollectionTime,
                    batchParameters.MessagingRecordCollectionBatch,
                    batchParameters.MessagingRecordFlushBatch,
                    batchParameters.MessagingRecordOperationTimeout,
                    batchParameters.MessagingRecordWorkerStopTimeout,
                    batchWorkerRecord);

            BatchRunnerReceiveAndForget.Start();
            BatchRunnerPeek.Start();
            BatchRunnerCommit.Start();
            BatchRunnerRecord.Start();
        }
        void ProcessPublish(IChannelHandlerContext context, PublishPacket packet)
        {
            if (!this.ConnectedToService)
            {
                return;
            }

            IMessagingServiceClient sendingClient = this.ResolveSendingClient(packet.TopicName);
            MessageAsyncProcessor <PublishPacket> publishProcessor;

            if (!this.publishProcessors.TryGetValue(sendingClient, out publishProcessor))
            {
                publishProcessor = new MessageAsyncProcessor <PublishPacket>((c, p) => this.PublishToServerAsync(c, sendingClient, p, null));
                publishProcessor.Closed.OnFault(ShutdownOnPublishToServerFaultAction, this);
                this.publishProcessors[sendingClient] = publishProcessor;
            }

            publishProcessor.Post(context, packet);
        }
Esempio n. 13
0
        async void ShutdownOnReceiveError(IChannelHandlerContext context, string exception)
        {
            this.publishPubAckProcessor.Abort();
            this.publishProcessor.Abort();
            this.publishPubRecProcessor.Abort();
            this.pubRelPubCompProcessor.Abort();

            IMessagingServiceClient hub = this.messagingServiceClient;

            if (hub != null)
            {
                this.messagingServiceClient = null;
                try
                {
                    await hub.DisposeAsync();
                }
                catch (Exception ex)
                {
                    MqttIotHubAdapterEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString());
                }
            }
            ShutdownOnError(context, "Receive", exception);
        }
 public void RegisterRoute(Func <string, bool> routeTopicPredicate, IMessagingServiceClient handler)
 {
     this.routes.Add(Tuple.Create(routeTopicPredicate, handler));
 }
 public SingleClientMqttMessagingBridge(IMessagingServiceClient messagingClient)
 {
     this.messagingClient = messagingClient;
 }
        async void CloseIotHubConnection(IChannelHandlerContext context, PublishPacket will)
        {
            if (!this.ConnectedToHub)
            {
                // closure happened before IoT Hub connection was established or it was initiated due to disconnect
                return;
            }

            try
            {
                this.publishProcessor.Complete();
                this.publishPubAckProcessor.Complete();
                this.publishPubRecProcessor.Complete();
                this.pubRelPubCompProcessor.Complete();
                await Task.WhenAll(
                    this.CompletePublishAsync(context, will),
                    this.publishPubAckProcessor.Completion,
                    this.publishPubRecProcessor.Completion,
                    this.pubRelPubCompProcessor.Completion);

                IMessagingServiceClient hub = this.messagingServiceClient;
                this.messagingServiceClient = null;
                await hub.DisposeAsync();
            }
            catch (Exception ex)
            {
                MqttIotHubAdapterEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString());
            }
        }
Esempio n. 17
0
 public MessageFeedbackChannel(string messageId, IMessagingServiceClient client)
 {
     this.messageId = messageId;
     this.client    = client;
 }
 public MessageFeedbackChannel(string messageId, IMessagingServiceClient client)
 {
     this.messageId = messageId;
     this.client = client;
 }
        async void ShutdownOnReceiveError(IChannelHandlerContext context, string exception)
        {
            this.publishPubAckProcessor.Abort();
            this.publishProcessor.Abort();
            this.publishPubRecProcessor.Abort();
            this.pubRelPubCompProcessor.Abort();

            IMessagingServiceClient hub = this.messagingServiceClient;
            if (hub != null)
            {
                this.messagingServiceClient = null;
                try
                {
                    await hub.DisposeAsync();
                }
                catch (Exception ex)
                {
                    MqttIotHubAdapterEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString());
                }
            }
            ShutdownOnError(context, "Receive", exception);
        }
Esempio n. 20
0
 public BatchWorkerReceiveAndForget(IMessagingServiceClient messagingServiceClient)
 {
     _messagingServiceClient = messagingServiceClient;
 }
 public bool TryResolveClient(string topicName, out IMessagingServiceClient sendingClient)
 {
     sendingClient = this.messagingClient;
     return(true);
 }
Esempio n. 22
0
        /// <summary>
        ///     Performs complete initialization of <see cref="MqttIotHubAdapter" /> based on received CONNECT packet.
        /// </summary>
        /// <param name="context"><see cref="IChannelHandlerContext" /> instance.</param>
        /// <param name="packet">CONNECT packet.</param>
        async void Connect(IChannelHandlerContext context, ConnectPacket packet)
        {
            bool connAckSent = false;

            Exception exception = null;

            try
            {
                if (!this.IsInState(StateFlags.WaitingForConnect))
                {
                    ShutdownOnError(context, "CONNECT has been received in current session already. Only one CONNECT is expected per session.");
                    return;
                }

                this.stateFlags = StateFlags.ProcessingConnect;
                this.identity   = await this.authProvider.GetAsync(packet.ClientId,
                                                                   packet.Username, packet.Password, context.Channel.RemoteAddress);

                if (!this.identity.IsAuthenticated)
                {
                    connAckSent = true;
                    await Util.WriteMessageAsync(context, new ConnAckPacket
                    {
                        ReturnCode = ConnectReturnCode.RefusedNotAuthorized
                    });

                    PerformanceCounters.ConnectionFailedAuthPerSecond.Increment();
                    ShutdownOnError(context, "Authentication failed.");
                    return;
                }

                this.messagingServiceClient = await this.messagingFactory.CreateIotHubClientAsync(this.identity);

                bool sessionPresent = await this.EstablishSessionStateAsync(packet.CleanSession);

                this.keepAliveTimeout = this.DeriveKeepAliveTimeout(packet);

                if (packet.HasWill)
                {
                    var will = new PublishPacket(packet.WillQualityOfService, false, packet.WillRetain);
                    will.TopicName  = packet.WillTopicName;
                    will.Payload    = packet.WillMessage;
                    this.willPacket = will;
                }

                connAckSent = true;
                await Util.WriteMessageAsync(context, new ConnAckPacket
                {
                    SessionPresent = sessionPresent,
                    ReturnCode     = ConnectReturnCode.Accepted
                });

                this.CompleteConnect(context);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (exception != null)
            {
                if (!connAckSent)
                {
                    try
                    {
                        await Util.WriteMessageAsync(context, new ConnAckPacket
                        {
                            ReturnCode = ConnectReturnCode.RefusedServerUnavailable
                        });
                    }
                    catch (Exception ex)
                    {
                        if (MqttIotHubAdapterEventSource.Log.IsVerboseEnabled)
                        {
                            MqttIotHubAdapterEventSource.Log.Verbose("Error sending 'Server Unavailable' CONNACK.", ex.ToString());
                        }
                    }
                }

                ShutdownOnError(context, "CONNECT", exception);
            }
        }
        public async Task CloseAsync()
        {
            await this.deviceClient.DisposeAsync(null);

            this.deviceClient = null;
        }
Esempio n. 24
0
 public BatchWorkerRecord(IMessagingServiceClient messagingServiceClient)
 {
     _messagingServiceClient = messagingServiceClient;
 }
Esempio n. 25
0
 public BatchWorkerPeek(IMessagingServiceClient messagingServiceClient)
 {
     _messagingServiceClient = messagingServiceClient;
 }
Esempio n. 26
0
        /// <summary>
        /// Starts the containers for scenario run.
        /// </summary>
        /// <param name="scenarioName">Name of the scenario.</param>
        public override async Task StartContainersForScenarioRun(String scenarioName)
        {
            String traceFolder = FdOs.IsWindows() ? $"D:\\home\\txnproc\\trace\\{scenarioName}" : $"//home//txnproc//trace//{scenarioName}";

            Logging.Enabled();

            Guid testGuid = Guid.NewGuid();

            this.TestId = testGuid;

            this.Logger.LogInformation($"Test Id is {testGuid}");

            // Setup the container names
            this.SecurityServiceContainerName  = $"securityservice{testGuid:N}";
            this.EventStoreContainerName       = $"eventstore{testGuid:N}";
            this.MessagingServiceContainerName = $"messagingservice{testGuid:N}";

            String eventStoreAddress = $"http://{this.EventStoreContainerName}";

            (String, String, String)dockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland");

            INetworkService testNetwork = DockerHelper.SetupTestNetwork();

            this.TestNetworks.Add(testNetwork);
            IContainerService eventStoreContainer =
                DockerHelper.SetupEventStoreContainer(this.EventStoreContainerName, this.Logger, "eventstore/eventstore:20.10.0-buster-slim", testNetwork, traceFolder, true);

            IContainerService securityServiceContainer = DockerHelper.SetupSecurityServiceContainer(this.SecurityServiceContainerName,
                                                                                                    this.Logger,
                                                                                                    "stuartferguson/securityservice",
                                                                                                    testNetwork,
                                                                                                    traceFolder,
                                                                                                    dockerCredentials,
                                                                                                    true);

            IContainerService messagingServiceContainer = DockerHelper.SetupMessagingServiceContainer(this.MessagingServiceContainerName,
                                                                                                      this.Logger,
                                                                                                      "messagingservice",
                                                                                                      new List <INetworkService> {
                testNetwork
            },
                                                                                                      traceFolder,
                                                                                                      dockerCredentials,
                                                                                                      this.SecurityServiceContainerName,
                                                                                                      eventStoreAddress,
                                                                                                      ("serviceClient", "Secret1"));

            this.Containers.AddRange(new List <IContainerService>
            {
                eventStoreContainer,
                securityServiceContainer,
                messagingServiceContainer
            });

            // Cache the ports
            this.SecurityServicePort  = securityServiceContainer.ToHostExposedEndpoint("5001/tcp").Port;
            this.EventStoreHttpPort   = eventStoreContainer.ToHostExposedEndpoint("2113/tcp").Port;
            this.MessagingServicePort = messagingServiceContainer.ToHostExposedEndpoint("5006/tcp").Port;

            // Setup the base address resolvers
            String SecurityServiceBaseAddressResolver(String api) => $"https://127.0.0.1:{this.SecurityServicePort}";
            String MessagingServiceBaseAddressResolver(String api) => $"http://127.0.0.1:{this.MessagingServicePort}";

            HttpClientHandler clientHandler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (message,
                                                             certificate2,
                                                             arg3,
                                                             arg4) =>
                {
                    return(true);
                }
            };
            HttpClient httpClient = new HttpClient(clientHandler);

            this.SecurityServiceClient  = new SecurityServiceClient(SecurityServiceBaseAddressResolver, httpClient);
            this.MessagingServiceClient = new MessagingServiceClient(MessagingServiceBaseAddressResolver, httpClient);
        }
Esempio n. 27
0
 public BatchWorkerCommit(IMessagingServiceClient messagingServiceClient)
 {
     _messagingServiceClient = messagingServiceClient;
 }
 public SingleClientMessagingBridge(IDeviceIdentity deviceIdentity, IMessagingServiceClient messagingClient)
 {
     this.deviceIdentity  = deviceIdentity;
     this.messagingClient = messagingClient;
 }
        /// <summary>
        ///     Performs complete initialization of <see cref="MqttIotHubAdapter" /> based on received CONNECT packet.
        /// </summary>
        /// <param name="context"><see cref="IChannelHandlerContext" /> instance.</param>
        /// <param name="packet">CONNECT packet.</param>
        async void Connect(IChannelHandlerContext context, ConnectPacket packet)
        {
            bool connAckSent = false;

            Exception exception = null;
            try
            {
                if (!this.IsInState(StateFlags.WaitingForConnect))
                {
                    ShutdownOnError(context, "CONNECT has been received in current session already. Only one CONNECT is expected per session.");
                    return;
                }

                this.stateFlags = StateFlags.ProcessingConnect;
                this.identity = await this.authProvider.GetAsync(packet.ClientId,
                    packet.Username, packet.Password, context.Channel.RemoteAddress);
                if (!this.identity.IsAuthenticated)
                {
                    connAckSent = true;
                    await Util.WriteMessageAsync(context, new ConnAckPacket
                    {
                        ReturnCode = ConnectReturnCode.RefusedNotAuthorized
                    });
                    PerformanceCounters.ConnectionFailedAuthPerSecond.Increment();
                    ShutdownOnError(context, "Authentication failed.");
                    return;
                }

                this.messagingServiceClient = await this.messagingFactory.CreateIotHubClientAsync(this.identity);

                bool sessionPresent = await this.EstablishSessionStateAsync(packet.CleanSession);

                this.keepAliveTimeout = this.DeriveKeepAliveTimeout(packet);

                if (packet.HasWill)
                {
                    var will = new PublishPacket(packet.WillQualityOfService, false, packet.WillRetain);
                    will.TopicName = packet.WillTopicName;
                    will.Payload = packet.WillMessage;
                    this.willPacket = will;
                }

                connAckSent = true;
                await Util.WriteMessageAsync(context, new ConnAckPacket
                {
                    SessionPresent = sessionPresent,
                    ReturnCode = ConnectReturnCode.Accepted
                });

                this.CompleteConnect(context);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (exception != null)
            {
                if (!connAckSent)
                {
                    try
                    {
                        await Util.WriteMessageAsync(context, new ConnAckPacket
                        {
                            ReturnCode = ConnectReturnCode.RefusedServerUnavailable
                        });
                    }
                    catch (Exception ex)
                    {
                        if (MqttIotHubAdapterEventSource.Log.IsVerboseEnabled)
                        {
                            MqttIotHubAdapterEventSource.Log.Verbose("Error sending 'Server Unavailable' CONNACK.", ex.ToString());
                        }
                    }
                }

                ShutdownOnError(context, "CONNECT", exception);
            }
        }