private async Task <ITenant> CreateChildTenantAsync(string parentTenantId, string name, Guid?wellKnownChildTenantGuid)
        {
            HttpOperationHeaderResponse <Client.Models.CreateChildTenantHeaders> result =
                await this.TenantService.CreateChildTenantWithHttpMessagesAsync(parentTenantId, name, wellKnownChildTenantGuid).ConfigureAwait(false);

            if (result.Response.StatusCode == HttpStatusCode.NotFound)
            {
                throw new TenantNotFoundException();
            }

            // TODO: How do we determine a duplicate Id?
            // See https://github.com/marain-dotnet/Marain.Tenancy/issues/237
            if (result.Response.StatusCode == HttpStatusCode.Conflict)
            {
                throw new TenantConflictException();
            }

            if (!result.Response.IsSuccessStatusCode)
            {
                throw new InvalidOperationException(result.Response.ReasonPhrase);
            }

            object tenant = await this.TenantService.GetTenantAsync(
                this.TenantMapper.ExtractTenantIdFrom(this.TenantService.BaseUri, result.Headers.Location)).ConfigureAwait(false);

            return(this.TenantMapper.MapTenant(tenant));
        }
        private async Task UpdateDigitalTwinComponentPropertyAsync()
        {
            // Choose a random value to assign to the targetTemperature property in thermostat1 component
            int desiredTargetTemperature = Random.Next(0, 100);

            const string targetTemperaturePropertyName = "targetTemperature";
            var          updateOperation = new UpdateOperationsUtility();

            // First let's take a look at when the property was updated and what was it set to.
            HttpOperationResponse <TemperatureControllerTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await _digitalTwinClient
                                                                                                              .GetDigitalTwinAsync <TemperatureControllerTwin>(_digitalTwinId);

            ThermostatTwin thermostat1 = getDigitalTwinResponse.Body.Thermostat1;

            if (thermostat1 != null)
            {
                // Thermostat1 is present in the TemperatureController twin. We can add/replace the component-level property "targetTemperature"
                double?currentComponentTargetTemperature = getDigitalTwinResponse.Body.Thermostat1.TargetTemperature;
                if (currentComponentTargetTemperature != null)
                {
                    DateTimeOffset targetTemperatureDesiredLastUpdateTime = getDigitalTwinResponse.Body.Thermostat1.Metadata.TargetTemperature.LastUpdateTime;
                    _logger.LogDebug($"The property {targetTemperaturePropertyName} under component {Thermostat1Component} was last updated on `" +
                                     $"{targetTemperatureDesiredLastUpdateTime.ToLocalTime()} `" +
                                     $" with a value of {getDigitalTwinResponse.Body.Thermostat1.Metadata.TargetTemperature.DesiredValue}.");

                    // The property path to be replaced should be prepended with a '/'
                    updateOperation.AppendReplacePropertyOp($"/{Thermostat1Component}/{targetTemperaturePropertyName}", desiredTargetTemperature);
                }
                else
                {
                    _logger.LogDebug($"The property {targetTemperaturePropertyName} under component {Thermostat1Component} `" +
                                     $"was never set on the {_digitalTwinId} digital twin.");

                    // The property path to be added should be prepended with a '/'
                    updateOperation.AppendAddPropertyOp($"/{Thermostat1Component}/{targetTemperaturePropertyName}", desiredTargetTemperature);
                }
            }
            else
            {
                // Thermostat1 is not present in the TemperatureController twin. We will add the component
                var componentProperty = new Dictionary <string, object> {
                    { targetTemperaturePropertyName, desiredTargetTemperature }, { "$metadata", new object() }
                };
                _logger.LogDebug($"The component {Thermostat1Component} does not exist on the {_digitalTwinId} digital twin.");

                // The property path to be replaced should be prepended with a '/'
                updateOperation.AppendAddComponentOp($"/{Thermostat1Component}", componentProperty);
            }

            _logger.LogDebug($"Update the {targetTemperaturePropertyName} property under component {Thermostat1Component} on the {_digitalTwinId} `" +
                             $"digital twin to {desiredTargetTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateDigitalTwinResponse = await _digitalTwinClient
                                                                                               .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {updateDigitalTwinResponse.Response.StatusCode}.");

            // Print the TemperatureController digital twin
            await GetAndPrintDigitalTwinAsync <TemperatureControllerTwin>();
        }
        private async Task UpdateCurrentTemperaturePropertyAsync()
        {
            // Choose a random value to assign to the currentTemperature property
            int currentTemperature = Random.Next(0, 100);

            const string currentTemperaturePropertyName = "currentTemperature";
            var          updateOperation = new UpdateOperationsUtility();

            // First, add the property to the digital twin
            updateOperation.AppendAddPropertyOp($"/{currentTemperaturePropertyName}", currentTemperature);
            _logger.LogDebug($"Add the {currentTemperaturePropertyName} property on the {_digitalTwinId} digital twin " +
                             $"with a value of {currentTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> addPropertyToDigitalTwinResponse = await _digitalTwinClient
                                                                                                      .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {addPropertyToDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();

            // Second, replace the property to a different value
            int newCurrentTemperature = Random.Next(0, 100);

            updateOperation.AppendReplacePropertyOp($"/{currentTemperaturePropertyName}", newCurrentTemperature);
            _logger.LogDebug($"Replace the {currentTemperaturePropertyName} property on the {_digitalTwinId} digital twin " +
                             $"with a value of {newCurrentTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> replacePropertyInDigitalTwinResponse = await _digitalTwinClient
                                                                                                          .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {replacePropertyInDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();

            // Third, remove the currentTemperature property
            updateOperation.AppendRemoveOp($"/{currentTemperaturePropertyName}");
            _logger.LogDebug($"Remove the {currentTemperaturePropertyName} property on the {_digitalTwinId} digital twin.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> removePropertyInDigitalTwinResponse = await _digitalTwinClient
                                                                                                         .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {removePropertyInDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();
        }
Ejemplo n.º 4
0
        public async Task <string> TextFromImageAsync(byte[] data)
        {
            ComputerVisionClient computerVision = new ComputerVisionClient(new ApiKeyServiceClientCredentials("8715a698ede2411b8909589611ad3f6d"), new System.Net.Http.DelegatingHandler[] { });

            computerVision.Endpoint = "https://westcentralus.api.cognitive.microsoft.com";
            HttpOperationHeaderResponse <RecognizeTextInStreamHeaders> res = await computerVision.RecognizeTextInStreamWithHttpMessagesAsync(new MemoryStream(data), TextRecognitionMode.Printed);

            var str = await res.Response.Content.ReadAsStringAsync();

            var       id = res.Headers.OperationLocation;
            const int numberOfCharsInOperationId = 36;

            id = id.Substring(id.Length - numberOfCharsInOperationId);
            TextOperationResult result = await computerVision.GetTextOperationResultAsync(id);

            var r = res.Response.Content.ReadAsStringAsync();

            return(r.ToString());
        }
        private async Task UpdateTargetTemperaturePropertyAsync()
        {
            const string targetTemperaturePropertyName = "targetTemperature";
            var          updateOperation = new UpdateOperationsUtility();

            // Choose a random value to assign to the targetTemperature property
            int desiredTargetTemperature = Random.Next(0, 100);

            // First let's take a look at when the property was updated and what was it set to.
            HttpOperationResponse <ThermostatTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await _digitalTwinClient
                                                                                                   .GetDigitalTwinAsync <ThermostatTwin>(_digitalTwinId);

            double?currentTargetTemperature = getDigitalTwinResponse.Body.TargetTemperature;

            if (currentTargetTemperature != null)
            {
                DateTimeOffset targetTemperatureDesiredLastUpdateTime = getDigitalTwinResponse.Body.Metadata.TargetTemperature.LastUpdateTime;
                _logger.LogDebug($"The property {targetTemperaturePropertyName} was last updated on " +
                                 $"{targetTemperatureDesiredLastUpdateTime.ToLocalTime()} `" +
                                 $" with a value of {getDigitalTwinResponse.Body.Metadata.TargetTemperature.DesiredValue}.");

                // The property path to be replaced should be prepended with a '/'
                updateOperation.AppendReplacePropertyOp($"/{targetTemperaturePropertyName}", desiredTargetTemperature);
            }
            else
            {
                _logger.LogDebug($"The property {targetTemperaturePropertyName} was never set on the ${_digitalTwinId} digital twin.");

                // The property path to be added should be prepended with a '/'
                updateOperation.AppendAddPropertyOp($"/{targetTemperaturePropertyName}", desiredTargetTemperature);
            }

            _logger.LogDebug($"Update the {targetTemperaturePropertyName} property on the " +
                             $"{_digitalTwinId} digital twin to {desiredTargetTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateDigitalTwinResponse = await _digitalTwinClient
                                                                                               .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {updateDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Send a request to start a new workflow instance into the workflow engine
        /// </summary>
        /// <param name='tenantId'>
        /// The tenant within which the request should operate
        /// </param>
        /// <param name='body'>
        /// Details of the new workflow instance to be started
        /// </param>
        /// <param name='customHeaders'>
        /// Headers that will be added to request.
        /// </param>
        /// <param name='cancellationToken'>
        /// The cancellation token.
        /// </param>
        /// <exception cref="HttpOperationException">
        /// Thrown when the operation returned an invalid status code
        /// </exception>
        /// <exception cref="ValidationException">
        /// Thrown when a required parameter is null
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown when a required parameter is null
        /// </exception>
        /// <return>
        /// A response object containing the response body and response headers.
        /// </return>
        public async Task <HttpOperationHeaderResponse <SendStartNewWorkflowInstanceRequestHeaders> > SendStartNewWorkflowInstanceRequestWithHttpMessagesAsync(string tenantId, StartNewWorkflowInstanceRequest body, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (tenantId == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "tenantId");
            }
            if (body == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "body");
            }
            if (body != null)
            {
                body.Validate();
            }
            // Tracing
            bool   _shouldTrace  = ServiceClientTracing.IsEnabled;
            string _invocationId = null;

            if (_shouldTrace)
            {
                _invocationId = ServiceClientTracing.NextInvocationId.ToString();
                Dictionary <string, object> tracingParameters = new Dictionary <string, object>();
                tracingParameters.Add("tenantId", tenantId);
                tracingParameters.Add("body", body);
                tracingParameters.Add("cancellationToken", cancellationToken);
                ServiceClientTracing.Enter(_invocationId, this, "SendStartNewWorkflowInstanceRequest", tracingParameters);
            }
            // Construct URL
            var _baseUrl = BaseUri.AbsoluteUri;
            var _url     = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "{tenantId}/marain/workflow/messageprocessing/startnewworkflowinstancerequests").ToString();

            _url = _url.Replace("{tenantId}", System.Uri.EscapeDataString(tenantId));
            // Create HTTP transport objects
            var _httpRequest = new HttpRequestMessage();
            HttpResponseMessage _httpResponse = null;

            _httpRequest.Method     = new HttpMethod("POST");
            _httpRequest.RequestUri = new System.Uri(_url);
            // Set Headers


            if (customHeaders != null)
            {
                foreach (var _header in customHeaders)
                {
                    if (_httpRequest.Headers.Contains(_header.Key))
                    {
                        _httpRequest.Headers.Remove(_header.Key);
                    }
                    _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
                }
            }

            // Serialize Request
            string _requestContent = null;

            if (body != null)
            {
                _requestContent      = SafeJsonConvert.SerializeObject(body, SerializationSettings);
                _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8);
                _httpRequest.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
            }
            // Set Credentials
            if (Credentials != null)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
            }
            // Send Request
            if (_shouldTrace)
            {
                ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
            }
            cancellationToken.ThrowIfCancellationRequested();
            _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);

            if (_shouldTrace)
            {
                ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
            }
            HttpStatusCode _statusCode = _httpResponse.StatusCode;

            cancellationToken.ThrowIfCancellationRequested();
            string _responseContent = null;

            if ((int)_statusCode != 202 && (int)_statusCode != 400)
            {
                var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
                if (_httpResponse.Content != null)
                {
                    _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                }
                else
                {
                    _responseContent = string.Empty;
                }
                ex.Request  = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
                ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
                if (_shouldTrace)
                {
                    ServiceClientTracing.Error(_invocationId, ex);
                }
                _httpRequest.Dispose();
                if (_httpResponse != null)
                {
                    _httpResponse.Dispose();
                }
                throw ex;
            }
            // Create Result
            var _result = new HttpOperationHeaderResponse <SendStartNewWorkflowInstanceRequestHeaders>();

            _result.Request  = _httpRequest;
            _result.Response = _httpResponse;
            try
            {
                _result.Headers = _httpResponse.GetHeadersAsJson().ToObject <SendStartNewWorkflowInstanceRequestHeaders>(JsonSerializer.Create(DeserializationSettings));
            }
            catch (JsonException ex)
            {
                _httpRequest.Dispose();
                if (_httpResponse != null)
                {
                    _httpResponse.Dispose();
                }
                throw new SerializationException("Unable to deserialize the headers.", _httpResponse.GetHeadersAsJson().ToString(), ex);
            }
            if (_shouldTrace)
            {
                ServiceClientTracing.Exit(_invocationId, _result);
            }
            return(_result);
        }
        public async Task DigitalTwinWithOnlyRootComponentOperationsAsync()
        {
            // Create a new test device instance.
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string deviceId = testDevice.Id;

            try
            {
                // Create a device client instance over Mqtt, initializing it with the "Thermostat" model which has only a root component.
                var options = new ClientOptions
                {
                    ModelId = ThermostatModelId,
                };
                using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

                // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
                await deviceClient.OpenAsync().ConfigureAwait(false);

                // Perform operations on the digital twin.
                using var digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(s_connectionString);

                // Retrieve the digital twin.
                HttpOperationResponse <ThermostatTwin, DigitalTwinGetHeaders> response =
                    await digitalTwinClient.GetDigitalTwinAsync <ThermostatTwin>(deviceId).ConfigureAwait(false);

                ThermostatTwin twin = response.Body;
                twin.Metadata.ModelId.Should().Be(ThermostatModelId);

                // Set callback handler for receiving root-level twin property updates.
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: DesiredProperty update received: {patch}, {context}");
                    return(Task.FromResult(true));
                }, deviceClient);

                // Update the root-level property "targetTemperature".
                string propertyName  = "targetTemperature";
                double propertyValue = new Random().Next(0, 100);
                var    ops           = new UpdateOperationsUtility();
                ops.AppendAddPropertyOp($"/{propertyName}", propertyValue);
                string patch = ops.Serialize();
                HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateResponse =
                    await digitalTwinClient.UpdateDigitalTwinAsync(deviceId, patch);

                updateResponse.Response.StatusCode.Should().Be(HttpStatusCode.Accepted);

                // Set callback to handle root-level command invocation request.
                int    expectedCommandStatus = 200;
                string commandName           = "getMaxMinReport";
                await deviceClient.SetMethodHandlerAsync(commandName,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithOnlyRootComponentOperationsAsync)}: Digital twin command received: {request.Name}.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the root-level command "getMaxMinReport" on the digital twin.
                DateTimeOffset since   = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(1));
                string         payload = JsonConvert.SerializeObject(since);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> commandResponse =
                    await digitalTwinClient.InvokeCommandAsync(deviceId, commandName, payload).ConfigureAwait(false);

                commandResponse.Body.Status.Should().Be(expectedCommandStatus);
                commandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(commandName));
            }
            finally
            {
                // Delete the device.
                await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
            }
        }
        public async Task DigitalTwinWithComponentOperationsAsync()
        {
            // Create a new test device instance.
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string deviceId = testDevice.Id;

            try
            {
                // Create a device client instance over Mqtt, initializing it with the "TemperatureController" model which has "Thermostat" components.
                var options = new ClientOptions
                {
                    ModelId = TemperatureControllerModelId,
                };
                using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

                // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
                await deviceClient.OpenAsync().ConfigureAwait(false);

                // Perform operations on the digital twin.
                using var digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(s_connectionString);

                // Retrieve the digital twin.
                HttpOperationResponse <TemperatureControllerTwin, DigitalTwinGetHeaders> response =
                    await digitalTwinClient.GetDigitalTwinAsync <TemperatureControllerTwin>(deviceId).ConfigureAwait(false);

                TemperatureControllerTwin twin = response.Body;
                twin.Metadata.ModelId.Should().Be(TemperatureControllerModelId);

                string componentName = "thermostat1";

                // Set callback handler for receiving twin property updates.
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: DesiredProperty update received: {patch}, {context}");
                    return(Task.FromResult(true));
                }, deviceClient);

                // Update the property "targetTemperature" under component "thermostat1" on the digital twin.
                // NOTE: since this is the first operation on the digital twin, the component "thermostat1" doesn't exist on it yet.
                // So we will create a property patch that "adds" a component, and updates the property in it.
                string propertyName   = "targetTemperature";
                double propertyValue  = new Random().Next(0, 100);
                var    propertyValues = new Dictionary <string, object> {
                    { propertyName, propertyValue }
                };

                var ops = new UpdateOperationsUtility();
                ops.AppendAddComponentOp($"/{componentName}", propertyValues);
                string patch = ops.Serialize();
                HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateResponse =
                    await digitalTwinClient.UpdateDigitalTwinAsync(deviceId, patch);

                updateResponse.Response.StatusCode.Should().Be(HttpStatusCode.Accepted);

                // Set callbacks to handle command requests.
                int expectedCommandStatus = 200;

                // Set callback to handle root-level command invocation request.
                string rootCommandName = "reboot";
                await deviceClient.SetMethodHandlerAsync(rootCommandName,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: Digital twin command {request.Name} received.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the root-level command "reboot" on the digital twin.
                int    delay = 1;
                string rootCommandPayload = JsonConvert.SerializeObject(delay);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> rootCommandResponse =
                    await digitalTwinClient.InvokeCommandAsync(deviceId, rootCommandName, rootCommandPayload).ConfigureAwait(false);

                rootCommandResponse.Body.Status.Should().Be(expectedCommandStatus);
                rootCommandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(rootCommandName));

                // Set callback to handle component-level command invocation request.
                // For a component-level command, the command name is in the format "<component-name>*<command-name>".
                string componentCommandName    = "getMaxMinReport";
                string componentCommandNamePnp = $"{componentName}*{componentCommandName}";
                await deviceClient.SetMethodHandlerAsync(componentCommandNamePnp,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: Digital twin command {request.Name} received.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the command "getMaxMinReport" under component "thermostat1" on the digital twin.
                DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(1));
                string         componentCommandPayload = JsonConvert.SerializeObject(since);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> componentCommandResponse =
                    await digitalTwinClient.InvokeComponentCommandAsync(deviceId, componentName, componentCommandName, componentCommandPayload).ConfigureAwait(false);

                componentCommandResponse.Body.Status.Should().Be(expectedCommandStatus);
                componentCommandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(componentCommandNamePnp));
            }
            finally
            {
                // Delete the device.
                await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Updates a digital twin.
        /// </summary>
        /// <param name='id'>
        /// Digital Twin ID.
        /// </param>
        /// <param name='digitalTwinPatch'>
        /// json-patch contents to update.
        /// </param>
        /// <param name='ifMatch'>
        /// </param>
        /// <param name='customHeaders'>
        /// Headers that will be added to request.
        /// </param>
        /// <param name='cancellationToken'>
        /// The cancellation token.
        /// </param>
        /// <exception cref="HttpOperationException">
        /// Thrown when the operation returned an invalid status code
        /// </exception>
        /// <exception cref="ValidationException">
        /// Thrown when a required parameter is null
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown when a required parameter is null
        /// </exception>
        /// <return>
        /// A response object containing the response body and response headers.
        /// </return>
        public async Task <HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> > UpdateDigitalTwinWithHttpMessagesAsync(string id, string digitalTwinPatch, string ifMatch = default(string), Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (id == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "id");
            }
            if (digitalTwinPatch == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "digitalTwinPatch");
            }
            string apiVersion = "2020-09-30";
            // Tracing
            bool   _shouldTrace  = ServiceClientTracing.IsEnabled;
            string _invocationId = null;

            if (_shouldTrace)
            {
                _invocationId = ServiceClientTracing.NextInvocationId.ToString();
                Dictionary <string, object> tracingParameters = new Dictionary <string, object>();
                tracingParameters.Add("id", id);
                tracingParameters.Add("digitalTwinPatch", digitalTwinPatch);
                tracingParameters.Add("ifMatch", ifMatch);
                tracingParameters.Add("apiVersion", apiVersion);
                tracingParameters.Add("cancellationToken", cancellationToken);
                ServiceClientTracing.Enter(_invocationId, this, "UpdateDigitalTwin", tracingParameters);
            }
            // Construct URL
            var _baseUrl = Client.BaseUri.AbsoluteUri;
            var _url     = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "digitaltwins/{id}").ToString();

            _url = _url.Replace("{id}", System.Uri.EscapeDataString(id));
            List <string> _queryParameters = new List <string>();

            if (apiVersion != null)
            {
                _queryParameters.Add(string.Format("api-version={0}", System.Uri.EscapeDataString(apiVersion)));
            }
            if (_queryParameters.Count > 0)
            {
                _url += "?" + string.Join("&", _queryParameters);
            }
            // Create HTTP transport objects
            var _httpRequest = new HttpRequestMessage();
            HttpResponseMessage _httpResponse = null;

            _httpRequest.Method     = new HttpMethod("PATCH");
            _httpRequest.RequestUri = new System.Uri(_url);
            // Set Headers
            if (ifMatch != null)
            {
                if (_httpRequest.Headers.Contains("If-Match"))
                {
                    _httpRequest.Headers.Remove("If-Match");
                }
                _httpRequest.Headers.TryAddWithoutValidation("If-Match", ifMatch);
            }


            if (customHeaders != null)
            {
                foreach (var _header in customHeaders)
                {
                    if (_httpRequest.Headers.Contains(_header.Key))
                    {
                        _httpRequest.Headers.Remove(_header.Key);
                    }
                    _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
                }
            }

            // Serialize Request
            string _requestContent = null;

            if (digitalTwinPatch != null)
            {
                _requestContent      = digitalTwinPatch;
                _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8);
                _httpRequest.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
            }
            // Set Credentials
            if (Client.Credentials != null)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
            }
            // Send Request
            if (_shouldTrace)
            {
                ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
            }
            cancellationToken.ThrowIfCancellationRequested();
            _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);

            if (_shouldTrace)
            {
                ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
            }
            HttpStatusCode _statusCode = _httpResponse.StatusCode;

            cancellationToken.ThrowIfCancellationRequested();
            string _responseContent = null;

            if ((int)_statusCode != 202)
            {
                var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
                if (_httpResponse.Content != null)
                {
                    _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                }
                else
                {
                    _responseContent = null;
                }
                ex.Request  = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
                ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
                if (_shouldTrace)
                {
                    ServiceClientTracing.Error(_invocationId, ex);
                }
                _httpRequest.Dispose();
                if (_httpResponse != null)
                {
                    _httpResponse.Dispose();
                }
                throw ex;
            }
            // Create Result
            var _result = new HttpOperationHeaderResponse <DigitalTwinUpdateHeaders>();

            _result.Request  = _httpRequest;
            _result.Response = _httpResponse;
            try
            {
                _result.Headers = _httpResponse.GetHeadersAsJson().ToObject <DigitalTwinUpdateHeaders>(JsonSerializer.Create(Client.DeserializationSettings));
            }
            catch (JsonException ex)
            {
                _httpRequest.Dispose();
                if (_httpResponse != null)
                {
                    _httpResponse.Dispose();
                }
                throw new SerializationException("Unable to deserialize the headers.", _httpResponse.GetHeadersAsJson().ToString(), ex);
            }
            if (_shouldTrace)
            {
                ServiceClientTracing.Exit(_invocationId, _result);
            }
            return(_result);
        }