Beispiel #1
0
        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));
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
        }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        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);
     }
 }
Beispiel #11
0
        /// <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);
        }
Beispiel #12
0
        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));
        }
Beispiel #15
0
        /// <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);
        }
Beispiel #16
0
        /// <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);
        }