public override Task AbandonAsync(string lockToken, CancellationToken cancellationToken) { var customHeaders = PrepareCustomHeaders( CommonConstants.DeviceBoundPathAbandonTemplate.FormatInvariant(this.deviceId, lockToken), null, CommonConstants.CloudToDeviceOperation); // Even though If-Match is not a customHeader, add it here for convenience customHeaders.Add(HttpRequestHeader.IfMatch.ToString(), lockToken); return(this.HandleTimeoutCancellation(() => this.httpClientHelper.PostAsync( GetRequestUri(this.deviceId, CommonConstants.DeviceBoundPathTemplate + "/{0}/abandon".FormatInvariant(lockToken), null), (Object)null, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, cancellationToken), cancellationToken)); }
public override Task CompleteAsync(string lockToken, CancellationToken cancellationToken) { IDictionary <string, string> customHeaders = PrepareCustomHeaders( CommonConstants.DeviceBoundPathCompleteTemplate.FormatInvariant(_deviceId, lockToken), null, CommonConstants.CloudToDeviceOperation); var eTag = new ETagHolder { ETag = lockToken }; return(_httpClientHelper.DeleteAsync( GetRequestUri(_deviceId, CommonConstants.DeviceBoundPathTemplate + "/{0}".FormatInvariant(lockToken), null), eTag, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, cancellationToken)); }
public async Task GetExceptionCodeAsync_NoContentErrorCode_InvalidErrorCode() { // arrange var httpResponseMessage = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); var exceptionResult = new IoTHubExceptionResult { Message = "" }; httpResponseMessage.Content = new StringContent(JsonConvert.SerializeObject(exceptionResult)); httpResponseMessage.Headers.Add(CommonConstants.HttpErrorCodeName, "DeviceNotFound"); // act ErrorCode errorCode = await ExceptionHandlingHelper.GetExceptionCodeAsync(httpResponseMessage); // assert Assert.AreEqual(ErrorCode.InvalidErrorCode, errorCode); }
protected override Task OnSendEventAsync(IEnumerable <Message> messages) { if (messages == null) { throw Fx.Exception.ArgumentNull("messages"); } var customHeaders = PrepareCustomHeaders(CommonConstants.DeviceEventPathTemplate.FormatInvariant(this.deviceId), string.Empty, CommonConstants.DeviceToCloudOperation); string body = ToJson(messages); return(this.httpClientHelper.PostAsync <string>( GetRequestUri(this.deviceId, CommonConstants.DeviceEventPathTemplate, null), body, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, CancellationToken.None)); }
protected override Task OnCompleteAsync(string lockToken) { var customHeaders = PrepareCustomHeaders( CommonConstants.DeviceBoundPathCompleteTemplate.FormatInvariant(this.deviceId, lockToken), null, CommonConstants.CloudToDeviceOperation); var eTag = new ETagHolder { ETag = lockToken }; return(this.httpClientHelper.DeleteAsync( GetRequestUri(this.deviceId, CommonConstants.DeviceBoundPathTemplate + "/{0}".FormatInvariant(lockToken), null), eTag, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, CancellationToken.None)); }
static async Task <Exception> MapToExceptionAsync( HttpResponseMessage response, IDictionary <HttpStatusCode, Func <HttpResponseMessage, Task <Exception> > > errorMapping) { Func <HttpResponseMessage, Task <Exception> > func; if (!errorMapping.TryGetValue(response.StatusCode, out func)) { return(new IotHubException( await ExceptionHandlingHelper.GetExceptionMessageAsync(response), isTransient: true)); } var mapToExceptionFunc = errorMapping[response.StatusCode]; var exception = mapToExceptionFunc(response); return(await exception); }
internal HttpTransportHandler(IPipelineContext context, IotHubConnectionString iotHubConnectionString, Http1TransportSettings transportSettings, HttpClientHandler httpClientHandler = null) : base(context, transportSettings) { ProductInfo productInfo = context.Get <ProductInfo>(); this.deviceId = iotHubConnectionString.DeviceId; this.moduleId = iotHubConnectionString.ModuleId; this.httpClientHelper = new HttpClientHelper( iotHubConnectionString.HttpsEndpoint, iotHubConnectionString, ExceptionHandlingHelper.GetDefaultErrorMapping(), DefaultOperationTimeout, null, transportSettings.ClientCertificate, httpClientHandler, productInfo, transportSettings.Proxy); }
public override async Task AbandonAsync(string lockToken, CancellationToken cancellationToken) { IDictionary <string, string> customHeaders = PrepareCustomHeaders( CommonConstants.DeviceBoundPathAbandonTemplate.FormatInvariant(_deviceId, lockToken), null, CommonConstants.CloudToDeviceOperation); // Even though If-Match is not a customHeader, add it here for convenience customHeaders.Add(HttpRequestHeader.IfMatch.ToString(), lockToken); await _httpClientHelper .PostAsync( GetRequestUri(_deviceId, CommonConstants.DeviceBoundPathTemplate + "/{0}/abandon".FormatInvariant(lockToken), null), (object)null, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, cancellationToken) .ConfigureAwait(false); }
public override Task SendEventAsync(IEnumerable <Message> messages, CancellationToken cancellationToken) { if (messages == null) { throw Fx.Exception.ArgumentNull(nameof(messages)); } cancellationToken.ThrowIfCancellationRequested(); var customHeaders = PrepareCustomHeaders(CommonConstants.DeviceEventPathTemplate.FormatInvariant(_deviceId), string.Empty, CommonConstants.DeviceToCloudOperation); string body = ToJson(messages); return(_httpClientHelper.PostAsync <string>( GetRequestUri(_deviceId, CommonConstants.DeviceEventPathTemplate, null), body, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, cancellationToken)); }
public override Task RejectAsync(string lockToken, CancellationToken cancellationToken) { var customHeaders = PrepareCustomHeaders( CommonConstants.DeviceBoundPathRejectTemplate.FormatInvariant(this.deviceId, lockToken), null, CommonConstants.CloudToDeviceOperation); var eTag = new ETagHolder { ETag = lockToken }; return(this.HandleTimeoutCancellation(() => this.httpClientHelper.DeleteAsync( GetRequestUri(this.deviceId, CommonConstants.DeviceBoundPathTemplate + "/{0}".FormatInvariant(lockToken), new Dictionary <string, string> { { "reject", null } }), eTag, ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, cancellationToken), cancellationToken)); }
internal HttpTransportHandler( PipelineContext context, IotHubConnectionString iotHubConnectionString, Http1TransportSettings transportSettings, HttpClientHandler httpClientHandler = null, bool isClientPrimaryTransportHandler = false) : base(context, transportSettings) { ProductInfo productInfo = context.ProductInfo; _deviceId = iotHubConnectionString.DeviceId; _moduleId = iotHubConnectionString.ModuleId; _httpClientHelper = new HttpClientHelper( iotHubConnectionString.HttpsEndpoint, iotHubConnectionString, ExceptionHandlingHelper.GetDefaultErrorMapping(), s_defaultOperationTimeout, null, transportSettings.ClientCertificate, httpClientHandler, productInfo, transportSettings.Proxy, isClientPrimaryTransportHandler); }
public override async Task <Message> ReceiveAsync(TimeSpan timeout, CancellationToken cancellationToken) { // Long-polling is not supported if (!TimeSpan.Zero.Equals(timeout)) { throw new ArgumentOutOfRangeException(nameof(timeout), "Http Protocol does not support a non-zero receive timeout"); } cancellationToken.ThrowIfCancellationRequested(); IDictionary <string, string> customHeaders = PrepareCustomHeaders(CommonConstants.DeviceBoundPathTemplate.FormatInvariant(this.deviceId), null, CommonConstants.CloudToDeviceOperation); IDictionary <string, string> queryValueDictionary = new Dictionary <string, string>() { { CustomHeaderConstants.MessageLockTimeout, DefaultOperationTimeout.TotalSeconds.ToString(CultureInfo.InvariantCulture) } }; HttpResponseMessage responseMessage = await this.httpClientHelper.GetAsync <HttpResponseMessage>( GetRequestUri(this.deviceId, CommonConstants.DeviceBoundPathTemplate, queryValueDictionary), ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, true, cancellationToken).ConfigureAwait(false); if (responseMessage == null || responseMessage.StatusCode == HttpStatusCode.NoContent) { return(null); } IEnumerable <string> messageId; responseMessage.Headers.TryGetValues(CustomHeaderConstants.MessageId, out messageId); IEnumerable <string> lockToken; responseMessage.Headers.TryGetValues(HttpResponseHeader.ETag.ToString(), out lockToken); IEnumerable <string> enqueuedTime; responseMessage.Headers.TryGetValues(CustomHeaderConstants.EnqueuedTime, out enqueuedTime); IEnumerable <string> deliveryCountAsStr; responseMessage.Headers.TryGetValues(CustomHeaderConstants.DeliveryCount, out deliveryCountAsStr); IEnumerable <string> expiryTime; responseMessage.Headers.TryGetValues(CustomHeaderConstants.ExpiryTimeUtc, out expiryTime); IEnumerable <string> correlationId; responseMessage.Headers.TryGetValues(CustomHeaderConstants.CorrelationId, out correlationId); IEnumerable <string> sequenceNumber; responseMessage.Headers.TryGetValues(CustomHeaderConstants.SequenceNumber, out sequenceNumber); byte[] byteContent = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false); var message = byteContent != null ? new Message(byteContent) : new Message(); message.MessageId = messageId != null?messageId.First() : null; message.LockToken = lockToken != null?lockToken.First().Trim('\"') : null; if (enqueuedTime != null) { DateTime enqueuedTimeUtc; if (DateTime.TryParse(enqueuedTime.First(), out enqueuedTimeUtc)) { message.EnqueuedTimeUtc = enqueuedTimeUtc; } } if (deliveryCountAsStr != null) { byte deliveryCount; if (byte.TryParse(deliveryCountAsStr.First(), out deliveryCount)) { message.DeliveryCount = deliveryCount; } } if (expiryTime != null) { DateTime absoluteExpiryTime; if (DateTime.TryParse(expiryTime.First(), out absoluteExpiryTime)) { message.ExpiryTimeUtc = absoluteExpiryTime; } } message.CorrelationId = correlationId != null?correlationId.First() : null; message.SequenceNumber = sequenceNumber != null?Convert.ToUInt64(sequenceNumber.First()) : 0; // Read custom headers and map them to properties. foreach (KeyValuePair <string, IEnumerable <string> > keyValue in responseMessage.Headers) { if (keyValue.Key.StartsWith(CustomHeaderConstants.HttpAppPropertyPrefix, StringComparison.OrdinalIgnoreCase)) { message.Properties.Add(keyValue.Key.Substring(CustomHeaderConstants.HttpAppPropertyPrefix.Length), keyValue.Value.First()); } } return(message); }
internal async Task UploadToBlobAsync(string blobName, Stream source, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var fileUploadRequest = new FileUploadRequest() { BlobName = blobName }; var fileUploadResponse = await this.httpClientHelper.PostAsync <FileUploadRequest, FileUploadResponse>( GetRequestUri(this.deviceId, CommonConstants.BlobUploadPathTemplate, null), fileUploadRequest, ExceptionHandlingHelper.GetDefaultErrorMapping(), null, cancellationToken).ConfigureAwait(false); string putString = String.Format( CultureInfo.InvariantCulture, "https://{0}/{1}/{2}{3}", fileUploadResponse.HostName, fileUploadResponse.ContainerName, Uri.EscapeDataString(fileUploadResponse.BlobName), // Pass URL encoded device name and blob name to support special characters fileUploadResponse.SasToken); var notification = new FileUploadNotificationResponse(); try { // 2. Use SAS URI to send data to Azure Storage Blob (PUT) CloudBlockBlob blob = new CloudBlockBlob(new Uri(putString)); var uploadTask = blob.UploadFromStreamAsync(source); await uploadTask.ConfigureAwait(false); notification.CorrelationId = fileUploadResponse.CorrelationId; notification.IsSuccess = uploadTask.IsCompleted; notification.StatusCode = uploadTask.IsCompleted ? 0 : -1; notification.StatusDescription = uploadTask.IsCompleted ? null : "Failed to upload to storage."; // 3. POST to IoTHub with upload status await this.httpClientHelper.PostAsync <FileUploadNotificationResponse>( GetRequestUri(this.deviceId, CommonConstants.BlobUploadStatusPathTemplate + "notifications", null), notification, ExceptionHandlingHelper.GetDefaultErrorMapping(), null, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { throw; } catch (Exception ex) when(!ex.IsFatal()) { // 3. POST to IoTHub with upload status notification.IsSuccess = false; notification.StatusCode = -1; notification.StatusDescription = ex.Message; await this.httpClientHelper.PostAsync <FileUploadNotificationResponse>( GetRequestUri(this.deviceId, CommonConstants.BlobUploadStatusPathTemplate + "notifications/" + fileUploadResponse.CorrelationId, null), notification, ExceptionHandlingHelper.GetDefaultErrorMapping(), null, cancellationToken).ConfigureAwait(false); throw; } }
public override async Task <Message> ReceiveAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); IDictionary <string, string> customHeaders = PrepareCustomHeaders( CommonConstants.DeviceBoundPathTemplate.FormatInvariant(_deviceId), null, CommonConstants.CloudToDeviceOperation); var queryValueDictionary = new Dictionary <string, string> { { CustomHeaderConstants.MessageLockTimeout, s_defaultOperationTimeout.TotalSeconds.ToString(CultureInfo.InvariantCulture) } }; HttpResponseMessage responseMessage = await _httpClientHelper .GetAsync <HttpResponseMessage>( GetRequestUri(_deviceId, CommonConstants.DeviceBoundPathTemplate, queryValueDictionary), ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, true, cancellationToken) .ConfigureAwait(false); if (responseMessage == null || responseMessage.StatusCode == HttpStatusCode.NoContent) { return(null); } byte[] byteContent = await responseMessage.Content .ReadHttpContentAsByteArrayAsync(cancellationToken) .ConfigureAwait(false); Message message = byteContent == null ? new Message() : new Message(byteContent); // Read Http headers and map them to message system properties. foreach (KeyValuePair <string, IEnumerable <string> > header in responseMessage.Headers) { string headerKey = header.Key; if (s_mapHttpHeadersToMessageProperties.ContainsKey(headerKey)) { string messagePropertyKey = s_mapHttpHeadersToMessageProperties[headerKey]; object messagePropertyValue = ConvertToMessageSystemProperty(messagePropertyKey, header.Value); if (messagePropertyValue != null) { message.SystemProperties[messagePropertyKey] = messagePropertyValue; } } } // Read custom headers and map them to properties. foreach (KeyValuePair <string, IEnumerable <string> > keyValue in responseMessage.Headers) { if (keyValue.Key.StartsWith(CustomHeaderConstants.HttpAppPropertyPrefix, StringComparison.OrdinalIgnoreCase)) { message.Properties.Add( keyValue.Key.Substring(CustomHeaderConstants.HttpAppPropertyPrefix.Length), keyValue.Value.First()); } } return(message); }
internal async Task UploadToBlobAsync(String blobName, System.IO.Stream source) { // 1. Construct GET request to get SAS URI for storage account var responseMessage = await this.httpClientHelper.GetAsync <HttpResponseMessage>( GetRequestUri(this.deviceId, CommonConstants.BlobUploadPathTemplate + blobName, null), ExceptionHandlingHelper.GetDefaultErrorMapping(), null, true, CancellationToken.None); if (responseMessage.StatusCode != HttpStatusCode.OK) { throw new HttpRequestException(responseMessage.StatusCode.ToString()); } var stringContent = await responseMessage.Content.ReadAsStringAsync(); var getResponseData = JsonConvert.DeserializeObject <FileUploadGetResponse>(stringContent); string putString = String.Format("https://{0}/{1}/{2}{3}", getResponseData.HostName, getResponseData.ContainerName, getResponseData.BlobName, getResponseData.SasToken); FileUploadNotificationResponse notification = new FileUploadNotificationResponse(); try { // 2. Use SAS URI to send data to Azure Storage Blob (PUT) CloudBlockBlob blob = new CloudBlockBlob(new Uri(putString)); var uploadTask = blob.UploadFromStreamAsync(source); await uploadTask; notification.IsSuccess = uploadTask.IsCompleted; notification.StatusCode = uploadTask.IsCompleted ? 0 : -1; notification.StatusDescription = uploadTask.IsCompleted ? null : "Failed to upload to storage."; // 3. POST to IoTHub with upload status await this.httpClientHelper.PostAsync <FileUploadNotificationResponse>( GetRequestUri(this.deviceId, CommonConstants.BlobUploadPathTemplate + "notifications/" + getResponseData.CorrelationId, null), notification, ExceptionHandlingHelper.GetDefaultErrorMapping(), null, CancellationToken.None); } catch (Exception ex) { // 3. POST to IoTHub with upload status notification.IsSuccess = false; notification.StatusCode = -1; notification.StatusDescription = ex.Message; await this.httpClientHelper.PostAsync <FileUploadNotificationResponse>( GetRequestUri(this.deviceId, CommonConstants.BlobUploadPathTemplate + "notifications/" + getResponseData.CorrelationId, null), notification, ExceptionHandlingHelper.GetDefaultErrorMapping(), null, CancellationToken.None); throw ex; } }
public override async Task <Message> ReceiveAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); IDictionary <string, string> customHeaders = PrepareCustomHeaders(CommonConstants.DeviceBoundPathTemplate.FormatInvariant(_deviceId), null, CommonConstants.CloudToDeviceOperation); IDictionary <string, string> queryValueDictionary = new Dictionary <string, string> { { CustomHeaderConstants.MessageLockTimeout, s_defaultOperationTimeout.TotalSeconds.ToString(CultureInfo.InvariantCulture) } }; HttpResponseMessage responseMessage = await _httpClientHelper .GetAsync <HttpResponseMessage>( GetRequestUri(_deviceId, CommonConstants.DeviceBoundPathTemplate, queryValueDictionary), ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, true, cancellationToken) .ConfigureAwait(false); if (responseMessage == null || responseMessage.StatusCode == HttpStatusCode.NoContent) { return(null); } responseMessage.Headers.TryGetValues(CustomHeaderConstants.MessageId, out IEnumerable <string> messageId); responseMessage.Headers.TryGetValues(HttpResponseHeader.ETag.ToString(), out IEnumerable <string> lockToken); responseMessage.Headers.TryGetValues(CustomHeaderConstants.EnqueuedTime, out IEnumerable <string> enqueuedTime); responseMessage.Headers.TryGetValues(CustomHeaderConstants.DeliveryCount, out IEnumerable <string> deliveryCountAsStr); responseMessage.Headers.TryGetValues(CustomHeaderConstants.ExpiryTimeUtc, out IEnumerable <string> expiryTime); responseMessage.Headers.TryGetValues(CustomHeaderConstants.CorrelationId, out IEnumerable <string> correlationId); responseMessage.Headers.TryGetValues(CustomHeaderConstants.SequenceNumber, out IEnumerable <string> sequenceNumber); byte[] byteContent = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false); Message message = byteContent != null ? new Message(byteContent) : new Message(); message.MessageId = messageId?.First(); message.LockToken = lockToken?.First().Trim('\"'); if (enqueuedTime != null) { if (DateTime.TryParse(enqueuedTime.First(), out DateTime enqueuedTimeUtc)) { message.EnqueuedTimeUtc = enqueuedTimeUtc; } } if (deliveryCountAsStr != null) { if (byte.TryParse(deliveryCountAsStr.First(), out byte deliveryCount)) { message.DeliveryCount = deliveryCount; } } if (expiryTime != null) { if (DateTime.TryParse(expiryTime.First(), out DateTime absoluteExpiryTime)) { message.ExpiryTimeUtc = absoluteExpiryTime; } } message.CorrelationId = correlationId?.First(); message.SequenceNumber = sequenceNumber == null ? 0 : Convert.ToUInt64(sequenceNumber.First(), CultureInfo.InvariantCulture); // Read custom headers and map them to properties. foreach (KeyValuePair <string, IEnumerable <string> > keyValue in responseMessage.Headers) { if (keyValue.Key.StartsWith(CustomHeaderConstants.HttpAppPropertyPrefix, StringComparison.OrdinalIgnoreCase)) { message.Properties.Add(keyValue.Key.Substring(CustomHeaderConstants.HttpAppPropertyPrefix.Length), keyValue.Value.First()); } } return(message); }
protected async override Task <Message> OnReceiveAsync(TimeSpan timeout) { // Long-polling is not supported if (!TimeSpan.Zero.Equals(timeout)) { throw new ArgumentOutOfRangeException("timeout", "Http Protocol does not support a non-zero receive timeout"); } IDictionary <string, string> customHeaders = PrepareCustomHeaders(CommonConstants.DeviceBoundPathTemplate.FormatInvariant(this.deviceId), null, CommonConstants.CloudToDeviceOperation); IDictionary <string, string> queryValueDictionary = new Dictionary <string, string>() { { CustomHeaderConstants.MessageLockTimeout, DefaultOperationTimeout.TotalSeconds.ToString(CultureInfo.InvariantCulture) } }; var responseMessage = await this.httpClientHelper.GetAsync <HttpResponseMessage>( GetRequestUri(this.deviceId, CommonConstants.DeviceBoundPathTemplate, queryValueDictionary), ExceptionHandlingHelper.GetDefaultErrorMapping(), customHeaders, true, CancellationToken.None); if (responseMessage.StatusCode == HttpStatusCode.NoContent) { return(null); } IEnumerable <string> messageId; responseMessage.Headers.TryGetValues(CustomHeaderConstants.MessageId, out messageId); IEnumerable <string> lockToken; responseMessage.Headers.TryGetValues(HttpResponseHeader.ETag.ToString(), out lockToken); IEnumerable <string> enqueuedTime; responseMessage.Headers.TryGetValues(CustomHeaderConstants.EnqueuedTime, out enqueuedTime); IEnumerable <string> deliveryCountAsStr; responseMessage.Headers.TryGetValues(CustomHeaderConstants.DeliveryCount, out deliveryCountAsStr); IEnumerable <string> expiryTime; responseMessage.Headers.TryGetValues(CustomHeaderConstants.ExpiryTimeUtc, out expiryTime); IEnumerable <string> correlationId; responseMessage.Headers.TryGetValues(CustomHeaderConstants.CorrelationId, out correlationId); IEnumerable <string> sequenceNumber; responseMessage.Headers.TryGetValues(CustomHeaderConstants.SequenceNumber, out sequenceNumber); var byteContent = await responseMessage.Content.ReadAsByteArrayAsync(); var message = byteContent != null ? new Message(byteContent) : new Message(); message.MessageId = messageId != null?messageId.First() : null; message.LockToken = lockToken != null?lockToken.First().Trim('\"') : null; if (enqueuedTime != null) { DateTime enqueuedTimeUtc; if (DateTime.TryParse(enqueuedTime.First(), out enqueuedTimeUtc)) { message.EnqueuedTimeUtc = enqueuedTimeUtc; } } if (deliveryCountAsStr != null) { byte deliveryCount; if (byte.TryParse(deliveryCountAsStr.First(), out deliveryCount)) { message.DeliveryCount = deliveryCount; } } if (expiryTime != null) { DateTime absoluteExpiryTime; if (DateTime.TryParse(expiryTime.First(), out absoluteExpiryTime)) { message.ExpiryTimeUtc = absoluteExpiryTime; } } message.CorrelationId = correlationId != null?correlationId.First() : null; message.SequenceNumber = sequenceNumber != null?Convert.ToUInt64(sequenceNumber.First()) : 0; return(message); }