diff --git a/.github/workflows/dotnet-ci.yml b/.github/workflows/dotnet-ci.yml
index ede5ecc..9fe1dbf 100644
--- a/.github/workflows/dotnet-ci.yml
+++ b/.github/workflows/dotnet-ci.yml
@@ -8,16 +8,19 @@ on:
branches:
- main
+env:
+ DOTNET_VERSION: 6.0.119
+
jobs:
static_code_analysis:
runs-on: ubuntu-20.04
steps:
- name: Checkout repository and submodules
uses: actions/checkout@v3
- - name: Install .NET 6.0.119
+ - name: Install .NET ${{ env.DOTNET_VERSION }}
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 6.0.119
+ dotnet-version: ${{ env.DOTNET_VERSION }}
global-json-file: cloud_connectors/azure/digital_twins_connector/global.json
- name: Cache NuGet dependencies
uses: actions/cache@v3
@@ -30,7 +33,9 @@ jobs:
- name: Build Digital Twins Connector
run: ./cloud_connectors/azure/digital_twins_connector/build.sh
- name: Build MQTT Connector's Azure Function
- run: dotnet build cloud_connectors/azure/mqtt_connector/azure_function/src/function.csproj
+ run: |
+ dotnet build cloud_connectors/azure/mqtt_connector/azure_function/src/function.csproj -warnaserror
+ dotnet build cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.csproj -warnaserror
- name: Digital Twins Connector Tests
run: dotnet test cloud_connectors/azure/digital_twins_connector/tests/**/*.csproj
- name: MQTT Connector's Azure Function Tests
diff --git a/cloud_connectors/azure/.globalconfig b/cloud_connectors/azure/.globalconfig
new file mode 100644
index 0000000..53317ae
--- /dev/null
+++ b/cloud_connectors/azure/.globalconfig
@@ -0,0 +1,6 @@
+# Global analyzer config for .NET projects
+is_global = true
+
+# The way to address this rule is not well documented and appears to be very complex,
+# so it's left as a suggestion for now
+dotnet_diagnostic.CA1848.severity = suggestion
\ No newline at end of file
diff --git a/cloud_connectors/azure/digital_twins_connector/build.sh b/cloud_connectors/azure/digital_twins_connector/build.sh
index 9b1b69f..8566180 100755
--- a/cloud_connectors/azure/digital_twins_connector/build.sh
+++ b/cloud_connectors/azure/digital_twins_connector/build.sh
@@ -7,6 +7,6 @@
# Set the current directory to the directory of this script.
cd "$(dirname "$0")"
-dotnet build src/core/DigitalTwinsConnector.csproj
-dotnet build src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.csproj
-dotnet build tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.csproj
\ No newline at end of file
+dotnet build src/core/DigitalTwinsConnector.csproj -warnaserror
+dotnet build src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.csproj -warnaserror
+dotnet build tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.csproj -warnaserror
\ No newline at end of file
diff --git a/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.cs b/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.cs
index 181814e..8a321c1 100644
--- a/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.cs
+++ b/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.cs
@@ -28,7 +28,7 @@ public class DigitalTwinsClientWrapper
///
/// the path.
/// Returns true if the path starts with a slash, otherwise false.
- private bool DoesPathStartsWithSlash(string path)
+ private static bool DoesPathStartsWithSlash(string path)
{
return path.StartsWith('/');
}
@@ -56,10 +56,12 @@ public DigitalTwinsClientWrapper(DigitalTwinsClient client, ILoggerthe digital twin instance ID.
/// the property path of a digital twin instance to update.
/// the data used to update a digital twin instance's property.
+ /// Rethrown if the client throws this exception
+ /// Thrown if the data parameter could not be parsed
/// Returns a task for updating a digital twin instance.
public async Task UpdateDigitalTwinAsync(string modelID, string instanceID, string instancePropertyPath, string data)
{
- List dataTypes = new List() { typeof(Double), typeof(Boolean), typeof(Int32) };
+ List dataTypes = new() { typeof(double), typeof(bool), typeof(int) };
var jsonPatchDocument = new JsonPatchDocument();
foreach (Type type in dataTypes)
@@ -73,19 +75,31 @@ public async Task UpdateDigitalTwinAsync(string modelID, string instanceID, stri
{
instancePropertyPath = "$/{instancePropertyPath}";
}
+
// Once we're able to parse the data string to a type
// we append it to the jsonPatchDocument
jsonPatchDocument.AppendAdd(instancePropertyPath, value);
// First UpdateDigitalTwinAsync call may block due to initial authorization.
await _client.UpdateDigitalTwinAsync(instanceID, jsonPatchDocument);
- _logger.LogInformation($"Successfully set instance {instanceID}{instancePropertyPath} based on model {modelID} to {data}");
+ _logger.LogInformation(
+ "Successfully set instance {InstanceID}{InstancePropertyPath} based on model {ModelID} to {Data}",
+ instanceID,
+ instancePropertyPath,
+ modelID,
+ data);
return;
}
catch (RequestFailedException ex)
{
- _logger.LogError($"Cannot set instance {instanceID}{instancePropertyPath} based on model {modelID} to {data} due to {ex.Message}");
- throw ex;
+ _logger.LogError(
+ "Cannot set instance {InstanceID}{InstancePropertyPath} based on model {ModelID} to {Data} due to {Message}",
+ instanceID,
+ instancePropertyPath,
+ modelID,
+ data,
+ ex.Message);
+ throw;
}
// Try to parse string data with the next type if we're unsuccessful.
catch (Exception ex) when (ex is NotSupportedException || ex is ArgumentException || ex is FormatException)
@@ -94,9 +108,13 @@ public async Task UpdateDigitalTwinAsync(string modelID, string instanceID, stri
}
}
- string errorMessage = $"Failed to parse {data}. Cannot set instance {instanceID}{instancePropertyPath} based on model {modelID} to {data}";
- _logger.LogError(errorMessage);
- throw new NotSupportedException(errorMessage);
+ _logger.LogError(
+ "Failed to parse data. Cannot set instance {InstanceID}{InstancePropertyPath} based on model {ModelID} to {Data}",
+ instanceID,
+ instancePropertyPath,
+ modelID,
+ data);
+ throw new NotSupportedException();
}
}
}
diff --git a/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.csproj b/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.csproj
index 6f27d36..4242c4d 100644
--- a/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.csproj
+++ b/cloud_connectors/azure/digital_twins_connector/src/DigitalTwinsClientWrapper/DigitalTwinsClientWrapper.csproj
@@ -3,6 +3,7 @@
net6.0
enable
+ latest-recommended
diff --git a/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnector.csproj b/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnector.csproj
index 88cae81..6ba07ce 100644
--- a/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnector.csproj
+++ b/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnector.csproj
@@ -4,6 +4,7 @@
Exe
net6.0
enable
+ latest-recommended
diff --git a/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnectorService.cs b/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnectorService.cs
index ae6882f..696f7ad 100644
--- a/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnectorService.cs
+++ b/cloud_connectors/azure/digital_twins_connector/src/core/DigitalTwinsConnectorService.cs
@@ -43,7 +43,7 @@ public override async Task UpdateDigitalTwin(UpdateDi
}
catch (Exception ex)
{
- _logger.LogError(ex.Message);
+ _logger.LogError("Error updating digital twin: {ExceptionType}: {Message}", ex.GetType(), ex.Message);
throw;
}
diff --git a/cloud_connectors/azure/digital_twins_connector/src/core/Program.cs b/cloud_connectors/azure/digital_twins_connector/src/core/Program.cs
index 695692e..aabd46e 100644
--- a/cloud_connectors/azure/digital_twins_connector/src/core/Program.cs
+++ b/cloud_connectors/azure/digital_twins_connector/src/core/Program.cs
@@ -29,13 +29,14 @@ static void Main(string[] args)
string adtInstanceUrl = adtInstanceConfig.AzureDigitalTwinsInstanceUrl;
var credential = new DefaultAzureCredential();
- DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
+ DigitalTwinsClient client = new(new Uri(adtInstanceUrl), credential);
ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddSimpleConsole(c =>
{
c.TimestampFormat = "[yyyy-MM-ddTHH:mm::ssZ] ";
c.UseUtcTimestamp = true;
}));
+
loggerFactory.CreateLogger("Main").LogInformation("Started the Azure Digital Twins Connector");
// Instantiate the DigitalTwinClient first before adding it as a service for dependency injection.
diff --git a/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.cs b/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.cs
index 09be11f..bfe43bf 100644
--- a/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.cs
+++ b/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.cs
@@ -23,7 +23,7 @@ public void Setup()
}
[Test]
- public async Task UpdateDigitalTwinAsync_ShouldSucceed()
+ public async Task UpdateDigitalTwinAsyncShouldSucceed()
{
const string modelID = "some-model";
const string instanceID = "some-instance";
@@ -33,7 +33,7 @@ public async Task UpdateDigitalTwinAsync_ShouldSucceed()
}
[Test]
- public void UpdateDigitalTwinAsync_ThrowNotSupported()
+ public void UpdateDigitalTwinAsyncThrowNotSupported()
{
const string modelID = "some-model";
const string instanceID = "some-instance";
diff --git a/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.csproj b/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.csproj
index b0409a1..20b3fec 100644
--- a/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.csproj
+++ b/cloud_connectors/azure/digital_twins_connector/tests/DigitalTwinsClientWrapper.Tests/DigitalTwinsClientWrapper.Tests.csproj
@@ -4,6 +4,7 @@
net6.0
enable
false
+ latest-recommended
diff --git a/cloud_connectors/azure/mqtt_connector/azure_function/src/function.csproj b/cloud_connectors/azure/mqtt_connector/azure_function/src/function.csproj
index 9f0674c..323b768 100644
--- a/cloud_connectors/azure/mqtt_connector/azure_function/src/function.csproj
+++ b/cloud_connectors/azure/mqtt_connector/azure_function/src/function.csproj
@@ -2,6 +2,7 @@
net6.0
v4
+ latest-recommended
diff --git a/cloud_connectors/azure/mqtt_connector/azure_function/src/run.cs b/cloud_connectors/azure/mqtt_connector/azure_function/src/run.cs
index 3fe8523..c2b54fe 100644
--- a/cloud_connectors/azure/mqtt_connector/azure_function/src/run.cs
+++ b/cloud_connectors/azure/mqtt_connector/azure_function/src/run.cs
@@ -4,7 +4,8 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
+using System.Globalization;
+using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Azure;
@@ -19,25 +20,63 @@ namespace Microsoft.ESDV.CloudConnector.Azure {
///
/// This class contains the info to target an Azure Digital Twin instance.
///
- public class DigitalTwinsInstance {
- public string model_id { get; set; }
- public string instance_id { get; set; }
- public string instance_property_path { get; set; }
- public string data { get; set; }
+ public class DigitalTwinsInstance
+ {
+ ///
+ /// The Azure Digital Twins model ID
+ ///
+ [JsonPropertyName("model_id")]
+ public string ModelId { get; set; }
+
+ ///
+ /// The Azure Digital Twins instance ID
+ ///
+ [JsonPropertyName("instance_id")]
+ public string InstanceId { get; set; }
+
+ ///
+ /// The Azure Digital Twins instance property path
+ ///
+ [JsonPropertyName("instance_property_path")]
+ public string InstancePropertyPath { get; set; }
+
+ ///
+ /// The data to synchronize
+ ///
+ [JsonPropertyName("data")]
+ public string Data { get; set; }
}
- public class MQTTConnectorAzureFunction {
+ ///
+ /// Azure function for use with the MQTT connector.
+ /// Reads data from an event grid and forwards it to Azure Digital Twins.
+ ///
+ public class MQTTConnectorAzureFunction
+ {
+ ///
+ /// The logger for this function
+ ///
private readonly ILogger _logger;
+ ///
+ /// The environment variable name for the keyvault settings
+ ///
private const string KEYVAULT_SETTINGS = "KEYVAULT_SETTINGS";
- // Maps a string data type name to its concrete data type.
- private static readonly Dictionary dataTypeNameToConverterMap = new Dictionary {
+ ///
+ /// Maps a string data type name to its concrete data type.
+ ///
+ private static readonly Dictionary dataTypeNameToConverterMap = new()
+ {
{ "int", typeof(int) },
{ "double", typeof(double) },
{ "boolean", typeof(bool) }
};
+ ///
+ /// Create a new MQTTConnectorAzureFunction
+ ///
+ /// The logger to use
public MQTTConnectorAzureFunction(ILogger logger)
{
_logger = logger;
@@ -48,20 +87,25 @@ public MQTTConnectorAzureFunction(ILogger logger)
///
/// the path.
/// Returns true if the path starts with a slash, otherwise false.
- public static bool DoesPathStartsWithSlash(string path) {
+ public static bool DoesPathStartsWithSlash(string path)
+ {
return path.StartsWith('/');
}
///
/// Gets the data type from a data type name.
///
- /// the name of the data type.
+ /// the name of the data type.
+ /// Thrown if the data type is not supported.
/// Returns a task for updating a digital twin instance.
- public Type GetDataTypeFromString(string dataTypeName) {
- if (!dataTypeNameToConverterMap.ContainsKey(dataTypeName)) {
+ public static Type GetDataTypeFromString(string dataTypeName)
+ {
+ if (!dataTypeNameToConverterMap.TryGetValue(dataTypeName, out Type value))
+ {
throw new NotSupportedException($"No conversion for {dataTypeName}");
}
- return dataTypeNameToConverterMap[dataTypeName];
+
+ return value;
}
///
@@ -69,33 +113,38 @@ public Type GetDataTypeFromString(string dataTypeName) {
///
/// the Azure Digital Twins client.
/// the digital twin instance to update.
- /// the name of the data type.
+ /// the name of the data type. Defaults to "double".
/// Returns a task for updating a digital twin instance.
- public async Task UpdateDigitalTwinAsync(DigitalTwinsClient client, DigitalTwinsInstance instance, string dataTypeName = "double") {
- JsonPatchDocument jsonPatchDocument = new JsonPatchDocument();
+ public static async Task UpdateDigitalTwinAsync(DigitalTwinsClient client, DigitalTwinsInstance instance, string dataTypeName = "double")
+ {
+ JsonPatchDocument jsonPatchDocument = new();
- try {
+ try
+ {
// Get the concrete data type of an instance's data based on its string data type name
// then uses that concrete data type to change the data from string to its concrete data type.
Type dataType = GetDataTypeFromString(dataTypeName);
- dynamic convertedDataToType = Convert.ChangeType(instance.data, dataType);
+ dynamic convertedDataToType = Convert.ChangeType(instance.Data, dataType, CultureInfo.InvariantCulture);
- if (!DoesPathStartsWithSlash(instance.instance_property_path))
+ if (!DoesPathStartsWithSlash(instance.InstancePropertyPath))
{
- instance.instance_property_path = $"/{instance.instance_property_path}";
+ instance.InstancePropertyPath = $"/{instance.InstancePropertyPath}";
}
- jsonPatchDocument.AppendAdd(instance.instance_property_path, convertedDataToType);
+ jsonPatchDocument.AppendAdd(instance.InstancePropertyPath, convertedDataToType);
}
- catch (Exception ex) when (ex is NotSupportedException || ex is InvalidCastException || ex is FormatException) {
- throw new NotSupportedException($"Cannot convert {instance.data}. {ex.Message}");
+ catch (Exception ex) when (ex is NotSupportedException || ex is InvalidCastException || ex is FormatException)
+ {
+ throw new NotSupportedException($"Cannot convert {instance.Data}. {ex.Message}");
}
- try {
- await client.UpdateDigitalTwinAsync(instance.instance_id, jsonPatchDocument);
+ try
+ {
+ await client.UpdateDigitalTwinAsync(instance.InstanceId, jsonPatchDocument);
}
- catch(RequestFailedException ex) {
- string errorMessage = @$"Cannot set instance {instance.instance_id}{instance.instance_property_path}
- based on model {instance.model_id} to {instance.data} due to {ex.Message}";
+ catch(RequestFailedException ex)
+ {
+ string errorMessage = @$"Cannot set instance {instance.InstanceId}{instance.InstancePropertyPath}
+ based on model {instance.ModelId} to {instance.Data} due to {ex.Message}";
throw new NotSupportedException(errorMessage);
}
}
@@ -108,18 +157,21 @@ public async Task UpdateDigitalTwinAsync(DigitalTwinsClient client, DigitalTwins
/// An exception is thrown if the Azure Digital Twin client cannot update an instance.
///
[FunctionName("MQTTConnectorAzureFunction")]
- public async Task Run([EventGridTrigger] CloudEvent cloudEvent) {
+ public async Task Run([EventGridTrigger] CloudEvent cloudEvent)
+ {
DigitalTwinsInstance instance = cloudEvent.Data.ToObjectFromJson();
- try {
- DefaultAzureCredential credential = new DefaultAzureCredential();
+ try
+ {
+ DefaultAzureCredential credential = new();
string adt_instance_url = Environment.GetEnvironmentVariable(KEYVAULT_SETTINGS, EnvironmentVariableTarget.Process);
- DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adt_instance_url), credential);
+ DigitalTwinsClient client = new(new Uri(adt_instance_url), credential);
await UpdateDigitalTwinAsync(client, instance);
- _logger.LogInformation(@$"Successfully set instance {instance.instance_id}{instance.instance_property_path}
- based on model {instance.model_id} to {instance.data}");
+ _logger.LogInformation(@$"Successfully set instance {instance.InstanceId}{instance.InstancePropertyPath}
+ based on model {instance.ModelId} to {instance.Data}");
}
- catch (Exception ex) {
+ catch (Exception ex)
+ {
_logger.LogError(ex.Message);
throw;
}
diff --git a/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.cs b/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.cs
index 19bde42..5521487 100644
--- a/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.cs
+++ b/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
// SPDX-License-Identifier: MIT
+using System.Text.Json;
using Azure.DigitalTwins.Core;
using Microsoft.Extensions.Logging;
using Moq;
@@ -22,49 +23,67 @@ public void Setup()
_connector = new MQTTConnectorAzureFunction(new Mock>().Object);
_instance = new DigitalTwinsInstance
{
- model_id = "some-model",
- instance_id = "some-instance",
- instance_property_path = "some-instance-property",
- data = null
+ ModelId = "some-model",
+ InstanceId = "some-instance",
+ InstancePropertyPath = "some-instance-property",
+ Data = null
};
}
[Test]
- public void ConvertStringToDataType_ShouldSucceed()
+ public void ConvertStringToDataTypeShouldSucceed()
{
- Assert.That(_connector.GetDataTypeFromString("int"), Is.EqualTo(typeof(int)));
- Assert.That(_connector.GetDataTypeFromString("double"), Is.EqualTo(typeof(double)));
- Assert.That(_connector.GetDataTypeFromString("boolean"), Is.EqualTo(typeof(bool)));
- Assert.Throws(() => _connector.GetDataTypeFromString("invalid-converter"));
+ Assert.Multiple(() =>
+ {
+ Assert.That(MQTTConnectorAzureFunction.GetDataTypeFromString("int"), Is.EqualTo(typeof(int)));
+ Assert.That(MQTTConnectorAzureFunction.GetDataTypeFromString("double"), Is.EqualTo(typeof(double)));
+ Assert.That(MQTTConnectorAzureFunction.GetDataTypeFromString("boolean"), Is.EqualTo(typeof(bool)));
+ });
+ Assert.Throws(() => MQTTConnectorAzureFunction.GetDataTypeFromString("invalid-converter"));
}
[Test]
- public async Task UpdateDigitalTwinAsync_ShouldSucceed()
+ public async Task UpdateDigitalTwinAsyncShouldSucceed()
{
- _instance.data = "44.5";
- await _connector.UpdateDigitalTwinAsync(_client, _instance, "double");
+ _instance.Data = "44.5";
+ await MQTTConnectorAzureFunction.UpdateDigitalTwinAsync(_client, _instance, "double");
Assert.Pass();
- _instance.data = "44";
- await _connector.UpdateDigitalTwinAsync(_client, _instance, "int");
+ _instance.Data = "44";
+ await MQTTConnectorAzureFunction.UpdateDigitalTwinAsync(_client, _instance, "int");
Assert.Pass();
- _instance.data = "true";
- await _connector.UpdateDigitalTwinAsync(_client, _instance, "boolean");
+ _instance.Data = "true";
+ await MQTTConnectorAzureFunction.UpdateDigitalTwinAsync(_client, _instance, "boolean");
Assert.Pass();
}
[Test]
- public void UpdateDigitalTwinAsync_ThrowNotSupported()
+ public void UpdateDigitalTwinAsyncThrowNotSupported()
+ {
+ _instance.Data = null;
+ Assert.ThrowsAsync(async () => await MQTTConnectorAzureFunction.UpdateDigitalTwinAsync(_client, _instance));
+
+ _instance.Data = "test1234";
+ Assert.ThrowsAsync(async () => await MQTTConnectorAzureFunction.UpdateDigitalTwinAsync(_client, _instance, "invalid-converter"));
+
+ _instance.Data = "";
+ Assert.ThrowsAsync(async () => await MQTTConnectorAzureFunction.UpdateDigitalTwinAsync(_client, _instance, "double"));
+ }
+
+ [Test]
+ public void CanDeserializeDigitalTwinsInstance()
{
- _instance.data = null;
- Assert.ThrowsAsync(async () => await _connector.UpdateDigitalTwinAsync(_client, _instance));
+ string input = @"{
+ ""model_id"": ""some-model"",
+ ""instance_id"": ""some-instance"",
+ ""instance_property_path"": ""some-instance-property"",
+ ""data"": ""42""
+ }";
- _instance.data = "test1234";
- Assert.ThrowsAsync(async () => await _connector.UpdateDigitalTwinAsync(_client, _instance, "invalid-converter"));
+ BinaryData data = BinaryData.FromString(input);
- _instance.data = "";
- Assert.ThrowsAsync(async () => await _connector.UpdateDigitalTwinAsync(_client, _instance, "double"));
+ Assert.DoesNotThrow(() => data.ToObjectFromJson());
}
}
}
diff --git a/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.csproj b/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.csproj
index 24c4e2d..ac71991 100644
--- a/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.csproj
+++ b/cloud_connectors/azure/mqtt_connector/azure_function/tests/MQTTConnectorAzureFunction.Tests.csproj
@@ -4,6 +4,7 @@
net6.0
enable
false
+ latest-recommended