예제 #1
0
        private async Task <RegistrationOperationStatus> OperationStatusLookupAsync(
            AmqpClientConnection client,
            string operationId,
            string correlationId)
        {
            var amqpMessage = AmqpMessage.Create(new AmqpValue()
            {
                Value = DeviceOperations.GetOperationStatus
            });

            amqpMessage.Properties.CorrelationId = correlationId;
            amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.OperationType] =
                DeviceOperations.GetOperationStatus;
            amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.OperationId] = operationId;
            var outcome = await client.AmqpSession.SendingLink
                          .SendMessageAsync(amqpMessage, new ArraySegment <byte>(Guid.NewGuid().ToByteArray()),
                                            TimeoutConstant).ConfigureAwait(false);

            ValidateOutcome(outcome);
            var amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(TimeoutConstant)
                               .ConfigureAwait(false);

            client.AmqpSession.ReceivingLink.AcceptMessage(amqpResponse);
            string jsonResponse = await new StreamReader(amqpResponse.BodyStream).ReadToEndAsync()
                                  .ConfigureAwait(false);
            RegistrationOperationStatus status = JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonResponse);

            status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, DefaultOperationPoolingInterval);
            return(status);
        }
        private async Task <RegistrationOperationStatus> RegisterDeviceAsync(
            AmqpClientConnection client,
            string correlationId,
            DeviceRegistration deviceRegistration)
        {
            AmqpMessage amqpMessage = null;

            try
            {
                if (deviceRegistration == null)
                {
                    amqpMessage = AmqpMessage.Create(new MemoryStream(), true);
                }
                else
                {
                    var customContentStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(deviceRegistration)));
                    amqpMessage = AmqpMessage.Create(customContentStream, true);
                }

                amqpMessage.Properties.CorrelationId = correlationId;
                amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.OperationType]     = DeviceOperations.Register;
                amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.ForceRegistration] = false;

                Outcome outcome = await client.AmqpSession.SendingLink
                                  .SendMessageAsync(
                    amqpMessage,
                    new ArraySegment <byte>(Guid.NewGuid().ToByteArray()),
                    s_timeoutConstant)
                                  .ConfigureAwait(false);

                ValidateOutcome(outcome);

                AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(s_timeoutConstant).ConfigureAwait(false);

                client.AmqpSession.ReceivingLink.AcceptMessage(amqpResponse);

                using (var streamReader = new StreamReader(amqpResponse.BodyStream))
                {
                    string jsonResponse = await streamReader
                                          .ReadToEndAsync()
                                          .ConfigureAwait(false);

                    RegistrationOperationStatus status = JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonResponse);
                    status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultOperationPoolingInterval);
                    return(status);
                }
            }
            finally
            {
                amqpMessage?.Dispose();
            }
        }
        private void ValidateOutcome(Outcome outcome)
        {
            if (outcome is Rejected rejected)
            {
                try
                {
                    ProvisioningErrorDetailsAmqp errorDetails = JsonConvert.DeserializeObject <ProvisioningErrorDetailsAmqp>(rejected.Error.Description);
                    int  statusCode  = errorDetails.ErrorCode / 1000;
                    bool isTransient = statusCode >= (int)HttpStatusCode.InternalServerError || statusCode == 429;
                    if (isTransient)
                    {
                        errorDetails.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultOperationPoolingInterval);
                    }

                    throw new ProvisioningTransportException(
                              rejected.Error.Description,
                              null,
                              isTransient,
                              errorDetails);
                }
                catch (JsonException ex)
                {
                    if (Logging.IsEnabled)
                    {
                        Logging.Error(
                            this,
                            $"{nameof(ProvisioningTransportHandlerAmqp)} server returned malformed error response." +
                            $"Parsing error: {ex}. Server response: {rejected.Error.Description}",
                            nameof(RegisterAsync));
                    }

                    throw new ProvisioningTransportException(
                              $"AMQP transport exception: malformed server error message: '{rejected.Error.Description}'",
                              ex,
                              false);
                }
            }
        }