private async Task <RegistrationOperationStatus> RegisterDeviceAsync( AmqpClientConnection client, string correlationId, DeviceRegistration deviceRegistration) { AmqpMessage amqpMessage; 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; 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); return(JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonResponse)); }
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); 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); return(JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonResponse)); }
public override Task OpenConnectionAsync( AmqpClientConnection connection, bool useWebSocket, IWebProxy proxy, RemoteCertificateValidationCallback remoteCertificateValidationCallback, CancellationToken cancellationToken) { return(connection.OpenAsync(useWebSocket, null, proxy, remoteCertificateValidationCallback, cancellationToken)); }
public override Task OpenConnectionAsync( AmqpClientConnection connection, bool useWebSocket, IWebProxy proxy, RemoteCertificateValidationCallback remoteCertificateValidationCallback, CancellationToken cancellationToken) { X509Certificate2 clientCert = _security.GetAuthenticationCertificate(); return(connection.OpenAsync(useWebSocket, clientCert, proxy, remoteCertificateValidationCallback, cancellationToken)); }
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 static async Task CreateLinksAsync(AmqpClientConnection connection, string linkEndpoint, string productInfo) { AmqpClientSession amqpDeviceSession = connection.CreateSession(); await amqpDeviceSession.OpenAsync(s_timeoutConstant).ConfigureAwait(false); AmqpClientLink amqpReceivingLink = amqpDeviceSession.CreateReceivingLink(linkEndpoint); amqpReceivingLink.AddClientVersion(productInfo); amqpReceivingLink.AddApiVersion(ClientApiVersionHelper.ApiVersion); await amqpReceivingLink.OpenAsync(s_timeoutConstant).ConfigureAwait(false); AmqpClientLink amqpSendingLink = amqpDeviceSession.CreateSendingLink(linkEndpoint); amqpSendingLink.AddClientVersion(productInfo); amqpSendingLink.AddApiVersion(ClientApiVersionHelper.ApiVersion); await amqpSendingLink.OpenAsync(s_timeoutConstant).ConfigureAwait(false); }
private async Task <RegistrationOperationStatus> OperationStatusLookupAsync( AmqpClientConnection client, string operationId, string correlationId, CancellationToken cancellationToken) { using 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; Outcome outcome = await client.AmqpSession.SendingLink .SendMessageAsync( amqpMessage, new ArraySegment <byte>(Guid.NewGuid().ToByteArray()), cancellationToken) .ConfigureAwait(false); ValidateOutcome(outcome); AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink .ReceiveMessageAsync(cancellationToken) .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_defaultOperationPollingInterval); return(status); }
public override Task OpenConnectionAsync(AmqpClientConnection connection, TimeSpan timeout, bool useWebSocket, IWebProxy proxy) { return(connection.OpenAsync(timeout, useWebSocket, null, null, proxy)); }
public override async Task <DeviceRegistrationResult> RegisterAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, $"{nameof(ProvisioningTransportHandlerAmqp)}.{nameof(RegisterAsync)}"); } cancellationToken.ThrowIfCancellationRequested(); try { AmqpAuthStrategy authStrategy; if (message.Security is SecurityClientHsmTpm) { authStrategy = new AmqpAuthStrategyTpm((SecurityClientHsmTpm)message.Security); } else if (message.Security is SecurityClientHsmX509) { authStrategy = new AmqpAuthStrategyX509((SecurityClientHsmX509)message.Security); } else { throw new NotSupportedException( $"{nameof(message.Security)} must be of type {nameof(SecurityClientHsmTpm)} " + $"or {nameof(SecurityClientHsmX509)}"); } if (Logging.IsEnabled) { Logging.Associate(authStrategy, this); } bool useWebSocket = (FallbackType == TransportFallbackType.WebSocketOnly); var builder = new UriBuilder() { Scheme = useWebSocket ? WebSocketConstants.Scheme : AmqpConstants.SchemeAmqps, Host = message.GlobalDeviceEndpoint, Port = useWebSocket ? WebSocketConstants.Port : AmqpConstants.DefaultSecurePort }; string registrationId = message.Security.GetRegistrationID(); string linkEndpoint = $"{message.IdScope}/registrations/{registrationId}"; AmqpClientConnection connection = authStrategy.CreateConnection(builder.Uri, linkEndpoint); await authStrategy.OpenConnectionAsync(connection, TimeoutConstant, useWebSocket).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await CreateLinksAsync(connection, linkEndpoint, message.ProductInfo).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); string correlationId = new Guid().ToString(); RegistrationOperationStatus operation = await RegisterDeviceAsync(connection, correlationId).ConfigureAwait(false); // Poll with operationId until registration complete. int attempts = 0; string operationId = operation.OperationId; // Poll with operationId until registration complete. while (string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusAssigning) == 0 || string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusUnassigned) == 0) { cancellationToken.ThrowIfCancellationRequested(); await Task.Delay( operation.RetryAfter ?? DefaultOperationPoolingIntervalMilliseconds).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); operation = await OperationStatusLookupAsync( connection, operationId, correlationId).ConfigureAwait(false); attempts++; } if (string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusAssigned) == 0) { authStrategy.SaveCredentials(operation); } return(ConvertToProvisioningRegistrationResult(operation.RegistrationStatus)); } // TODO: Catch only expected exceptions from Amqp. catch (Exception ex) { if (Logging.IsEnabled) { Logging.Error( this, $"{nameof(ProvisioningTransportHandlerAmqp)} threw exception {ex}", nameof(RegisterAsync)); } // TODO: Extract trackingId from the exception. throw new ProvisioningTransportException($"AMQP transport exception", true, "", ex); } finally { if (Logging.IsEnabled) { Logging.Exit(this, $"{nameof(ProvisioningTransportHandlerAmqp)}.{nameof(RegisterAsync)}"); } } }
public abstract Task OpenConnectionAsync(AmqpClientConnection connection, TimeSpan timeout, bool useWebSocket, IWebProxy proxy, RemoteCertificateValidationCallback remoteCertificateValidationCallback);
public abstract Task OpenConnectionAsync( AmqpClientConnection connection, bool useWebSocket, IWebProxy proxy, RemoteCertificateValidationCallback remoteCertificateValidationCallback, CancellationToken cancellationToken);
public abstract Task OpenConnectionAsync(AmqpClientConnection connection, TimeSpan timeout, bool useWebSocket, IWebProxy proxy);
public override Task OpenConnectionAsync(AmqpClientConnection connection, TimeSpan timeout, bool useWebSocket, IWebProxy proxy) { X509Certificate2 clientCert = _security.GetAuthenticationCertificate(); return(connection.OpenAsync(timeout, useWebSocket, clientCert, _security.CertificateValidationCallback, proxy)); }
/// <summary> /// Registers a device described by the message. /// </summary> /// <param name="message">The provisioning message.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The registration result.</returns> public override async Task <DeviceRegistrationResult> RegisterAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, $"{nameof(ProvisioningTransportHandlerAmqp)}.{nameof(RegisterAsync)}"); } if (message == null) { throw new ArgumentNullException(nameof(message)); } cancellationToken.ThrowIfCancellationRequested(); try { AmqpAuthStrategy authStrategy; if (message.Security is SecurityProviderTpm) { authStrategy = new AmqpAuthStrategyTpm((SecurityProviderTpm)message.Security); } else if (message.Security is SecurityProviderX509) { authStrategy = new AmqpAuthStrategyX509((SecurityProviderX509)message.Security); } else if (message.Security is SecurityProviderSymmetricKey) { authStrategy = new AmqpAuthStrategySymmetricKey((SecurityProviderSymmetricKey)message.Security); } else { throw new NotSupportedException( $"{nameof(message.Security)} must be of type {nameof(SecurityProviderTpm)}, " + $"{nameof(SecurityProviderX509)} or {nameof(SecurityProviderSymmetricKey)}"); } if (Logging.IsEnabled) { Logging.Associate(authStrategy, this); } bool useWebSocket = (FallbackType == TransportFallbackType.WebSocketOnly); var builder = new UriBuilder() { Scheme = useWebSocket ? WebSocketConstants.Scheme : AmqpConstants.SchemeAmqps, Host = message.GlobalDeviceEndpoint, Port = Port, }; string registrationId = message.Security.GetRegistrationID(); string linkEndpoint = $"{message.IdScope}/registrations/{registrationId}"; using AmqpClientConnection connection = authStrategy.CreateConnection(builder.Uri, message.IdScope); await authStrategy.OpenConnectionAsync(connection, s_timeoutConstant, useWebSocket, Proxy, RemoteCertificateValidationCallback).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await CreateLinksAsync( connection, linkEndpoint, message.ProductInfo).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); string correlationId = Guid.NewGuid().ToString(); DeviceRegistration deviceRegistration = (message.Payload != null && message.Payload.Length > 0) ? new DeviceRegistration { Payload = new JRaw(message.Payload) } : null; RegistrationOperationStatus operation = await RegisterDeviceAsync(connection, correlationId, deviceRegistration).ConfigureAwait(false); // Poll with operationId until registration complete. int attempts = 0; string operationId = operation.OperationId; // Poll with operationId until registration complete. while (string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusAssigning) == 0 || string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusUnassigned) == 0) { cancellationToken.ThrowIfCancellationRequested(); await Task.Delay( operation.RetryAfter ?? RetryJitter.GenerateDelayWithJitterForRetry(s_defaultOperationPoolingInterval), cancellationToken).ConfigureAwait(false); try { operation = await OperationStatusLookupAsync( connection, operationId, correlationId).ConfigureAwait(false); } catch (ProvisioningTransportException e) when(e.ErrorDetails is ProvisioningErrorDetailsAmqp amqp && e.IsTransient) { operation.RetryAfter = amqp.RetryAfter; } attempts++; } if (string.CompareOrdinal(operation.Status, RegistrationOperationStatus.OperationStatusAssigned) == 0) { authStrategy.SaveCredentials(operation); } await connection.CloseAsync(s_timeoutConstant).ConfigureAwait(false); return(ConvertToProvisioningRegistrationResult(operation.RegistrationState)); } catch (Exception ex) when(!(ex is ProvisioningTransportException)) { if (Logging.IsEnabled) { Logging.Error( this, $"{nameof(ProvisioningTransportHandlerAmqp)} threw exception {ex}", nameof(RegisterAsync)); } throw new ProvisioningTransportException($"AMQP transport exception", ex, true); } finally { if (Logging.IsEnabled) { Logging.Exit(this, $"{nameof(ProvisioningTransportHandlerAmqp)}.{nameof(RegisterAsync)}"); } } }
public override Task OpenConnectionAsync(AmqpClientConnection connection, TimeSpan timeout, bool useWebSocket) { X509Certificate2 clientCert = _security.GetAuthenticationCertificate(); return(connection.OpenAsync(timeout, useWebSocket, clientCert)); }
public AmqpClientSession(AmqpClientConnection amqpTestConnection) { _amqpConnection = amqpTestConnection; AmqpSessionSettings = new AmqpSessionSettings(); }
public override Task OpenConnectionAsync(AmqpClientConnection connection, TimeSpan timeout, bool useWebSocket, IWebProxy proxy, RemoteCertificateValidationCallback remoteCertificateValidationCallback) { return(connection.OpenAsync(timeout, useWebSocket, null, proxy, remoteCertificateValidationCallback)); }