admin管理员组

文章数量:1336737

I have one deployment manifest, which I can upload using this command:

az iot edge deployment create --hub-name IoTHubName --content ./deployment.arm64v8.json --deployment-id
 "V20241119_arm64v8_v2" --target-condition "tags.DeviceDeploymentVersion='V20241119-arm64v8'" --priority 28

Works great and is successful every time..

Now for the API via the SDK..

     var registryManager = MsAzureDevicesNS.RegistryManager.CreateFromConnectionString(_IOTHubDevicesConfiguration.IOTHubConnectionString);
   
    var configuration = new Configuration(edgeDeploymentModel.DeploymentId)
    {
      Content = new ConfigurationContent
      {
        ModulesContent = JsonSerializer.Deserialize<IDictionary<string, IDictionary<string, object>>>(
                    edgeDeploymentModel.ConfigurationContent, _jsonSerializerOptions)
      },
      TargetCondition = edgeDeploymentModel.TargetCondition,
      Priority = edgeDeploymentModel.Priority,
      ETag = string.Empty,
    };


edgeDeploymentModel.ConfigurationContent is the json read from the exact same file -> deployment.arm64v8.json.

I then: await registryManager.AddConfigurationAsync(configuration);

Error message is pretty generic (thanks JSON)

This is the deployment manifest that was used to upload (correctly) using the cli

{
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "gfsedgemodules": {
                "username": "XXXEdgeModules",
                "password": "",
                "address": "XXXedgemodules.azurecr.io"
              }
            }
          }
        },
        "systemModules": {
          "edgeAgent": {
            "env": {
              "StorageFolder": {
                "value": "/tmp/edgeAgent"
              }
            },
            "type": "docker",
            "settings": {
              "image": "mcr.microsoft/azureiotedge-agent:1.5",
              "createOptions": "{\"HostConfig\":{\"privileged\":true,\"Binds_Comment\":\"When binding, define the host path to the container path\",\"Binds\":[\"/srv/iotEdge/edgeAgent:/tmp/edgeAgent\"]}}"
            }
          },
          "edgeHub": {
            "env": {
              "StorageFolder": {
                "value": "/tmp/edgeHub"
              },
              "UpstreamProtocol": {
                "value": "Mqtt"
              }
            },
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "mcr.microsoft/azureiotedge-hub:1.5",
              "createOptions": "{\"HostConfig\":{\"Binds\":[\"/srv/iotEdge/edgeHub:/tmp/edgeHub:\"],\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
            }
          }
        },
        "modules": {
          "XXXConnectIoTModule": {
            "version": "2.0.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "XXXedgemodules.azurecr.io/XXXconnectrepo:v20241120.v1-arm64v8",
              "createOptions": "{\"HostConfig\":{\"NetworkMode\":\"host\",\"privileged\":true,\"Binds\":[\"/dev/i2c-1:/dev/i2c-1\"],\"Mount_Comment\":\"Source is the host, and Target is within the Pod - the Source points to Target\",\"Mounts\":[{\"Commment\":\"Read the device initialization file\",\"Source\":\"/home/XXXAdmin001/XXXInitialization\",\"Target\":\"/host/XXXInitialization\",\"Type\":\"bind\",\"ReadOnly\":true},{\"Commment\":\"CPU Temperature of device\",\"Source\":\"/sys/class/thermal/thermal_zone0\",\"Target\":\"/host/sys/class/thermal/thermal_zone0\",\"Type\":\"bind\",\"ReadOn",
              "createOptions01": "ly\":true},{\"Commment\":\"Get Serial Number of the device\",\"Source\":\"/sys/firmware/devicetree/base/\",\"Target\":\"/host/sys/firmware/devicetree/base/\",\"Type\":\"bind\",\"ReadOnly\":true},{\"Commment\":\"Get the host name of the device\",\"Source\":\"/proc/sys/kernel/\",\"Target\":\"/host/proc/sys/kernel/\",\"Type\":\"bind\",\"ReadOnly\":true},{\"Commment\":\"Get the CPU Info of the device\",\"Source\":\"/proc/\",\"Target\":\"/host/proc/\",\"Type\":\"bind\",\"ReadOnly\":true}]},\"NetworkingConfig\":{\"EndpointsConfig\":{\"host\":{}}}}"
            },
            "env": {
              "Version": {
                "value": "v20241120.V1"
              },
              "RuntimeLogLevel": {
                "value": "Information"
              }
            }
          }
        }
      }
    },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.2",
        "routes": {
          "XXXConnectIoTModuleToIoTHub": {
            "route": "FROM /messages/modules/XXXModule/outputs/* INTO $upstream"
          }
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 7200
        }
      }
    },
    "XXXModule": {
      "properties.desired.version": "v20241120.V1"
    }
  }
}
System.ArgumentException
  HResult=0x80070057
  Message={"Message":"ErrorCode:InvalidConfigurationContent;The content provided for configuration is invalid. Please check and try again","ExceptionMessage":"Tracking ID:ee7f302c1982487d942975af604e7af3-G:0-TimeStamp:11/20/2024 00:09:17"}
  Source=Microsoft.Azure.Devices
  StackTrace:
   at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__36.MoveNext()
   at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__32.MoveNext()
   at Microsoft.Azure.Devices.HttpClientHelper.<PutAsync>d__11`1.MoveNext()
   at GFSConnectApp.Engines.IoTHubDevicesEngine.<UploadConfigurationToIotHubAsync>d__11.MoveNext() in C:\Users\Richard\source\repos\PhxBiz\GFSConnectSLN\GFSConnectApp\Engines\IoTHubDevicesEngine.cs:line 158

This exception was originally thrown at this call stack:
    Microsoft.Azure.Devices.HttpClientHelper.ExecuteAsync(System.Net.Http.HttpClient, System.Net.Http.HttpMethod, System.Uri, System.Func<System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Func<System.Net.Http.HttpResponseMessage, bool>, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Collections.Generic.IDictionary<System.Net.HttpStatusCode, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.Tasks.Task<System.Exception>>>, System.Threading.CancellationToken)
    Microsoft.Azure.Devices.HttpClientHelper.ExecuteAsync(System.Net.Http.HttpMethod, System.Uri, System.Func<System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Collections.Generic.IDictionary<System.Net.HttpStatusCode, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.Tasks.Task<System.Exception>>>, System.Threading.CancellationToken)
    GFSConnectApp.Engines.IoTHubDevicesEngine.UploadConfigurationToIotHubAsync(GFSConnectApp.Model.EdgeConfigurationModel) in IoTHubDevicesEngine.cs

Same file, I was thinking the SDK would allow it.... perhaps the deserialization into the dictionary is where an error is occurring

I have one deployment manifest, which I can upload using this command:

az iot edge deployment create --hub-name IoTHubName --content ./deployment.arm64v8.json --deployment-id
 "V20241119_arm64v8_v2" --target-condition "tags.DeviceDeploymentVersion='V20241119-arm64v8'" --priority 28

Works great and is successful every time..

Now for the API via the SDK..

     var registryManager = MsAzureDevicesNS.RegistryManager.CreateFromConnectionString(_IOTHubDevicesConfiguration.IOTHubConnectionString);
   
    var configuration = new Configuration(edgeDeploymentModel.DeploymentId)
    {
      Content = new ConfigurationContent
      {
        ModulesContent = JsonSerializer.Deserialize<IDictionary<string, IDictionary<string, object>>>(
                    edgeDeploymentModel.ConfigurationContent, _jsonSerializerOptions)
      },
      TargetCondition = edgeDeploymentModel.TargetCondition,
      Priority = edgeDeploymentModel.Priority,
      ETag = string.Empty,
    };


edgeDeploymentModel.ConfigurationContent is the json read from the exact same file -> deployment.arm64v8.json.

I then: await registryManager.AddConfigurationAsync(configuration);

Error message is pretty generic (thanks JSON)

This is the deployment manifest that was used to upload (correctly) using the cli

{
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "gfsedgemodules": {
                "username": "XXXEdgeModules",
                "password": "",
                "address": "XXXedgemodules.azurecr.io"
              }
            }
          }
        },
        "systemModules": {
          "edgeAgent": {
            "env": {
              "StorageFolder": {
                "value": "/tmp/edgeAgent"
              }
            },
            "type": "docker",
            "settings": {
              "image": "mcr.microsoft/azureiotedge-agent:1.5",
              "createOptions": "{\"HostConfig\":{\"privileged\":true,\"Binds_Comment\":\"When binding, define the host path to the container path\",\"Binds\":[\"/srv/iotEdge/edgeAgent:/tmp/edgeAgent\"]}}"
            }
          },
          "edgeHub": {
            "env": {
              "StorageFolder": {
                "value": "/tmp/edgeHub"
              },
              "UpstreamProtocol": {
                "value": "Mqtt"
              }
            },
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "mcr.microsoft/azureiotedge-hub:1.5",
              "createOptions": "{\"HostConfig\":{\"Binds\":[\"/srv/iotEdge/edgeHub:/tmp/edgeHub:\"],\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
            }
          }
        },
        "modules": {
          "XXXConnectIoTModule": {
            "version": "2.0.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "XXXedgemodules.azurecr.io/XXXconnectrepo:v20241120.v1-arm64v8",
              "createOptions": "{\"HostConfig\":{\"NetworkMode\":\"host\",\"privileged\":true,\"Binds\":[\"/dev/i2c-1:/dev/i2c-1\"],\"Mount_Comment\":\"Source is the host, and Target is within the Pod - the Source points to Target\",\"Mounts\":[{\"Commment\":\"Read the device initialization file\",\"Source\":\"/home/XXXAdmin001/XXXInitialization\",\"Target\":\"/host/XXXInitialization\",\"Type\":\"bind\",\"ReadOnly\":true},{\"Commment\":\"CPU Temperature of device\",\"Source\":\"/sys/class/thermal/thermal_zone0\",\"Target\":\"/host/sys/class/thermal/thermal_zone0\",\"Type\":\"bind\",\"ReadOn",
              "createOptions01": "ly\":true},{\"Commment\":\"Get Serial Number of the device\",\"Source\":\"/sys/firmware/devicetree/base/\",\"Target\":\"/host/sys/firmware/devicetree/base/\",\"Type\":\"bind\",\"ReadOnly\":true},{\"Commment\":\"Get the host name of the device\",\"Source\":\"/proc/sys/kernel/\",\"Target\":\"/host/proc/sys/kernel/\",\"Type\":\"bind\",\"ReadOnly\":true},{\"Commment\":\"Get the CPU Info of the device\",\"Source\":\"/proc/\",\"Target\":\"/host/proc/\",\"Type\":\"bind\",\"ReadOnly\":true}]},\"NetworkingConfig\":{\"EndpointsConfig\":{\"host\":{}}}}"
            },
            "env": {
              "Version": {
                "value": "v20241120.V1"
              },
              "RuntimeLogLevel": {
                "value": "Information"
              }
            }
          }
        }
      }
    },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.2",
        "routes": {
          "XXXConnectIoTModuleToIoTHub": {
            "route": "FROM /messages/modules/XXXModule/outputs/* INTO $upstream"
          }
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 7200
        }
      }
    },
    "XXXModule": {
      "properties.desired.version": "v20241120.V1"
    }
  }
}
System.ArgumentException
  HResult=0x80070057
  Message={"Message":"ErrorCode:InvalidConfigurationContent;The content provided for configuration is invalid. Please check and try again","ExceptionMessage":"Tracking ID:ee7f302c1982487d942975af604e7af3-G:0-TimeStamp:11/20/2024 00:09:17"}
  Source=Microsoft.Azure.Devices
  StackTrace:
   at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__36.MoveNext()
   at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__32.MoveNext()
   at Microsoft.Azure.Devices.HttpClientHelper.<PutAsync>d__11`1.MoveNext()
   at GFSConnectApp.Engines.IoTHubDevicesEngine.<UploadConfigurationToIotHubAsync>d__11.MoveNext() in C:\Users\Richard\source\repos\PhxBiz\GFSConnectSLN\GFSConnectApp\Engines\IoTHubDevicesEngine.cs:line 158

This exception was originally thrown at this call stack:
    Microsoft.Azure.Devices.HttpClientHelper.ExecuteAsync(System.Net.Http.HttpClient, System.Net.Http.HttpMethod, System.Uri, System.Func<System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Func<System.Net.Http.HttpResponseMessage, bool>, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Collections.Generic.IDictionary<System.Net.HttpStatusCode, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.Tasks.Task<System.Exception>>>, System.Threading.CancellationToken)
    Microsoft.Azure.Devices.HttpClientHelper.ExecuteAsync(System.Net.Http.HttpMethod, System.Uri, System.Func<System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.CancellationToken, System.Threading.Tasks.Task>, System.Collections.Generic.IDictionary<System.Net.HttpStatusCode, System.Func<System.Net.Http.HttpResponseMessage, System.Threading.Tasks.Task<System.Exception>>>, System.Threading.CancellationToken)
    GFSConnectApp.Engines.IoTHubDevicesEngine.UploadConfigurationToIotHubAsync(GFSConnectApp.Model.EdgeConfigurationModel) in IoTHubDevicesEngine.cs

Same file, I was thinking the SDK would allow it.... perhaps the deserialization into the dictionary is where an error is occurring

Share Improve this question edited Nov 21, 2024 at 18:09 codeputer asked Nov 20, 2024 at 0:12 codeputercodeputer 2,0284 gold badges21 silver badges48 bronze badges 1
  • What type of configuration would you like to create and upload? Where would you like to upload it? Please provide the documents or links you are following and the packages you are using – Sampath Commented Nov 20, 2024 at 3:21
Add a comment  | 

1 Answer 1

Reset to default 0

The error is related to the structure of the ModulesContent dictionary and configuration properties.

I referred to this MSDOC for importing and exporting device identities in Azure IoT Hub.

Additionally, I referred to the following GitHub repositories for ConfigurationContent and ImportExportDevicesSample

Below code is to create a configuration that will be uploaded to IoT Hub using the RegistryManager.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Azure.Devices;

namespace AzureIoT
{
    public class IoTHubDeviceManagement
    {
        private readonly string _iotHubConnectionString;

        public IoTHubDeviceManagement(string connectionString)
        {
            _iotHubConnectionString = connectionString;
        }

        public async Task UploadConfigurationAsync(string deploymentId, string configurationContentJson, string targetCondition, int priority)
        {
            try
            {
                
                var registryManager = RegistryManager.CreateFromConnectionString(_iotHubConnectionString);

              
                var configData = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(configurationContentJson);

         
                var modulesContentJson = configData["modulesContent"].ToString();
                var labelsJson = configData.ContainsKey("labels") ? configData["labels"].ToString() : "{}"; 
                var metricsJson = configData.ContainsKey("metrics") ? configData["metrics"].ToString() : "{}";
                var modulesContent = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(modulesContentJson);
                var modulesContentAsIDictionary = new Dictionary<string, IDictionary<string, object>>();

                foreach (var module in modulesContent)
                {
                    var moduleContent = JsonSerializer.Deserialize<Dictionary<string, object>>(module.Value.ToString());
                    modulesContentAsIDictionary.Add(module.Key, moduleContent);
                }

                var configuration = new Microsoft.Azure.Devices.Configuration(deploymentId)
                {
                    Content = new Microsoft.Azure.Devices.ConfigurationContent
                    {
                        ModulesContent = modulesContentAsIDictionary
                    },
                    TargetCondition = targetCondition,
                    Priority = priority,
                    ETag = string.Empty 
                };

            
                if (!string.IsNullOrEmpty(labelsJson))
                {
                    var labels = JsonSerializer.Deserialize<Dictionary<string, string>>(labelsJson);
                    configuration.Labels = labels;
                }

                if (!string.IsNullOrEmpty(metricsJson))
                {
                    var metrics = JsonSerializer.Deserialize<Dictionary<string, object>>(metricsJson);
         
                }

                await registryManager.AddConfigurationAsync(configuration);
                Console.WriteLine("Configuration uploaded successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error uploading configuration: {ex.Message}");
            }
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
      
            string connectionString = "HostName=AzureIOTHubName.azure-devices;SharedAccessKeyName=iothubowner;SharedAccessKey=kkk..";

            string configurationContentJson = @"
            {
                ""modulesContent"": {
                    ""$edgeAgent"": {
                        ""properties.desired"": {
                            ""modules"": {
                                ""module1"": {
                                    ""type"": ""docker"",
                                    ""settings"": {
                                        ""image"": ""mydockerimage:v1"",
                                        ""createOptions"": ""\""""
                                    }
                                }
                            }
                        }
                    },
                    ""$edgeHub"": {
                        ""properties.desired"": {
                            ""routes"": {
                                ""myRoute"": ""FROM /messages/* INTO $upstream""
                            }
                        }
                    }
                },
                ""labels"": {
                    ""environment"": ""production"",
                    ""location"": ""building_1""
                },
                ""metrics"": {
                    ""queries"": {
                        ""statusQuery"": ""SELECT deviceId FROM devices WHERE properties.reported.status = 'OK'""
                    }
                },
                ""priority"": 10
            }";


            string targetCondition = "tags.DeviceDeploymentVersion='V20241119-arm64v8' AND tags.environment='production' AND tags.location='building_1'";

            
            var iotDeviceManagement = new IoTHubDeviceManagement(connectionString);

          
            await iotDeviceManagement.UploadConfigurationAsync("raviteja", configurationContentJson, targetCondition, 28);
        }
    }
}

本文标签: azureHow to create Configuration that will upload via the RegistryManagerStack Overflow