internal static async Task <IndividualEnrollment> CreateOrUpdateAsync( IContractApiHttp contractApiHttp, IndividualEnrollment individualEnrollment, CancellationToken cancellationToken) { /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_001: [The CreateOrUpdateAsync shall throw ArgumentException if the provided individualEnrollment is null.] */ if (individualEnrollment == null) { throw new ArgumentNullException(nameof(individualEnrollment)); } /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_002: [The CreateOrUpdateAsync shall sent the Put HTTP request to create or update the individualEnrollment.] */ ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Put, GetEnrollmentUri(individualEnrollment.RegistrationId), null, JsonConvert.SerializeObject(individualEnrollment), individualEnrollment.ETag, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_003: [The CreateOrUpdateAsync shall return an IndividualEnrollment object created from the body of the HTTP response.] */ return(JsonConvert.DeserializeObject <IndividualEnrollment>(contractApiResponse.Body)); }
internal static async Task <BulkEnrollmentOperationResult> BulkOperationAsync( IContractApiHttp contractApiHttp, BulkOperationMode bulkOperationMode, IEnumerable <IndividualEnrollment> individualEnrollments, CancellationToken cancellationToken) { /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_004: [The BulkOperationAsync shall throw ArgumentException if the provided * individualEnrollments is null or empty.] */ if (!(individualEnrollments ?? throw new ArgumentNullException(nameof(individualEnrollments))).Any()) { throw new ArgumentException($"{nameof(individualEnrollments)} cannot be empty"); } /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_005: [The BulkOperationAsync shall sent the Put HTTP request to run the bulk operation to the collection of the individualEnrollment.] */ ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Post, GetEnrollmentUri(), null, BulkEnrollmentOperation.ToJson(bulkOperationMode, individualEnrollments), null, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_006: [The BulkOperationAsync shall return an BulkEnrollmentOperationResult object created from the body of the HTTP response.] */ return(JsonConvert.DeserializeObject <BulkEnrollmentOperationResult>(contractApiResponse.Body)); }
internal static async Task <DeviceRegistrationState> GetAsync( IContractApiHttp contractApiHttp, string id, CancellationToken cancellationToken) { /* SRS_REGISTRATION_STATUS_MANAGER_28_001: [The GetAsync shall throw ArgumentException if the provided ID is null or empty.] */ ParserUtils.EnsureRegistrationId(id); /* SRS_REGISTRATION_STATUS_MANAGER_28_002: [The GetAsync shall sent the Get HTTP request to get the deviceRegistrationState information.] */ ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Get, GetDeviceRegistrationStatusUri(id), null, null, null, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } /* SRS_REGISTRATION_STATUS_MANAGER_28_003: [The GetAsync shall return a DeviceRegistrationState object created from the body of the HTTP response.] */ return(JsonConvert.DeserializeObject <DeviceRegistrationState>(contractApiResponse.Body)); }
internal static async Task <BulkEnrollmentOperationResult> BulkOperationAsync( IContractApiHttp contractApiHttp, BulkOperationMode bulkOperationMode, IEnumerable <IndividualEnrollment> individualEnrollments, CancellationToken cancellationToken) { if (individualEnrollments == null) { throw new ArgumentNullException(nameof(individualEnrollments)); } if (!individualEnrollments.Any()) { throw new ArgumentException($"{nameof(individualEnrollments)} cannot be empty."); } ContractApiResponse contractApiResponse = await contractApiHttp .RequestAsync( HttpMethod.Post, GetEnrollmentUri(), null, BulkEnrollmentOperation.ToJson(bulkOperationMode, individualEnrollments), null, cancellationToken) .ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } return(JsonConvert.DeserializeObject <BulkEnrollmentOperationResult>(contractApiResponse.Body)); }
internal static async Task <IndividualEnrollment> GetAsync( IContractApiHttp contractApiHttp, string registrationId, CancellationToken cancellationToken) { /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_007: [The GetAsync shall throw ArgumentException if the provided registrationId is null or empty.] */ ParserUtils.EnsureRegistrationId(registrationId); /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_008: [The GetAsync shall sent the Get HTTP request to get the individualEnrollment information.] */ ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Get, GetEnrollmentUri(registrationId), null, null, null, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } /* SRS_INDIVIDUAL_ENROLLMENT_MANAGER_21_009: [The GetAsync shall return an IndividualEnrollment object created from the body of the HTTP response.] */ return(JsonConvert.DeserializeObject <IndividualEnrollment>(contractApiResponse.Body)); }
internal static async Task <EnrollmentGroup> CreateOrUpdateAsync( IContractApiHttp contractApiHttp, EnrollmentGroup enrollmentGroup, CancellationToken cancellationToken) { if (enrollmentGroup == null) { throw new ArgumentNullException(nameof(enrollmentGroup)); } ContractApiResponse contractApiResponse = await contractApiHttp .RequestAsync( HttpMethod.Put, GetEnrollmentUri(enrollmentGroup.EnrollmentGroupId), null, JsonConvert.SerializeObject(enrollmentGroup), enrollmentGroup.ETag, cancellationToken) .ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } return(JsonConvert.DeserializeObject <EnrollmentGroup>(contractApiResponse.Body)); }
internal static async Task <IndividualEnrollment> CreateOrUpdateAsync( IContractApiHttp contractApiHttp, IndividualEnrollment individualEnrollment, CancellationToken cancellationToken) { if (individualEnrollment == null) { throw new ArgumentNullException(nameof(individualEnrollment)); } ContractApiResponse contractApiResponse = await contractApiHttp .RequestAsync( HttpMethod.Put, GetEnrollmentUri(individualEnrollment.RegistrationId), null, JsonConvert.SerializeObject(individualEnrollment), individualEnrollment.ETag, cancellationToken) .ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } return(JsonConvert.DeserializeObject <IndividualEnrollment>(contractApiResponse.Body)); }
internal static async Task <EnrollmentGroup> CreateOrUpdateAsync( IContractApiHttp contractApiHttp, EnrollmentGroup enrollmentGroup, CancellationToken cancellationToken) { /* SRS_ENROLLMENT_GROUP_MANAGER_28_001: [The CreateOrUpdateAsync shall throw ArgumentNullException if the provided enrollmentGroup is null.] */ if (enrollmentGroup == null) { throw new ArgumentNullException(nameof(enrollmentGroup)); } /* SRS_ENROLLMENT_GROUP_MANAGER_28_002: [The CreateOrUpdateAsync shall sent the Put HTTP request to create or update the enrollmentGroup.] */ ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Put, GetEnrollmentUri(enrollmentGroup.EnrollmentGroupId), null, JsonConvert.SerializeObject(enrollmentGroup), enrollmentGroup.ETag, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } /* SRS_ENROLLMENT_GROUP_MANAGER_28_003: [The CreateOrUpdateAsync shall return an enrollmentGroup object created from the body of the HTTP response.] */ return(JsonConvert.DeserializeObject <EnrollmentGroup>(contractApiResponse.Body)); }
internal ProvisioningServiceClientHttpException(ContractApiResponse response, bool isTransient) : base($"{response.ErrorMessage}:{response.Body}", isTransient: isTransient) { Body = response.Body; StatusCode = response.StatusCode; Fields = response.Fields; ErrorMessage = response.ErrorMessage; }
private static void ValidateHttpResponse(ContractApiResponse response) { if (response.StatusCode >= HttpStatusCode.InternalServerError) { throw new ProvisioningServiceClientHttpException(response, isTransient: true); } else if (response.StatusCode >= HttpStatusCode.Ambiguous) { throw new ProvisioningServiceClientHttpException(response, isTransient: false); } }
/// <summary> /// Return the next page of result for the query. /// </summary> /// <returns>The <see cref="QueryResult"/> with the next page of items for the query.</returns> /// <exception cref="IndexOutOfRangeException">if the query does no have more pages to return.</exception> public async Task <QueryResult> NextAsync() { /* SRS_QUERY_21_014: [The next shall throw IndexOutOfRangeException if the hasNext is false.] */ if (!_hasNext) { throw new IndexOutOfRangeException("There are no more pending elements"); } /* SRS_QUERY_21_015: [If the pageSize is not 0, the next shall send the HTTP request with `x-ms-max-item-count=[pageSize]` in the header.] */ IDictionary <string, string> headerParameters = new Dictionary <string, string>(); if (PageSize != 0) { headerParameters.Add(PageSizeHeaderKey, PageSize.ToString(CultureInfo.InvariantCulture)); } /* SRS_QUERY_21_016: [If the continuationToken is not null or empty, the next shall send the HTTP request with `x-ms-continuation=[continuationToken]` in the header.] */ if (!string.IsNullOrWhiteSpace(ContinuationToken)) { headerParameters.Add(ContinuationTokenHeaderKey, ContinuationToken); } /* SRS_QUERY_21_017: [The next shall send a HTTP request with a HTTP verb `POST`.] */ ContractApiResponse httpResponse = await _contractApiHttp.RequestAsync( HttpMethod.Post, _queryPath, headerParameters, _querySpecificationJson, null, _cancellationToken).ConfigureAwait(false); /* SRS_QUERY_21_018: [The next shall create and return a new instance of the QueryResult using the `x-ms-item-type` as type, `x-ms-continuation` as the next continuationToken, and the message body.] */ httpResponse.Fields.TryGetValue(ItemTypeHeaderKey, out string type); httpResponse.Fields.TryGetValue(ContinuationTokenHeaderKey, out string continuationToken); ContinuationToken = continuationToken; /* SRS_QUERY_21_017: [The next shall set hasNext as true if the continuationToken is not null, or false if it is null.] */ _hasNext = (ContinuationToken != null); QueryResult result = new QueryResult(type, httpResponse.Body, ContinuationToken); return(result); }
internal static async Task <AttestationMechanism> GetEnrollmentAttestationAsync( IContractApiHttp contractApiHttp, string registrationId, CancellationToken cancellationToken) { ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Post, GetEnrollmentAttestationUri(registrationId), null, null, null, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } return(JsonConvert.DeserializeObject <AttestationMechanism>(contractApiResponse.Body)); }
internal static async Task <EnrollmentGroup> GetAsync( IContractApiHttp contractApiHttp, string enrollmentGroupId, CancellationToken cancellationToken) { /* SRS_ENROLLMENT_GROUP_MANAGER_28_008: [The GetAsync shall sent the Get HTTP request to get the enrollmentGroup information.] */ ContractApiResponse contractApiResponse = await contractApiHttp.RequestAsync( HttpMethod.Get, GetEnrollmentUri(enrollmentGroupId), null, null, null, cancellationToken).ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } /* SRS_ENROLLMENT_GROUP_MANAGER_28_009: [The GetAsync shall return an EnrollmentGroup object created from the body of the HTTP response.] */ return(JsonConvert.DeserializeObject <EnrollmentGroup>(contractApiResponse.Body)); }
internal static async Task <DeviceRegistrationState> GetAsync( IContractApiHttp contractApiHttp, string id, CancellationToken cancellationToken) { ContractApiResponse contractApiResponse = await contractApiHttp .RequestAsync( HttpMethod.Get, GetDeviceRegistrationStatusUri(id), null, null, null, cancellationToken) .ConfigureAwait(false); if (contractApiResponse.Body == null) { throw new ProvisioningServiceClientHttpException(contractApiResponse, true); } return(JsonConvert.DeserializeObject <DeviceRegistrationState>(contractApiResponse.Body)); }
/// <summary> /// Return the next page of result for the query. /// </summary> /// <returns>The <see cref="QueryResult"/> with the next page of items for the query.</returns> /// <exception cref="IndexOutOfRangeException">if the query does no have more pages to return.</exception> public async Task <QueryResult> NextAsync() { if (!_hasNext) { throw new IndexOutOfRangeException("There are no more pending elements"); } IDictionary <string, string> headerParameters = new Dictionary <string, string>(); if (PageSize != 0) { headerParameters.Add(PageSizeHeaderKey, PageSize.ToString(CultureInfo.InvariantCulture)); } if (!string.IsNullOrWhiteSpace(ContinuationToken)) { headerParameters.Add(ContinuationTokenHeaderKey, ContinuationToken); } ContractApiResponse httpResponse = await _contractApiHttp .RequestAsync( HttpMethod.Post, _queryPath, headerParameters, _querySpecificationJson, null, _cancellationToken) .ConfigureAwait(false); httpResponse.Fields.TryGetValue(ItemTypeHeaderKey, out string type); httpResponse.Fields.TryGetValue(ContinuationTokenHeaderKey, out string continuationToken); ContinuationToken = continuationToken; _hasNext = ContinuationToken != null; var result = new QueryResult(type, httpResponse.Body, ContinuationToken); return(result); }
/// <summary> /// Unified HTTP request API /// </summary> /// <param name="httpMethod">the <see cref="HttpMethod"/> with the HTTP verb.</param> /// <param name="requestUri">the rest API <see cref="Uri"/> with for the requested service.</param> /// <param name="customHeaders">the optional <code>Dictionary</code> with additional header fields. It can be <code>null</code>.</param> /// <param name="body">the <code>string</code> with the message body. It can be <code>null</code> or empty.</param> /// <param name="ifMatch">the optional <code>string</code> with the match condition, normally an eTag. It can be <code>null</code>.</param> /// <param name="cancellationToken">the task cancellation Token.</param> /// <returns>The <see cref="ContractApiResponse"/> with the HTTP response.</returns> /// <exception cref="ProvisioningServiceClientException">if the cancellation was requested.</exception> /// <exception cref="ProvisioningServiceClientTransportException">if there is a error in the HTTP communication /// between client and service.</exception> /// <exception cref="ProvisioningServiceClientHttpException">if the service answer the request with error status.</exception> public async Task <ContractApiResponse> RequestAsync( HttpMethod httpMethod, Uri requestUri, IDictionary <string, string> customHeaders, string body, string ifMatch, CancellationToken cancellationToken) { ContractApiResponse response; using (var msg = new HttpRequestMessage(httpMethod, requestUri)) { if (!string.IsNullOrEmpty(body)) { msg.Content = new StringContent(body, Encoding.UTF8, MediaTypeForDeviceManagementApis); } msg.Headers.Add(HttpRequestHeader.Authorization.ToString(), _authenticationHeaderProvider.GetAuthorizationHeader()); msg.Headers.Add(HttpRequestHeader.UserAgent.ToString(), Utils.GetClientVersion()); if (customHeaders != null) { foreach (var header in customHeaders) { msg.Headers.Add(header.Key, header.Value); } } InsertIfMatch(msg, ifMatch); try { using (HttpResponseMessage httpResponse = await _httpClientObj.SendAsync(msg, cancellationToken).ConfigureAwait(false)) { if (httpResponse == null) { throw new ProvisioningServiceClientTransportException( $"The response message was null when executing operation {httpMethod}."); } response = new ContractApiResponse( await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), httpResponse.StatusCode, httpResponse.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault()), httpResponse.ReasonPhrase); } } catch (AggregateException ex) { var innerExceptions = ex.Flatten().InnerExceptions; if (innerExceptions.Any(e => e is TimeoutException)) { throw new ProvisioningServiceClientTransportException(ex.Message, ex); } throw; } catch (TimeoutException ex) { throw new ProvisioningServiceClientTransportException(ex.Message, ex); } catch (IOException ex) { throw new ProvisioningServiceClientTransportException(ex.Message, ex); } catch (HttpRequestException ex) { throw new ProvisioningServiceClientTransportException(ex.Message, ex); } catch (TaskCanceledException ex) { // Unfortunately TaskCanceledException is thrown when HttpClient times out. if (cancellationToken.IsCancellationRequested) { throw new ProvisioningServiceClientException(ex.Message, ex); } throw new ProvisioningServiceClientTransportException($"The {httpMethod} operation timed out.", ex); } } ValidateHttpResponse(response); return(response); }