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); } } } }
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); } }