private async Task VerifyPublishPacketTopicAsync(IChannelHandlerContext context, string topicName, string jsonData)
        {
            Match match = s_registrationStatusTopicRegex.Match(topicName);

            if (match.Groups.Count >= 2)
            {
                if (Enum.TryParse(match.Groups[1].Value, out HttpStatusCode statusCode))
                {
                    if (statusCode >= HttpStatusCode.BadRequest)
                    {
                        var errorDetails = JsonConvert.DeserializeObject <ProvisioningErrorDetailsMqtt>(jsonData);

                        bool isTransient = statusCode >= HttpStatusCode.InternalServerError || (int)statusCode == 429;

                        if (isTransient)
                        {
                            errorDetails.RetryAfter = ProvisioningErrorDetailsMqtt.GetRetryAfterFromTopic(topicName, s_defaultOperationPoolingInterval);
                        }

                        await FailWithExceptionAsync(
                            context,
                            new ProvisioningTransportException(
                                jsonData,
                                null,
                                isTransient,
                                errorDetails)).ConfigureAwait(false);
                    }
                }
            }
        }
Exemplo n.º 2
0
        private async Task ProcessRegistrationStatusAsync(IChannelHandlerContext context, PublishPacket packet)
        {
            string operationId = null;

            try // TODO : extract generic method for exception handling.
            {
                await PubAckAsync(context, packet.PacketId).ConfigureAwait(true);

                string jsonData = Encoding.UTF8.GetString(
                    packet.Payload.GetIoBuffer().Array,
                    packet.Payload.GetIoBuffer().Offset,
                    packet.Payload.GetIoBuffer().Count);

                await VerifyPublishPacketTopicAsync(context, packet.TopicName, jsonData).ConfigureAwait(true);

                //"{\"operationId\":\"0.indcertdevice1.e50c0fa7-8b9b-4b3d-8374-02d71377886f\",\"status\":\"assigning\"}"
                var operation = JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonData);
                operationId          = operation.OperationId;
                operation.RetryAfter = ProvisioningErrorDetailsMqtt.GetRetryAfterFromTopic(packet.TopicName, s_defaultOperationPoolingInterval);

                if (string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusAssigning) == 0 ||
                    string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusUnassigned) == 0)
                {
                    await Task.Delay(operation.RetryAfter ?? RetryJitter.GenerateDelayWithJitterForRetry(s_defaultOperationPoolingInterval)).ConfigureAwait(true);

                    ChangeState(State.WaitForStatus, State.WaitForPubAck);
                    await PublishGetOperationAsync(context, operationId).ConfigureAwait(true);
                }
                else
                {
                    ChangeState(State.WaitForStatus, State.Done);
                    _taskCompletionSource.TrySetResult(operation);

                    await this.DoneAsync(context).ConfigureAwait(true);
                }
            }
            catch (ProvisioningTransportException te)
            {
                await FailWithExceptionAsync(context, te).ConfigureAwait(true);
            }
            catch (Exception ex)
            {
                var wrapperEx = new ProvisioningTransportException(
                    $"{ExceptionPrefix} Error while processing RegistrationStatus.",
                    ex,
                    false);

                await FailWithExceptionAsync(context, wrapperEx).ConfigureAwait(true);
            }
        }