From a286bd17233f60a00c527fb7e6b0bb4531a5f525 Mon Sep 17 00:00:00 2001 From: "David R. Williamson" Date: Tue, 2 Jun 2020 13:35:52 -0700 Subject: [PATCH 1/6] fix(adt): fix BasicDigitalTwin and use in an example --- .../Azure.DigitalTwins.Core.netstandard2.0.cs | 16 +++-- .../ComponentSamples.cs | 61 ++++++++++++------- .../DigitalTwinsLifecycleSamples.cs | 4 -- .../ModelLifecycleSamples.cs | 2 +- .../PublishTelemetrySamples.cs | 2 +- .../SamplesConstants.cs | 2 +- .../Azure.DigitalTwins.Core/samples/Readme.md | 37 ++++++++--- .../src/DigitalTwinsClient.cs | 49 ++++++++++----- .../src/Serialization/BasicDigitalTwin.cs | 39 +++++++----- .../src/Serialization/DigitalTwinMetadata.cs | 5 +- .../src/Serialization/ModelProperties.cs | 26 ++++++++ .../Serialization/UpdateOperationsUtility.cs | 14 ++++- .../src/Serialization/WritableProperty.cs | 2 +- 13 files changed, 181 insertions(+), 78 deletions(-) create mode 100644 sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs index cfade0ca518ce..2e45f3395b5e8 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs @@ -122,15 +122,11 @@ public static partial class QueryChargeHelper } namespace Azure.DigitalTwins.Core.Serialization { - public partial class BasicDigitalTwin + public partial class BasicDigitalTwin : Azure.DigitalTwins.Core.Serialization.ModelProperties { public BasicDigitalTwin() { } - [System.Text.Json.Serialization.JsonExtensionDataAttribute] - public System.Collections.Generic.IDictionary CustomProperties { get { throw null; } set { } } [System.Text.Json.Serialization.JsonPropertyNameAttribute("$dtId")] public string Id { get { throw null; } set { } } - [System.Text.Json.Serialization.JsonPropertyNameAttribute("$metadata")] - public Azure.DigitalTwins.Core.Serialization.DigitalTwinMetadata Metadata { get { throw null; } set { } } } public partial class BasicRelationship { @@ -152,7 +148,15 @@ public DigitalTwinMetadata() { } [System.Text.Json.Serialization.JsonPropertyNameAttribute("$model")] public string ModelId { get { throw null; } set { } } [System.Text.Json.Serialization.JsonExtensionDataAttribute] - public System.Collections.Generic.IDictionary ModelProperties { get { throw null; } set { } } + public System.Collections.Generic.IDictionary WriteableProperties { get { throw null; } set { } } + } + public partial class ModelProperties + { + public ModelProperties() { } + [System.Text.Json.Serialization.JsonExtensionDataAttribute] + public System.Collections.Generic.IDictionary CustomProperties { get { throw null; } set { } } + [System.Text.Json.Serialization.JsonPropertyNameAttribute("$metadata")] + public Azure.DigitalTwins.Core.Serialization.DigitalTwinMetadata Metadata { get { throw null; } set { } } } public partial class UpdateOperationsUtility { diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs index 63a47a116a288..38d757db321e7 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; +using System.Text.Json; using System.Threading.Tasks; using Azure.DigitalTwins.Core.Serialization; using static Azure.DigitalTwins.Core.Samples.SampleLogger; @@ -30,54 +32,69 @@ public async Task RunSamplesAsync() string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, DigitalTwinsClient).ConfigureAwait(false); string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, DigitalTwinsClient).ConfigureAwait(false); - string twinId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false); + string dtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); - string newModelPayload = SamplesConstants.TemporaryModelPayload + string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); // Then we create models - await DigitalTwinsClient.CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }).ConfigureAwait(false); - Console.WriteLine($"Successfully created models with Ids: {componentModelId}, {modelId}"); + Response> createModelsResponse = await DigitalTwinsClient + .CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }) + .ConfigureAwait(false); + Console.WriteLine($"Successfully created models Ids {componentModelId} and {modelId} with response {createModelsResponse.GetRawResponse().Status}."); - // Create digital twin with Component payload - string twinPayload = SamplesConstants.TemporaryTwinPayload - .Replace(SamplesConstants.ModelId, modelId) - .Replace(SamplesConstants.ComponentId, componentModelId); + #region Snippet:DigitalTwinsSampleCreateBasicTwin - await DigitalTwinsClient.CreateDigitalTwinAsync(twinId, twinPayload).ConfigureAwait(false); - Console.WriteLine($"Created digital twin {twinId}."); + // Create digital twin with Component payload using the BasicDigitalTwin serialization helper - #region Snippet:DigitalTwinsSampleUpdateComponent + var basicDigitalTwin = new BasicDigitalTwin(); + basicDigitalTwin.Metadata.ModelId = modelId; + basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); + basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + + var componentMetadata = new ModelProperties(); + componentMetadata.Metadata.ModelId = componentModelId; + componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); + componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); - // Update Component with replacing property value - string propertyPath = "/ComponentProp1"; - string propValue = "New Value"; + basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + + Response createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); + Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); + + #endregion Snippet:DigitalTwinsSampleCreateBasicTwin + + #region Snippet:DigitalTwinsSampleUpdateComponent + + // Update Component1 by replacing the property ComponentProp1 value var componentUpdateUtility = new UpdateOperationsUtility(); - componentUpdateUtility.AppendReplaceOp(propertyPath, propValue); + componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); + string updatePayload = componentUpdateUtility.Serialize(); - Response response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize()); + Response response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); - #endregion Snippet:DigitalTwinsSampleUpdateComponent + Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); - Console.WriteLine($"Updated component for digital twin {twinId}. Update response status: {response.GetRawResponse().Status}"); + #endregion Snippet:DigitalTwinsSampleUpdateComponent // Get Component #region Snippet:DigitalTwinsSampleGetComponent - response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false); - - #endregion Snippet:DigitalTwinsSampleGetComponent + response = await DigitalTwinsClient.GetComponentAsync(dtId, SamplesConstants.ComponentPath).ConfigureAwait(false); Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}"); + #endregion Snippet:DigitalTwinsSampleGetComponent + // Now delete a Twin - await DigitalTwinsClient.DeleteDigitalTwinAsync(twinId).ConfigureAwait(false); + await DigitalTwinsClient.DeleteDigitalTwinAsync(dtId).ConfigureAwait(false); // Delete models try diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs index 3814ed0b35bb5..6f42947f0149f 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs @@ -263,12 +263,8 @@ public async Task CreateAllTwinsAsync() { try { - #region Snippet:DigitalTwinsSampleCreateTwin - Response response = await DigitalTwinsClient.CreateDigitalTwinAsync(twin.Key, twin.Value).ConfigureAwait(false); - #endregion Snippet:DigitalTwinsSampleCreateTwin - Console.WriteLine($"Created digital twin {twin.Key}. Create response status: {response.GetRawResponse().Status}"); Console.WriteLine($"Body: {response?.Value}"); } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs index 6e02428cc3c2e..20edf7e6d6c49 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs @@ -39,7 +39,7 @@ public async Task RunSamplesAsync() string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, newComponentModelId); - string newModelPayload = SamplesConstants.TemporaryModelPayload + string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, sampleModelId) .Replace(SamplesConstants.ComponentId, newComponentModelId); diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs index 7314aea31ce50..3e694e7b9b1d0 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs @@ -40,7 +40,7 @@ public async Task RunSamplesAsync() string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); - string newModelPayload = SamplesConstants.TemporaryModelPayload + string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs index 3cec544fa6c3e..9f8b42ff6e925 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs @@ -53,7 +53,7 @@ public static class SamplesConstants /// /// The application/json description of a temporary model /// - public const string TemporaryModelPayload = @" + public const string TemporaryModelWithComponentPayload = @" { ""@id"": ""MODEL_ID"", ""@type"": ""Interface"", diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md index c93ae7e18cbb8..8f45ecb97e5e7 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md @@ -121,8 +121,25 @@ catch (Exception ex) For Creating Twin you will need to provide Id of a digital Twin such as `myTwin` and the application/json digital twin based on the model created earlier. You can look at sample application/json [here](https://github.com/Azure/azure-sdk-for-net-pr/tree/feature/IoT-ADT/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DTDL/DigitalTwins "DigitalTwin"). -```C# Snippet:DigitalTwinsSampleCreateTwin -Response response = await DigitalTwinsClient.CreateDigitalTwinAsync(twin.Key, twin.Value).ConfigureAwait(false); +```C# Snippet:DigitalTwinsSampleCreateBasicTwin +// Create digital twin with Component payload using the BasicDigitalTwin serialization helper + +var basicDigitalTwin = new BasicDigitalTwin(); +basicDigitalTwin.Metadata.ModelId = modelId; +basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); +basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + +var componentMetadata = new ModelProperties(); +componentMetadata.Metadata.ModelId = componentModelId; +componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); +componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); + +basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + +string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + +Response createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); +Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); ``` ### Query Digital Twin @@ -190,14 +207,14 @@ await DigitalTwinsClient.DeleteDigitalTwinAsync(twin.Key).ConfigureAwait(false); To update a component or in other words to replace, remove and/or add a component property or subproperty within Digital Twin, you would need id of a digital twin, component name and application/json-patch+json operations to be performed on the specified digital twin's component. Here is the sample code on how to do it. ```C# Snippet:DigitalTwinsSampleUpdateComponent -// Update Component with replacing property value -string propertyPath = "/ComponentProp1"; -string propValue = "New Value"; - +// Update Component1 by replacing the property ComponentProp1 value var componentUpdateUtility = new UpdateOperationsUtility(); -componentUpdateUtility.AppendReplaceOp(propertyPath, propValue); +componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); +string updatePayload = componentUpdateUtility.Serialize(); -Response response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize()); +Response response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); + +Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); ``` ### Get Digital Twin Component @@ -205,7 +222,9 @@ Response response = await DigitalTwinsClient.UpdateComponentAsync(twinId Get a component by providing name of a component and id of digital twin it belongs to. ```C# Snippet:DigitalTwinsSampleGetComponent -response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false); +response = await DigitalTwinsClient.GetComponentAsync(dtId, SamplesConstants.ComponentPath).ConfigureAwait(false); + +Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}"); ``` ## Create and list Digital Twin edges diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs index e8bed29036cf9..95377339bab7a 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs @@ -107,8 +107,8 @@ protected DigitalTwinsClient() /// Get a digital twin. /// /// - /// The returned application/json string can always be deserialized into an instance of . - /// It may also be deserialized into custom digital twin types that extend the with additional + /// The returned application/json string can always be deserialized into an instance of . + /// It may also be deserialized into custom digital twin types that extend the with additional /// strongly typed properties provided that you know the definition of the retrieved digital twin prior to deserialization. /// /// The Id of the digital twin. @@ -123,8 +123,8 @@ public virtual Task> GetDigitalTwinAsync(string digitalTwinId, /// Get a digital twin. /// /// - /// The returned application/json string can always be deserialized into an instance of . - /// It may also be deserialized into custom digital twin types that extend the with additional + /// The returned application/json string can always be deserialized into an instance of . + /// It may also be deserialized into custom digital twin types that extend the with additional /// strongly typed properties provided that you know the definition of the retrieved digital twin prior to deserialization. /// /// The Id of the digital twin. @@ -142,10 +142,27 @@ public virtual Response GetDigitalTwin(string digitalTwinId, Cancellatio /// The application/json digital twin to create. /// The cancellation token. /// The created application/json digital twin and the http response. - /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. + /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. /// - /// - /// Response<string> response = await DigitalTwinsClient.CreateDigitalTwinAsync(twin.Key, twin.Value).ConfigureAwait(false); + /// + /// // Create digital twin with Component payload using the BasicDigitalTwin serialization helper + /// + /// var basicDigitalTwin = new BasicDigitalTwin(); + /// basicDigitalTwin.Metadata.ModelId = modelId; + /// basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); + /// basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + /// + /// var componentMetadata = new ModelProperties(); + /// componentMetadata.Metadata.ModelId = componentModelId; + /// componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); + /// componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); + /// + /// basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + /// + /// string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + /// + /// Response<string> createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); + /// Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); /// /// public virtual Task> CreateDigitalTwinAsync(string digitalTwinId, string digitalTwin, CancellationToken cancellationToken = default) @@ -160,7 +177,7 @@ public virtual Task> CreateDigitalTwinAsync(string digitalTwinI /// The application/json digital twin to create. /// The cancellation token. /// The created application/json digital twin and the http response. - /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. + /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. public virtual Response CreateDigitalTwin(string digitalTwinId, string digitalTwin, CancellationToken cancellationToken = default) { return _dtRestClient.Add(digitalTwinId, digitalTwin, cancellationToken); @@ -237,7 +254,9 @@ public virtual Response UpdateDigitalTwin(string digitalTwinId, string d /// Json string representation of the component corresponding to the provided componentPath and the HTTP response. /// /// - /// response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false); + /// response = await DigitalTwinsClient.GetComponentAsync(dtId, SamplesConstants.ComponentPath).ConfigureAwait(false); + /// + /// Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}"); /// /// public virtual Task> GetComponentAsync(string digitalTwinId, string componentPath, CancellationToken cancellationToken = default) @@ -268,14 +287,14 @@ public virtual Response GetComponent(string digitalTwinId, string compon /// The HTTP response. /// /// - /// // Update Component with replacing property value - /// string propertyPath = "/ComponentProp1"; - /// string propValue = "New Value"; - /// + /// // Update Component1 by replacing the property ComponentProp1 value /// var componentUpdateUtility = new UpdateOperationsUtility(); - /// componentUpdateUtility.AppendReplaceOp(propertyPath, propValue); + /// componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); + /// string updatePayload = componentUpdateUtility.Serialize(); + /// + /// Response<string> response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); /// - /// Response<string> response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize()); + /// Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); /// /// public virtual Task> UpdateComponentAsync(string digitalTwinId, string componentPath, string componentUpdateOperations, RequestOptions requestOptions = default, CancellationToken cancellationToken = default) diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs index e6150410131b3..882205d0798ad 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs @@ -1,7 +1,6 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Collections.Generic; using System.Text.Json.Serialization; namespace Azure.DigitalTwins.Core.Serialization @@ -9,24 +8,34 @@ namespace Azure.DigitalTwins.Core.Serialization /// /// An optional, helper class for deserializing a digital twin. /// - public class BasicDigitalTwin + /// + /// + /// // Create digital twin with Component payload using the BasicDigitalTwin serialization helper + /// + /// var basicDigitalTwin = new BasicDigitalTwin(); + /// basicDigitalTwin.Metadata.ModelId = modelId; + /// basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); + /// basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + /// + /// var componentMetadata = new ModelProperties(); + /// componentMetadata.Metadata.ModelId = componentModelId; + /// componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); + /// componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); + /// + /// basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + /// + /// string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + /// + /// Response<string> createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); + /// Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); + /// + /// + public class BasicDigitalTwin : ModelProperties { /// /// The unique Id of the digital twin in a digital twins instance. This field is present on every digital twin. /// [JsonPropertyName("$dtId")] public string Id { get; set; } - - /// - /// Information about the model a digital twin conforms to. This field is present on every digital twin. - /// - [JsonPropertyName("$metadata")] - public DigitalTwinMetadata Metadata { get; set; } - - /// - /// Additional properties of the digital twin. This field will contain any properties of the digital twin that are not already defined by the other strong types of this class. - /// - [JsonExtensionData] - public IDictionary CustomProperties { get; set; } = new Dictionary(); } } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs index 1a7464e4f7445..bf2bbdbc31e2b 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs @@ -8,7 +8,7 @@ namespace Azure.DigitalTwins.Core.Serialization { /// /// An optional, helper class for deserializing a digital twin. - /// The $metadata class on a . + /// The $metadata class on a . /// public class DigitalTwinMetadata { @@ -21,7 +21,8 @@ public class DigitalTwinMetadata /// /// Additional, model-defined properties. /// + /// For your convenience, the value of each dictionary object can be turned into an instance of . [JsonExtensionData] - public IDictionary ModelProperties { get; set; } = new Dictionary(); + public IDictionary WriteableProperties { get; set; } = new Dictionary(); } } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs new file mode 100644 index 0000000000000..8d4102ad12746 --- /dev/null +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Azure.DigitalTwins.Core.Serialization +{ + /// + /// Properties on a digital twin that adhere to a specific model. + /// + public class ModelProperties + { + /// + /// Information about the model a digital twin conforms to. This field is present on every digital twin. + /// + [JsonPropertyName("$metadata")] + public DigitalTwinMetadata Metadata { get; set; } = new DigitalTwinMetadata(); + + /// + /// Additional properties of the digital twin. This field will contain any properties of the digital twin that are not already defined by the other strong types of this class. + /// + [JsonExtensionData] + public IDictionary CustomProperties { get; set; } = new Dictionary(); + } +} diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs index 2109fb680f5b3..a7215b9564738 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; @@ -9,6 +9,18 @@ namespace Azure.DigitalTwins.Core.Serialization /// /// A utility to create the application/json-patch+json operations payload required for update operations. /// + /// + /// + /// // Update Component1 by replacing the property ComponentProp1 value + /// var componentUpdateUtility = new UpdateOperationsUtility(); + /// componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); + /// string updatePayload = componentUpdateUtility.Serialize(); + /// + /// Response<string> response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); + /// + /// Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); + /// + /// public class UpdateOperationsUtility { private const string Op = "op"; diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs index 0aa16611b39a3..541154e0e094c 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs @@ -7,7 +7,7 @@ namespace Azure.DigitalTwins.Core.Serialization { /// /// An optional, helper class for deserializing a digital twin. - /// The ModelProperties dictionary on . + /// The ModelProperties dictionary on . /// /// /// A writable property is one that the service may request a change for from the device. From 0b2fd1ef28a71a6cee16b16b4878106732a87698 Mon Sep 17 00:00:00 2001 From: Basel Rustum Date: Wed, 3 Jun 2020 14:14:34 -0700 Subject: [PATCH 2/6] test(PublishTelemetry): Add E2E test for PublishTelemetry API --- .../tests/EventRouteTests.cs | 5 +- .../tests/PublishTelemetryTests.cs | 133 ++++++++++++++++++ 2 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/EventRouteTests.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/EventRouteTests.cs index 117057cc5055b..f1399cb8698c3 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/EventRouteTests.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/EventRouteTests.cs @@ -1,13 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Net; using System.Threading.Tasks; -using FluentAssertions; using Azure.DigitalTwins.Core.Models; -using System; +using FluentAssertions; using NUnit.Framework; -using Azure.Core.TestFramework; namespace Azure.DigitalTwins.Core.Tests { diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs new file mode 100644 index 0000000000000..d711bbadefdd4 --- /dev/null +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Net; +using System.Text.Json; +using System.Threading.Tasks; +using Azure.DigitalTwins.Core.Models; +using FluentAssertions; +using NUnit.Framework; + +namespace Azure.DigitalTwins.Core.Tests +{ + /// + /// Tests for DigitalTwinsClient APIs that handle publishing telemetry messages to Azure Digital Twins. + /// + public class PublishTelemetryTests : E2eTestBase + { + public PublishTelemetryTests(bool isAsync) + : base(isAsync) + { + } + + // Infrastructure setup script uses this hardcoded value when linking the test eventhub to the test digital twins instance. + private const string EndpointName = "someEventHubEndpoint"; + + [Test] + public async Task PublishTelemetry_Lifecycle() + { + // Setup + + // Create a DigitalTwinsClient instance. + DigitalTwinsClient client = GetClient(); + + string wifiComponentName = "wifiAccessPoint"; + string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.WifiModelIdPrefix).ConfigureAwait(false); + string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.RoomWithWifiModelIdPrefix).ConfigureAwait(false); + string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetSettings.RoomWithWifiTwinIdPrefix).ConfigureAwait(false); + string eventRouteId = $"someEventRouteId-{GetRandom()}"; + + try + { + // Create an event route for the digital twins client. + EventRoute eventRoute = await CreateEventRoute(client, eventRouteId); + + // Create the models needed for the digital twin. + await CreateModelsAndTwins(client, wifiModelId, roomWithWifiModelId, wifiComponentName, roomWithWifiTwinId); + + // Act - Test publishing telemetry to a digital twin. + Response publishTelemetryResponse = await client.PublishTelemetryAsync(roomWithWifiTwinId, "{\"Telemetry1\": 5}"); + + // Assert + publishTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); + + // Act - Test publishing telemetry to a component in a digital twin. + var telemetryPayload = new Dictionary + { + { "ComponentTelemetry1", 9} + }; + Response publishComponentTelemetryResponse = await client.PublishComponentTelemetryAsync(roomWithWifiTwinId, wifiComponentName, JsonSerializer.Serialize(telemetryPayload)); + + // Assert + publishComponentTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); + } + catch (Exception ex) + { + Assert.Fail($"Failure in executing a step in the test case: {ex.Message}."); + } + finally + { + // clean up + try + { + if (!string.IsNullOrWhiteSpace(eventRouteId)) + { + await client.DeleteEventRouteAsync(eventRouteId).ConfigureAwait(false); + } + if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId)) + { + await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false); + } + if (!string.IsNullOrWhiteSpace(roomWithWifiModelId)) + { + await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false); + } + if (!string.IsNullOrWhiteSpace(wifiModelId)) + { + await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false); + } + } + catch (Exception ex) + { + Assert.Fail($"Test clean up failed: {ex.Message}"); + } + } + + } + + private async Task CreateModelsAndTwins(DigitalTwinsClient client, string wifiModelId, string roomWithWifiModelId, string wifiComponentName, string roomWithWifiTwinId) + { + // Generate the payload needed to create the wifi component model. + string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId); + + // Generate the payload needed to create the room with wifi model. + string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName); + + // Create the room and wifi models. + await client.CreateModelsAsync(new List { roomWithWifiModel, wifiModel }).ConfigureAwait(false); + + // Generate the payload needed to create the room with wifi twin. + string roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiModelId, wifiComponentName); + + // Create the room with wifi component digital twin. + await client.CreateDigitalTwinAsync(roomWithWifiTwinId, roomWithWifiTwin); + } + + private async Task CreateEventRoute(DigitalTwinsClient client, string eventRouteId) + { + string filter = "type = 'Microsoft.DigitalTwins.Twin.Create' OR type = 'microsoft.iot.telemetry'"; + var eventRoute = new EventRoute(EndpointName) + { + Filter = filter + }; + + // Create an event route. + Response createEventRouteResponse = await client.CreateEventRouteAsync(eventRouteId, eventRoute).ConfigureAwait(false); + createEventRouteResponse.Status.Should().Be((int)HttpStatusCode.NoContent); + + return eventRoute; + } + } +} From e9c707e72ec374307ffd9742e0fee03db6661ccb Mon Sep 17 00:00:00 2001 From: Basel Rustum Date: Wed, 3 Jun 2020 16:01:58 -0700 Subject: [PATCH 3/6] Add ConfigureAwait for await calls --- .../tests/PublishTelemetryTests.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs index d711bbadefdd4..9fbfe80f15a2f 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs @@ -42,13 +42,13 @@ public async Task PublishTelemetry_Lifecycle() try { // Create an event route for the digital twins client. - EventRoute eventRoute = await CreateEventRoute(client, eventRouteId); + EventRoute eventRoute = await CreateEventRoute(client, eventRouteId).ConfigureAwait(false); // Create the models needed for the digital twin. - await CreateModelsAndTwins(client, wifiModelId, roomWithWifiModelId, wifiComponentName, roomWithWifiTwinId); + await CreateModelsAndTwins(client, wifiModelId, roomWithWifiModelId, wifiComponentName, roomWithWifiTwinId).ConfigureAwait(false); // Act - Test publishing telemetry to a digital twin. - Response publishTelemetryResponse = await client.PublishTelemetryAsync(roomWithWifiTwinId, "{\"Telemetry1\": 5}"); + Response publishTelemetryResponse = await client.PublishTelemetryAsync(roomWithWifiTwinId, "{\"Telemetry1\": 5}").ConfigureAwait(false); // Assert publishTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); @@ -58,7 +58,9 @@ public async Task PublishTelemetry_Lifecycle() { { "ComponentTelemetry1", 9} }; - Response publishComponentTelemetryResponse = await client.PublishComponentTelemetryAsync(roomWithWifiTwinId, wifiComponentName, JsonSerializer.Serialize(telemetryPayload)); + Response publishComponentTelemetryResponse = await client + .PublishComponentTelemetryAsync(roomWithWifiTwinId, wifiComponentName, JsonSerializer.Serialize(telemetryPayload)) + .ConfigureAwait(false); // Assert publishComponentTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); @@ -112,7 +114,7 @@ private async Task CreateModelsAndTwins(DigitalTwinsClient client, string wifiMo string roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiModelId, wifiComponentName); // Create the room with wifi component digital twin. - await client.CreateDigitalTwinAsync(roomWithWifiTwinId, roomWithWifiTwin); + await client.CreateDigitalTwinAsync(roomWithWifiTwinId, roomWithWifiTwin).ConfigureAwait(false); } private async Task CreateEventRoute(DigitalTwinsClient client, string eventRouteId) From 29aacf7e9925c72fe05c33c30099df8482283c3f Mon Sep 17 00:00:00 2001 From: Basel Rustum Date: Wed, 3 Jun 2020 16:25:33 -0700 Subject: [PATCH 4/6] Add recorded sessions --- .../PublishTelemetry_Lifecycle.json | 359 ++++++++++++++++++ .../PublishTelemetry_LifecycleAsync.json | 359 ++++++++++++++++++ 2 files changed, 718 insertions(+) create mode 100644 sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json create mode 100644 sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json new file mode 100644 index 0000000000000..99e91b1137065 --- /dev/null +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json @@ -0,0 +1,359 @@ +{ + "Entries": [ + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifi%3B110425964?includeModelDefinition=true\u0026api-version=2020-05-31-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "5368ed5029d83906476bdee5ac161265", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Content-Length": "212", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "error": { + "code": "ModelNotFound", + "message": "There is no Model(s) available that matches the provided id(s) dtmi:example:wifi;110425964. Check that the Model ID provided is valid by doing a Model_List API call." + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifiroom%3B12875?includeModelDefinition=true\u0026api-version=2020-05-31-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "33f76cd023b0c17758e610c674b7fcdf", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Content-Length": "212", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "error": { + "code": "ModelNotFound", + "message": "There is no Model(s) available that matches the provided id(s) dtmi:example:wifiroom;12875. Check that the Model ID provided is valid by doing a Model_List API call." + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406?api-version=2020-05-31-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "9f239d1389e4b08865c8bf0a77a1e390", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Content-Length": "278", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "error": { + "code": "DigitalTwinNotFound", + "message": "There is no digital twin instance that exists with the ID roomWithWifiTwin623722406. Please verify that the twin id is valid and ensure that the twin is not deleted. See section on querying the twins http://aka.ms/adtv2query." + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/eventroutes/someEventRouteId-1054814687?api-version=2020-05-31-preview", + "RequestMethod": "PUT", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "150", + "Content-Type": "application/json", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "38b47589ca9f92f07f43f673d3b3e105", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "endpointName": "someEventHubEndpoint", + "filter": "type = \u0027Microsoft.DigitalTwins.Twin.Create\u0027 OR type = \u0027microsoft.iot.telemetry\u0027" + }, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models?api-version=2020-05-31-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "1139", + "Content-Type": "application/json; charset=utf-8", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "41750306ec986fe3824b5ab8b6e1442c", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": "[{ \u0022@id\u0022: \u0022dtmi:example:wifiroom;12875\u0022, \u0022@type\u0022: \u0022Interface\u0022, \u0022displayName\u0022: \u0022RoomWithWifi\u0022, \u0022contents\u0022: [ { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Temperature\u0022, \u0022schema\u0022: \u0022double\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Humidity\u0022, \u0022schema\u0022: \u0022double\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022IsOccupied\u0022, \u0022schema\u0022: \u0022boolean\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022EmployeeId\u0022, \u0022schema\u0022: \u0022string\u0022 }, { \u0022@type\u0022: \u0022Component\u0022, \u0022name\u0022: \u0022wifiAccessPoint\u0022, \u0022schema\u0022: \u0022dtmi:example:wifi;110425964\u0022 } ], \u0022@context\u0022: \u0022dtmi:dtdl:context;2\u0022},{ \u0022@id\u0022: \u0022dtmi:example:wifi;110425964\u0022, \u0022@type\u0022: \u0022Interface\u0022, \u0022@context\u0022: \u0022dtmi:dtdl:context;2\u0022, \u0022displayName\u0022: \u0022Wifi\u0022, \u0022contents\u0022: [ { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022RouterName\u0022, \u0022schema\u0022: \u0022string\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Network\u0022, \u0022schema\u0022: \u0022string\u0022 } ]}]", + "StatusCode": 201, + "ResponseHeaders": { + "Content-Length": "317", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:22:36 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;12875\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:22:36.9664992\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;110425964\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:22:36.9666402\u002B00:00\u0022}]" + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406?api-version=2020-05-31-preview", + "RequestMethod": "PUT", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "318", + "Content-Type": "application/json; charset=utf-8", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "872e94366d2ad374330c6446913d9215", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": "{ \u0022$metadata\u0022: { \u0022$model\u0022: \u0022dtmi:example:wifiroom;12875\u0022 }, \u0022Temperature\u0022: 80, \u0022Humidity\u0022: 25, \u0022IsOccupied\u0022: true, \u0022EmployeeId\u0022: \u0022Employee1\u0022, \u0022wifiAccessPoint\u0022: { \u0022$metadata\u0022: { \u0022$model\u0022: \u0022dtmi:example:wifi;110425964\u0022 }, \u0022RouterName\u0022: \u0022Cisco1\u0022, \u0022Network\u0022: \u0022Room1\u0022 }}", + "StatusCode": 200, + "ResponseHeaders": { + "Content-Length": "1002", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:22:36 GMT", + "ETag": "W/\u00229a8f0d45-50e3-420f-967d-3142e66b5ec2\u0022", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "$dtId": "roomWithWifiTwin623722406", + "$etag": "9a8f0d45-50e3-420f-967d-3142e66b5ec2", + "Temperature": 80, + "Humidity": 25, + "IsOccupied": true, + "EmployeeId": "Employee1", + "wifiAccessPoint": { + "RouterName": "Cisco1", + "Network": "Room1", + "$metadata": { + "$model": "dtmi:example:wifi;110425964", + "RouterName": { + "desiredValue": "Cisco1", + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "Network": { + "desiredValue": "Room1", + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + } + } + }, + "$metadata": { + "$model": "dtmi:example:wifiroom;12875", + "Temperature": { + "desiredValue": 80, + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "Humidity": { + "desiredValue": 25, + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "IsOccupied": { + "desiredValue": true, + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "EmployeeId": { + "desiredValue": "Employee1", + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + } + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406/telemetry?api-version=2020-05-31-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "17", + "Content-Type": "application/json", + "dt-id": "7b6ee5d3-2d8f-47e4-8120-3e0c7c96d9cf", + "dt-timestamp": "06/03/20 23:22:37 \u002B00:00", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "9e7004dd4e6e9c469244b5546f38db9e", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": "{\u0022Telemetry1\u0022: 5}", + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406/components/wifiAccessPoint/telemetry?api-version=2020-05-31-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "25", + "Content-Type": "application/json", + "dt-id": "e510dae6-1884-483f-b1e5-95ff8c29563f", + "dt-timestamp": "06/03/20 23:22:38 \u002B00:00", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "3e3cc9fe5a8498da8ea10e8c889ddd45", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "ComponentTelemetry1": 9 + }, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/eventroutes/someEventRouteId-1054814687?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "b1da45b9a570e7be4e92f5e6b82064fa", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "c847c5315300839029d810cc3fba14f5", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifiroom%3B12875?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "299a7066295d592e0a55f0f265f4e06e", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifi%3B110425964?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "c25a143d15556545b457879795f2a893", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + } + ], + "Variables": { + "DIGITALTWINS_URL": "https://barustum-rg3.api.wus2.digitaltwins.azure.net", + "RandomSeed": "1587202902" + } +} \ No newline at end of file diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json new file mode 100644 index 0000000000000..b7d3ff088e360 --- /dev/null +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json @@ -0,0 +1,359 @@ +{ + "Entries": [ + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifi%3B114383368?includeModelDefinition=true\u0026api-version=2020-05-31-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "07acf913de78371345070cd429ae0875", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Content-Length": "212", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:19:06 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "error": { + "code": "ModelNotFound", + "message": "There is no Model(s) available that matches the provided id(s) dtmi:example:wifi;114383368. Check that the Model ID provided is valid by doing a Model_List API call." + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifiroom%3B11112?includeModelDefinition=true\u0026api-version=2020-05-31-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "0ef74c25447cbd80eede9e5b9a61316a", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Content-Length": "212", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:19:11 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "error": { + "code": "ModelNotFound", + "message": "There is no Model(s) available that matches the provided id(s) dtmi:example:wifiroom;11112. Check that the Model ID provided is valid by doing a Model_List API call." + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051?api-version=2020-05-31-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "e4842832754f103f41c686dda9581a30", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Content-Length": "279", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:19:11 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "error": { + "code": "DigitalTwinNotFound", + "message": "There is no digital twin instance that exists with the ID roomWithWifiTwin1651711051. Please verify that the twin id is valid and ensure that the twin is not deleted. See section on querying the twins http://aka.ms/adtv2query." + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/eventroutes/someEventRouteId-87181891?api-version=2020-05-31-preview", + "RequestMethod": "PUT", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "150", + "Content-Type": "application/json", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "231d7543b5964a2c890075dbaaa6db6a", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "endpointName": "someEventHubEndpoint", + "filter": "type = \u0027Microsoft.DigitalTwins.Twin.Create\u0027 OR type = \u0027microsoft.iot.telemetry\u0027" + }, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:12 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models?api-version=2020-05-31-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "1139", + "Content-Type": "application/json; charset=utf-8", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "f1df7bddd605b7d7fe3b7df9e0448583", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": "[{ \u0022@id\u0022: \u0022dtmi:example:wifiroom;11112\u0022, \u0022@type\u0022: \u0022Interface\u0022, \u0022displayName\u0022: \u0022RoomWithWifi\u0022, \u0022contents\u0022: [ { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Temperature\u0022, \u0022schema\u0022: \u0022double\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Humidity\u0022, \u0022schema\u0022: \u0022double\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022IsOccupied\u0022, \u0022schema\u0022: \u0022boolean\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022EmployeeId\u0022, \u0022schema\u0022: \u0022string\u0022 }, { \u0022@type\u0022: \u0022Component\u0022, \u0022name\u0022: \u0022wifiAccessPoint\u0022, \u0022schema\u0022: \u0022dtmi:example:wifi;114383368\u0022 } ], \u0022@context\u0022: \u0022dtmi:dtdl:context;2\u0022},{ \u0022@id\u0022: \u0022dtmi:example:wifi;114383368\u0022, \u0022@type\u0022: \u0022Interface\u0022, \u0022@context\u0022: \u0022dtmi:dtdl:context;2\u0022, \u0022displayName\u0022: \u0022Wifi\u0022, \u0022contents\u0022: [ { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022RouterName\u0022, \u0022schema\u0022: \u0022string\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Network\u0022, \u0022schema\u0022: \u0022string\u0022 } ]}]", + "StatusCode": 201, + "ResponseHeaders": { + "Content-Length": "317", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:19:20 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;11112\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:19:20.1501919\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;114383368\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:19:20.1503535\u002B00:00\u0022}]" + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051?api-version=2020-05-31-preview", + "RequestMethod": "PUT", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "318", + "Content-Type": "application/json; charset=utf-8", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "bb1e572b274c729b579ac574c9349620", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": "{ \u0022$metadata\u0022: { \u0022$model\u0022: \u0022dtmi:example:wifiroom;11112\u0022 }, \u0022Temperature\u0022: 80, \u0022Humidity\u0022: 25, \u0022IsOccupied\u0022: true, \u0022EmployeeId\u0022: \u0022Employee1\u0022, \u0022wifiAccessPoint\u0022: { \u0022$metadata\u0022: { \u0022$model\u0022: \u0022dtmi:example:wifi;114383368\u0022 }, \u0022RouterName\u0022: \u0022Cisco1\u0022, \u0022Network\u0022: \u0022Room1\u0022 }}", + "StatusCode": 200, + "ResponseHeaders": { + "Content-Length": "1003", + "Content-Type": "application/json; charset=utf-8", + "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "ETag": "W/\u002202ae4534-05c3-4518-b4b3-1ad8ca3b6b9d\u0022", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": { + "$dtId": "roomWithWifiTwin1651711051", + "$etag": "02ae4534-05c3-4518-b4b3-1ad8ca3b6b9d", + "Temperature": 80, + "Humidity": 25, + "IsOccupied": true, + "EmployeeId": "Employee1", + "wifiAccessPoint": { + "RouterName": "Cisco1", + "Network": "Room1", + "$metadata": { + "$model": "dtmi:example:wifi;114383368", + "RouterName": { + "desiredValue": "Cisco1", + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "Network": { + "desiredValue": "Room1", + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + } + } + }, + "$metadata": { + "$model": "dtmi:example:wifiroom;11112", + "Temperature": { + "desiredValue": 80, + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "Humidity": { + "desiredValue": 25, + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "IsOccupied": { + "desiredValue": true, + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + }, + "EmployeeId": { + "desiredValue": "Employee1", + "desiredVersion": 1, + "ackVersion": 1, + "ackCode": 200, + "ackDescription": "Auto-Sync" + } + } + } + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051/telemetry?api-version=2020-05-31-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "17", + "Content-Type": "application/json", + "dt-id": "2d80020c-ab51-4509-ab30-ba1d30695331", + "dt-timestamp": "06/03/20 23:19:21 \u002B00:00", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "dccb72ab3e3a6c3d9e66255a38326945", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": "{\u0022Telemetry1\u0022: 5}", + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051/components/wifiAccessPoint/telemetry?api-version=2020-05-31-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Authorization": "Sanitized", + "Content-Length": "25", + "Content-Type": "application/json", + "dt-id": "26030467-a958-47bf-89bc-1be1436f0027", + "dt-timestamp": "06/03/20 23:19:21 \u002B00:00", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "53b0f17a1f87b61ddf6c996b1062edc9", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "ComponentTelemetry1": 9 + }, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/eventroutes/someEventRouteId-87181891?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "6d4d5da4a979ec491ab11ce602413a24", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "d7fa803143838b985515fccda5d25c3c", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifiroom%3B11112?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "dab65c78fbe5d0cba8c439d60236b49e", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:23 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + }, + { + "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/models/dtmi%3Aexample%3Awifi%3B114383368?api-version=2020-05-31-preview", + "RequestMethod": "DELETE", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": [ + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" + ], + "x-ms-client-request-id": "9039743115676145c4c21863ad7b4647", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 204, + "ResponseHeaders": { + "Content-Length": "0", + "Date": "Wed, 03 Jun 2020 23:19:27 GMT", + "Strict-Transport-Security": "max-age=2592000" + }, + "ResponseBody": [] + } + ], + "Variables": { + "DIGITALTWINS_URL": "https://barustum-rg3.api.wus2.digitaltwins.azure.net", + "RandomSeed": "1563569306" + } +} \ No newline at end of file From 76e06210e64bc4b97198f5106cbc249e885372de Mon Sep 17 00:00:00 2001 From: Basel Rustum Date: Wed, 3 Jun 2020 18:34:01 -0700 Subject: [PATCH 5/6] Sanitize a couple of headers for the Publish Telemetry E2E tests --- .../PublishTelemetryRecordedTestSanitizer.cs | 26 +++++++++++++ .../tests/PublishTelemetryTests.cs | 1 + .../PublishTelemetry_Lifecycle.json | 38 +++++++++---------- .../PublishTelemetry_LifecycleAsync.json | 38 +++++++++---------- 4 files changed, 65 insertions(+), 38 deletions(-) create mode 100644 sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs new file mode 100644 index 0000000000000..e73a3e188e836 --- /dev/null +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; +using Azure.Core.TestFramework; + +namespace Azure.DigitalTwins.Core.Tests +{ + public class PublishTelemetryRecordedTestSanitizer : RecordedTestSanitizer + { + public override void SanitizeHeaders(IDictionary headers) + { + string[] keys = new string[] { "dt-id", "dt-timestamp" }; + + foreach (var key in keys) + { + if (headers.ContainsKey(key)) + { + headers[key] = new[] { SanitizeValue }; + } + } + + base.SanitizeHeaders(headers); + } + } +} diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs index 9fbfe80f15a2f..cbd034d1a5501 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs @@ -20,6 +20,7 @@ public class PublishTelemetryTests : E2eTestBase public PublishTelemetryTests(bool isAsync) : base(isAsync) { + Sanitizer = new PublishTelemetryRecordedTestSanitizer(); } // Infrastructure setup script uses this hardcoded value when linking the test eventhub to the test digital twins instance. diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json index 99e91b1137065..866f568d4d596 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json @@ -17,7 +17,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -44,7 +44,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -71,7 +71,7 @@ "ResponseHeaders": { "Content-Length": "278", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -102,7 +102,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:35 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -126,10 +126,10 @@ "ResponseHeaders": { "Content-Length": "317", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:22:36 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, - "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;12875\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:22:36.9664992\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;110425964\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:22:36.9666402\u002B00:00\u0022}]" + "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;12875\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9044138\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;110425964\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9045475\u002B00:00\u0022}]" }, { "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406?api-version=2020-05-31-preview", @@ -150,13 +150,13 @@ "ResponseHeaders": { "Content-Length": "1002", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:22:36 GMT", - "ETag": "W/\u00229a8f0d45-50e3-420f-967d-3142e66b5ec2\u0022", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "ETag": "W/\u0022c1c89a02-c6e8-44d3-9c7a-f8e05f9405be\u0022", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { "$dtId": "roomWithWifiTwin623722406", - "$etag": "9a8f0d45-50e3-420f-967d-3142e66b5ec2", + "$etag": "c1c89a02-c6e8-44d3-9c7a-f8e05f9405be", "Temperature": 80, "Humidity": 25, "IsOccupied": true, @@ -222,8 +222,8 @@ "Authorization": "Sanitized", "Content-Length": "17", "Content-Type": "application/json", - "dt-id": "7b6ee5d3-2d8f-47e4-8120-3e0c7c96d9cf", - "dt-timestamp": "06/03/20 23:22:37 \u002B00:00", + "dt-id": "Sanitized", + "dt-timestamp": "Sanitized", "User-Agent": [ "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" @@ -235,7 +235,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -247,8 +247,8 @@ "Authorization": "Sanitized", "Content-Length": "25", "Content-Type": "application/json", - "dt-id": "e510dae6-1884-483f-b1e5-95ff8c29563f", - "dt-timestamp": "06/03/20 23:22:38 \u002B00:00", + "dt-id": "Sanitized", + "dt-timestamp": "Sanitized", "User-Agent": [ "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" @@ -262,7 +262,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -283,7 +283,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -304,7 +304,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -325,7 +325,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -346,7 +346,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:22:37 GMT", + "Date": "Thu, 04 Jun 2020 01:31:54 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json index b7d3ff088e360..5a4b70b17afea 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json @@ -17,7 +17,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:19:06 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -44,7 +44,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:19:11 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -71,7 +71,7 @@ "ResponseHeaders": { "Content-Length": "279", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:19:11 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -102,7 +102,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:12 GMT", + "Date": "Thu, 04 Jun 2020 01:31:51 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -126,10 +126,10 @@ "ResponseHeaders": { "Content-Length": "317", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:19:20 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, - "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;11112\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:19:20.1501919\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;114383368\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-03T23:19:20.1503535\u002B00:00\u0022}]" + "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;11112\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9059837\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;114383368\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9061117\u002B00:00\u0022}]" }, { "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051?api-version=2020-05-31-preview", @@ -150,13 +150,13 @@ "ResponseHeaders": { "Content-Length": "1003", "Content-Type": "application/json; charset=utf-8", - "Date": "Wed, 03 Jun 2020 23:19:21 GMT", - "ETag": "W/\u002202ae4534-05c3-4518-b4b3-1ad8ca3b6b9d\u0022", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "ETag": "W/\u00226f6523d8-e25a-4e18-9279-23617b8b6096\u0022", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { "$dtId": "roomWithWifiTwin1651711051", - "$etag": "02ae4534-05c3-4518-b4b3-1ad8ca3b6b9d", + "$etag": "6f6523d8-e25a-4e18-9279-23617b8b6096", "Temperature": 80, "Humidity": 25, "IsOccupied": true, @@ -222,8 +222,8 @@ "Authorization": "Sanitized", "Content-Length": "17", "Content-Type": "application/json", - "dt-id": "2d80020c-ab51-4509-ab30-ba1d30695331", - "dt-timestamp": "06/03/20 23:19:21 \u002B00:00", + "dt-id": "Sanitized", + "dt-timestamp": "Sanitized", "User-Agent": [ "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" @@ -235,7 +235,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -247,8 +247,8 @@ "Authorization": "Sanitized", "Content-Length": "25", "Content-Type": "application/json", - "dt-id": "26030467-a958-47bf-89bc-1be1436f0027", - "dt-timestamp": "06/03/20 23:19:21 \u002B00:00", + "dt-id": "Sanitized", + "dt-timestamp": "Sanitized", "User-Agent": [ "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" @@ -262,7 +262,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -283,7 +283,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -304,7 +304,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:21 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -325,7 +325,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:23 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -346,7 +346,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Wed, 03 Jun 2020 23:19:27 GMT", + "Date": "Thu, 04 Jun 2020 01:31:52 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] From b470456469cf988ddc67d05dba0dc5b0c3a9d6f3 Mon Sep 17 00:00:00 2001 From: Basel Rustum Date: Thu, 4 Jun 2020 11:44:59 -0700 Subject: [PATCH 6/6] mock the message id and timestamp instead of sanitizing them --- .../PublishTelemetryRecordedTestSanitizer.cs | 26 ------- .../tests/PublishTelemetryTests.cs | 15 +++- .../PublishTelemetry_Lifecycle.json | 76 +++++++++---------- .../PublishTelemetry_LifecycleAsync.json | 74 +++++++++--------- 4 files changed, 87 insertions(+), 104 deletions(-) delete mode 100644 sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs deleted file mode 100644 index e73a3e188e836..0000000000000 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryRecordedTestSanitizer.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.Collections.Generic; -using Azure.Core.TestFramework; - -namespace Azure.DigitalTwins.Core.Tests -{ - public class PublishTelemetryRecordedTestSanitizer : RecordedTestSanitizer - { - public override void SanitizeHeaders(IDictionary headers) - { - string[] keys = new string[] { "dt-id", "dt-timestamp" }; - - foreach (var key in keys) - { - if (headers.ContainsKey(key)) - { - headers[key] = new[] { SanitizeValue }; - } - } - - base.SanitizeHeaders(headers); - } - } -} diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs index cbd034d1a5501..d54a688cdf9aa 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/PublishTelemetryTests.cs @@ -20,7 +20,6 @@ public class PublishTelemetryTests : E2eTestBase public PublishTelemetryTests(bool isAsync) : base(isAsync) { - Sanitizer = new PublishTelemetryRecordedTestSanitizer(); } // Infrastructure setup script uses this hardcoded value when linking the test eventhub to the test digital twins instance. @@ -49,18 +48,28 @@ public async Task PublishTelemetry_Lifecycle() await CreateModelsAndTwins(client, wifiModelId, roomWithWifiModelId, wifiComponentName, roomWithWifiTwinId).ConfigureAwait(false); // Act - Test publishing telemetry to a digital twin. - Response publishTelemetryResponse = await client.PublishTelemetryAsync(roomWithWifiTwinId, "{\"Telemetry1\": 5}").ConfigureAwait(false); + var telemetryOptions = new TelemetryOptions() + { + MessageId = Recording.Random.NewGuid().ToString(), + TimeStamp = default + }; + Response publishTelemetryResponse = await client.PublishTelemetryAsync(roomWithWifiTwinId, "{\"Telemetry1\": 5}", telemetryOptions).ConfigureAwait(false); // Assert publishTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); // Act - Test publishing telemetry to a component in a digital twin. + var componentTelemetryOptions = new TelemetryOptions() + { + MessageId = Recording.Random.NewGuid().ToString(), + TimeStamp = default + }; var telemetryPayload = new Dictionary { { "ComponentTelemetry1", 9} }; Response publishComponentTelemetryResponse = await client - .PublishComponentTelemetryAsync(roomWithWifiTwinId, wifiComponentName, JsonSerializer.Serialize(telemetryPayload)) + .PublishComponentTelemetryAsync(roomWithWifiTwinId, wifiComponentName, JsonSerializer.Serialize(telemetryPayload), componentTelemetryOptions) .ConfigureAwait(false); // Assert diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json index 866f568d4d596..918bca073c651 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_Lifecycle.json @@ -6,7 +6,7 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "5368ed5029d83906476bdee5ac161265", @@ -17,7 +17,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -33,7 +33,7 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "33f76cd023b0c17758e610c674b7fcdf", @@ -44,7 +44,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -60,7 +60,7 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "9f239d1389e4b08865c8bf0a77a1e390", @@ -71,7 +71,7 @@ "ResponseHeaders": { "Content-Length": "278", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -89,7 +89,7 @@ "Content-Length": "150", "Content-Type": "application/json", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "38b47589ca9f92f07f43f673d3b3e105", @@ -102,7 +102,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -115,7 +115,7 @@ "Content-Length": "1139", "Content-Type": "application/json; charset=utf-8", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "41750306ec986fe3824b5ab8b6e1442c", @@ -124,12 +124,12 @@ "RequestBody": "[{ \u0022@id\u0022: \u0022dtmi:example:wifiroom;12875\u0022, \u0022@type\u0022: \u0022Interface\u0022, \u0022displayName\u0022: \u0022RoomWithWifi\u0022, \u0022contents\u0022: [ { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Temperature\u0022, \u0022schema\u0022: \u0022double\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Humidity\u0022, \u0022schema\u0022: \u0022double\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022IsOccupied\u0022, \u0022schema\u0022: \u0022boolean\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022EmployeeId\u0022, \u0022schema\u0022: \u0022string\u0022 }, { \u0022@type\u0022: \u0022Component\u0022, \u0022name\u0022: \u0022wifiAccessPoint\u0022, \u0022schema\u0022: \u0022dtmi:example:wifi;110425964\u0022 } ], \u0022@context\u0022: \u0022dtmi:dtdl:context;2\u0022},{ \u0022@id\u0022: \u0022dtmi:example:wifi;110425964\u0022, \u0022@type\u0022: \u0022Interface\u0022, \u0022@context\u0022: \u0022dtmi:dtdl:context;2\u0022, \u0022displayName\u0022: \u0022Wifi\u0022, \u0022contents\u0022: [ { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022RouterName\u0022, \u0022schema\u0022: \u0022string\u0022 }, { \u0022@type\u0022: \u0022Property\u0022, \u0022name\u0022: \u0022Network\u0022, \u0022schema\u0022: \u0022string\u0022 } ]}]", "StatusCode": 201, "ResponseHeaders": { - "Content-Length": "317", + "Content-Length": "316", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, - "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;12875\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9044138\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;110425964\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9045475\u002B00:00\u0022}]" + "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;12875\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T18:37:48.2611441\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;110425964\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T18:37:48.261302\u002B00:00\u0022}]" }, { "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin623722406?api-version=2020-05-31-preview", @@ -139,7 +139,7 @@ "Content-Length": "318", "Content-Type": "application/json; charset=utf-8", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "872e94366d2ad374330c6446913d9215", @@ -150,13 +150,13 @@ "ResponseHeaders": { "Content-Length": "1002", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", - "ETag": "W/\u0022c1c89a02-c6e8-44d3-9c7a-f8e05f9405be\u0022", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", + "ETag": "W/\u002260af06fe-a622-4f29-b062-33cd931eeec6\u0022", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { "$dtId": "roomWithWifiTwin623722406", - "$etag": "c1c89a02-c6e8-44d3-9c7a-f8e05f9405be", + "$etag": "60af06fe-a622-4f29-b062-33cd931eeec6", "Temperature": 80, "Humidity": 25, "IsOccupied": true, @@ -222,20 +222,20 @@ "Authorization": "Sanitized", "Content-Length": "17", "Content-Type": "application/json", - "dt-id": "Sanitized", - "dt-timestamp": "Sanitized", + "dt-id": "9e7004dd-4e6e-9c46-9244-b5546f38db9e", + "dt-timestamp": "01/01/01 0:00:00 \u002B00:00", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "9e7004dd4e6e9c469244b5546f38db9e", + "x-ms-client-request-id": "3e3cc9fe5a8498da8ea10e8c889ddd45", "x-ms-return-client-request-id": "true" }, "RequestBody": "{\u0022Telemetry1\u0022: 5}", "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -247,13 +247,13 @@ "Authorization": "Sanitized", "Content-Length": "25", "Content-Type": "application/json", - "dt-id": "Sanitized", - "dt-timestamp": "Sanitized", + "dt-id": "b1da45b9-a570-e7be-4e92-f5e6b82064fa", + "dt-timestamp": "01/01/01 0:00:00 \u002B00:00", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "3e3cc9fe5a8498da8ea10e8c889ddd45", + "x-ms-client-request-id": "c847c5315300839029d810cc3fba14f5", "x-ms-return-client-request-id": "true" }, "RequestBody": { @@ -262,7 +262,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -273,17 +273,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "b1da45b9a570e7be4e92f5e6b82064fa", + "x-ms-client-request-id": "299a7066295d592e0a55f0f265f4e06e", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -294,17 +294,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "c847c5315300839029d810cc3fba14f5", + "x-ms-client-request-id": "c25a143d15556545b457879795f2a893", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -315,17 +315,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "299a7066295d592e0a55f0f265f4e06e", + "x-ms-client-request-id": "477fff7d3a85079c97eebdab629e1d35", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:49 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -336,17 +336,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "c25a143d15556545b457879795f2a893", + "x-ms-client-request-id": "2b8ea1f8515f519f2b357406a196c318", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:54 GMT", + "Date": "Thu, 04 Jun 2020 18:37:49 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json index 5a4b70b17afea..382c407a27ad1 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/tests/SessionRecords/PublishTelemetryTests/PublishTelemetry_LifecycleAsync.json @@ -6,7 +6,7 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "07acf913de78371345070cd429ae0875", @@ -17,7 +17,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:45 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -33,7 +33,7 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "0ef74c25447cbd80eede9e5b9a61316a", @@ -44,7 +44,7 @@ "ResponseHeaders": { "Content-Length": "212", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -60,7 +60,7 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "e4842832754f103f41c686dda9581a30", @@ -71,7 +71,7 @@ "ResponseHeaders": { "Content-Length": "279", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { @@ -89,7 +89,7 @@ "Content-Length": "150", "Content-Type": "application/json", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "231d7543b5964a2c890075dbaaa6db6a", @@ -102,7 +102,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:51 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -115,7 +115,7 @@ "Content-Length": "1139", "Content-Type": "application/json; charset=utf-8", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "f1df7bddd605b7d7fe3b7df9e0448583", @@ -126,10 +126,10 @@ "ResponseHeaders": { "Content-Length": "317", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:46 GMT", "Strict-Transport-Security": "max-age=2592000" }, - "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;11112\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9059837\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;114383368\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T01:31:52.9061117\u002B00:00\u0022}]" + "ResponseBody": "[{\u0022id\u0022:\u0022dtmi:example:wifiroom;11112\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022RoomWithWifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T18:37:47.6220061\u002B00:00\u0022},{\u0022id\u0022:\u0022dtmi:example:wifi;114383368\u0022,\u0022description\u0022:{},\u0022displayName\u0022:{\u0022en\u0022:\u0022Wifi\u0022},\u0022decommissioned\u0022:false,\u0022uploadTime\u0022:\u00222020-06-04T18:37:47.6221849\u002B00:00\u0022}]" }, { "RequestUri": "https://barustum-rg3.api.wus2.digitaltwins.azure.net/digitaltwins/roomWithWifiTwin1651711051?api-version=2020-05-31-preview", @@ -139,7 +139,7 @@ "Content-Length": "318", "Content-Type": "application/json; charset=utf-8", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], "x-ms-client-request-id": "bb1e572b274c729b579ac574c9349620", @@ -150,13 +150,13 @@ "ResponseHeaders": { "Content-Length": "1003", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", - "ETag": "W/\u00226f6523d8-e25a-4e18-9279-23617b8b6096\u0022", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", + "ETag": "W/\u0022f07bd8ed-423f-4e21-be2a-9ab24aacd460\u0022", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": { "$dtId": "roomWithWifiTwin1651711051", - "$etag": "6f6523d8-e25a-4e18-9279-23617b8b6096", + "$etag": "f07bd8ed-423f-4e21-be2a-9ab24aacd460", "Temperature": 80, "Humidity": 25, "IsOccupied": true, @@ -222,20 +222,20 @@ "Authorization": "Sanitized", "Content-Length": "17", "Content-Type": "application/json", - "dt-id": "Sanitized", - "dt-timestamp": "Sanitized", + "dt-id": "dccb72ab-3e3a-6c3d-9e66-255a38326945", + "dt-timestamp": "01/01/01 0:00:00 \u002B00:00", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "dccb72ab3e3a6c3d9e66255a38326945", + "x-ms-client-request-id": "53b0f17a1f87b61ddf6c996b1062edc9", "x-ms-return-client-request-id": "true" }, "RequestBody": "{\u0022Telemetry1\u0022: 5}", "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -247,13 +247,13 @@ "Authorization": "Sanitized", "Content-Length": "25", "Content-Type": "application/json", - "dt-id": "Sanitized", - "dt-timestamp": "Sanitized", + "dt-id": "6d4d5da4-a979-ec49-1ab1-1ce602413a24", + "dt-timestamp": "01/01/01 0:00:00 \u002B00:00", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "53b0f17a1f87b61ddf6c996b1062edc9", + "x-ms-client-request-id": "d7fa803143838b985515fccda5d25c3c", "x-ms-return-client-request-id": "true" }, "RequestBody": { @@ -262,7 +262,7 @@ "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -273,17 +273,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "6d4d5da4a979ec491ab11ce602413a24", + "x-ms-client-request-id": "dab65c78fbe5d0cba8c439d60236b49e", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -294,17 +294,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "d7fa803143838b985515fccda5d25c3c", + "x-ms-client-request-id": "9039743115676145c4c21863ad7b4647", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -315,17 +315,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "dab65c78fbe5d0cba8c439d60236b49e", + "x-ms-client-request-id": "a56ee0555f8a353fb4292fbf0ac2881f", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": [] @@ -336,17 +336,17 @@ "RequestHeaders": { "Authorization": "Sanitized", "User-Agent": [ - "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200603.1", + "azsdk-net-DigitalTwins.Core/1.0.0-dev.20200604.1", "(.NET Core 4.6.28801.04; Microsoft Windows 10.0.18363 )" ], - "x-ms-client-request-id": "9039743115676145c4c21863ad7b4647", + "x-ms-client-request-id": "319b5d61cb9862d416551622e268232c", "x-ms-return-client-request-id": "true" }, "RequestBody": null, "StatusCode": 204, "ResponseHeaders": { "Content-Length": "0", - "Date": "Thu, 04 Jun 2020 01:31:52 GMT", + "Date": "Thu, 04 Jun 2020 18:37:48 GMT", "Strict-Transport-Security": "max-age=2592000" }, "ResponseBody": []