Desarrollo de un módulo ioT Edge de C# para mover archivos con Azure Stack Edge Pro FPGA
Importante
Los dispositivos De Azure Stack Edge Pro FPGA llegaron al final del ciclo de vida en febrero de 2024.
En este artículo se explica cómo crear un módulo de IoT Edge para la implementación con el dispositivo Azure Stack Edge Pro FPGA. Azure Stack Edge Pro FPGA es una solución de almacenamiento que permite procesar datos y enviarlos a través de la red a Azure.
Puede usar módulos de Azure IoT Edge con Azure Stack Edge Pro FPGA para transformar los datos a medida que se mueven a Azure. El módulo usado en este artículo implementa la lógica para copiar un archivo de un recurso compartido local en un recurso compartido en la nube en el dispositivo Azure Stack Edge Pro FPGA.
En este artículo, aprenderá a:
- Cree un registro de contenedor para almacenar y administrar los módulos (imágenes de Docker).
- Cree un módulo de IoT Edge para implementarlo en el dispositivo Azure Stack Edge Pro FPGA.
Acerca del módulo ioT Edge
El dispositivo Azure Stack Edge Pro FPGA puede implementar y ejecutar módulos de IoT Edge. Los módulos perimetrales son básicamente contenedores de Docker que realizan una tarea específica, como ingerir un mensaje de un dispositivo, transformar un mensaje o enviar un mensaje a ioT Hub. En este artículo, crearás un módulo que copia archivos desde un recurso compartido local a un recurso compartido en la nube en tu dispositivo Azure Stack Edge Pro FPGA.
- Los archivos se escriben en la compartición local en el dispositivo Azure Stack Edge Pro FPGA.
- El generador de eventos de archivo crea un evento de archivo para cada archivo escrito en el recurso compartido local. Los eventos de archivo también se generan cuando se modifica un archivo. Los eventos de archivo se envían a IoT Edge Hub (en tiempo de ejecución de IoT Edge).
- El módulo personalizado de IoT Edge procesa el evento de archivo para crear un objeto de evento de archivo que también contiene una ruta de acceso relativa para el archivo. El módulo genera una ruta de acceso absoluta a partir de la ruta relativa del archivo y transfiere el archivo desde el recurso compartido local al recurso compartido en la nube. A continuación, el módulo elimina el archivo del recurso compartido local.
Una vez que el archivo está en el recurso compartido en la nube, se carga automáticamente en la cuenta de Azure Storage.
Prerrequisitos
Antes de comenzar, asegúrese de que tiene:
Un dispositivo FPGA Azure Stack Edge Pro que está en ejecución.
- El dispositivo también tiene un recurso de IoT Hub asociado.
- El dispositivo tiene configurado el rol de computación en el borde. Para obtener más información, vaya a Configure el cómputo para su Azure Stack Edge Pro FPGA.
Los siguientes recursos de desarrollo:
- de Visual Studio Code.
- extensión de C# para Visual Studio Code (con tecnología de OmniSharp).
- extensión de Azure IoT Edge para Visual Studio Code.
- SDK de .NET Core 2.1.
- Docker CE. Es posible que tenga que crear una cuenta para descargar e instalar el software.
Creación de un registro de contenedor
Un registro de contenedor de Azure es un registro privado de Docker en Azure donde puede almacenar y administrar las imágenes de contenedor privadas de Docker. Los dos servicios populares del registro de Docker disponibles en la nube son Azure Container Registry y Docker Hub. En este artículo se usa Container Registry.
En un explorador, inicia sesión en el portal de Azure.
Seleccione Crear un recurso > Contenedores > Registro de Contenedores. Haga clic en Crear.
Proporcionar:
Un nombre de registro único de dentro de Azure que contiene entre 5 y 50 caracteres alfanuméricos.
Elija una suscripción.
Cree un nuevo grupo de recursos o elija uno existente de .
Seleccione una Ubicación. Se recomienda que esta ubicación sea la misma que la asociada al recurso de Azure Stack Edge.
Cambie usuario administrador a Habilitar.
Establezca el SKU en Básico.
Seleccione Crear.
Una vez creado el registro de contenedor, vaya a él y seleccione Claves de acceso.
Copie los valores de servidor de inicio de sesión, nombre de usuarioy contraseña. Estos valores se usan más adelante para publicar la imagen de Docker en el registro y para agregar las credenciales del Registro al entorno de ejecución de Azure IoT Edge.
Creación de un proyecto de módulo de IoT Edge
En los pasos siguientes se crea un proyecto de módulo de IoT Edge basado en el SDK de .NET Core 2.1. El proyecto usa Visual Studio Code y la extensión de Azure IoT Edge.
Creación de una nueva solución
Cree una plantilla de solución de C# que pueda personalizar con su propio código.
En Visual Studio Code, seleccione Ver > paleta de comandos para abrir la paleta de comandos de VS Code.
En la paleta de comandos, escriba y ejecute el comando Azure: Inicie sesión y siga las instrucciones para iniciar sesión en su cuenta de Azure. Si ya ha iniciado sesión, puede omitir este paso.
En la paleta de comandos, escriba y ejecute el comando Azure IoT Edge: Nueva solución de IoT Edge. En la paleta de comandos, proporcione la siguiente información para crear la solución:
Seleccione la carpeta donde desea crear la solución.
Proporcione un nombre para la solución o acepte el valor predeterminado EdgeSolution.
Elija módulo de C# como plantilla de módulo.
Reemplace el nombre del módulo predeterminado por el nombre que desea asignar, en este caso, es FileCopyModule.
Especifique el registro de contenedor que creó en la sección anterior como repositorio de imágenes para el primer módulo. Reemplace localhost:5000 por el valor del servidor de login que copió.
La cadena final es similar a
<Login server name>/<Module name>
. En este ejemplo, la cadena es:mycontreg2.azurecr.io/filecopymodule
.
Vaya a archivo > Abrir carpeta.
Busque e indique la carpeta EdgeSolution que creó anteriormente. La ventana de VS Code carga el área de trabajo de la solución de IoT Edge con sus cinco componentes de nivel superior. No editará la carpeta .vscode, el archivo .gitignore, el archivo .env y el deployment.template.json de este artículo.
El único componente que modifique es la carpeta modules. Esta carpeta tiene el código de C# para el módulo y los archivos de Docker para compilar el módulo como una imagen de contenedor.
Actualización del módulo con código personalizado
En el explorador de VS Code, abra módulos > FileCopyModule > Program.cs.
En la parte superior del espacio de nombres FileCopyModule, agregue las siguientes directivas using para los tipos que se usan más adelante. microsoft.Azure.Devices.Client.Transport.Mqtt es un protocolo para enviar mensajes a IoT Edge Hub.
namespace FileCopyModule { using Microsoft.Azure.Devices.Client.Transport.Mqtt; using Newtonsoft.Json;
Agregue la variable InputFolderPath y OutputFolderPath a la clase Program.
class Program { static int counter; private const string InputFolderPath = "/home/input"; private const string OutputFolderPath = "/home/output";
Inmediatamente después del paso anterior, agregue la clase FileEvent para definir el cuerpo del mensaje.
/// <summary> /// The FileEvent class defines the body of incoming messages. /// </summary> private class FileEvent { public string ChangeType { get; set; } public string ShareRelativeFilePath { get; set; } public string ShareName { get; set; } }
En el método Init , el código crea y configura un objeto ModuleClient. Este objeto permite al módulo conectarse al entorno de ejecución de Azure IoT Edge local mediante el protocolo MQTT para enviar y recibir mensajes. El entorno de ejecución de IoT Edge proporciona la cadena de conexión que se usa en el método Init al módulo. El código registra una devolución de llamada de FileCopy para recibir mensajes de un hub de IoT Edge a través del punto de conexión input1. Reemplace el método Init por el código siguiente.
/// <summary> /// Initializes the ModuleClient and sets up the callback to receive /// messages containing file event information /// </summary> static async Task Init() { MqttTransportSettings mqttSetting = new MqttTransportSettings(TransportType.Mqtt_Tcp_Only); ITransportSettings[] settings = { mqttSetting }; // Open a connection to the IoT Edge runtime ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings); await ioTHubModuleClient.OpenAsync(); Console.WriteLine("IoT Hub module client initialized."); // Register callback to be called when a message is received by the module await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", FileCopy, ioTHubModuleClient); }
Quite el código del método PipeMessage y, en su lugar, inserte el código para FileCopy.
/// <summary> /// This method is called whenever the module is sent a message from the IoT Edge Hub. /// This method deserializes the file event, extracts the corresponding relative file path, and creates the absolute input file path using the relative file path and the InputFolderPath. /// This method also forms the absolute output file path using the relative file path and the OutputFolderPath. It then copies the input file to output file and deletes the input file after the copy is complete. /// </summary> static async Task<MessageResponse> FileCopy(Message message, object userContext) { int counterValue = Interlocked.Increment(ref counter); try { byte[] messageBytes = message.GetBytes(); string messageString = Encoding.UTF8.GetString(messageBytes); Console.WriteLine($"Received message: {counterValue}, Body: [{messageString}]"); if (!string.IsNullOrEmpty(messageString)) { var fileEvent = JsonConvert.DeserializeObject<FileEvent>(messageString); string relativeFileName = fileEvent.ShareRelativeFilePath.Replace("\\", "/"); string inputFilePath = InputFolderPath + relativeFileName; string outputFilePath = OutputFolderPath + relativeFileName; if (File.Exists(inputFilePath)) { Console.WriteLine($"Moving input file: {inputFilePath} to output file: {outputFilePath}"); var outputDir = Path.GetDirectoryName(outputFilePath); if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } File.Copy(inputFilePath, outputFilePath, true); Console.WriteLine($"Copied input file: {inputFilePath} to output file: {outputFilePath}"); File.Delete(inputFilePath); Console.WriteLine($"Deleted input file: {inputFilePath}"); } else { Console.WriteLine($"Skipping this event as input file doesn't exist: {inputFilePath}"); } } } catch (Exception ex) { Console.WriteLine("Caught exception: {0}", ex.Message); Console.WriteLine(ex.StackTrace); } Console.WriteLine($"Processed event."); return MessageResponse.Completed; }
Guarde este archivo.
También puede descargar un ejemplo de código existente para este proyecto. A continuación, puede validar el archivo que guardó contra el archivo program.cs de este ejemplo.
Construye tu solución de IoT Edge
En la sección anterior, creó una solución de IoT Edge y agregó código a FileCopyModule para copiar archivos del recurso compartido local al recurso compartido en la nube. Ahora debe compilar la solución como una imagen de contenedor y subirla a su registro de contenedores.
En VSCode, vaya a Terminal > Nuevo terminal para abrir un nuevo terminal integrado de Visual Studio Code.
Inicie sesión en Docker escribiendo el siguiente comando en el terminal integrado.
docker login <ACR login server> -u <ACR username>
Use el servidor de inicio de sesión y el nombre de usuario que copió del registro de contenedor.
Cuando se le solicite la contraseña, proporcione la contraseña. También puede recuperar los valores para el servidor de inicio de sesión, el nombre de usuario y la contraseña desde las Claves de acceso en su registro de contenedores en el portal de Azure.
Una vez proporcionadas las credenciales, puede insertar la imagen del módulo en el registro de contenedor de Azure. En el Explorador de VS Code, haga clic con el botón derecho en el archivo module.json y seleccione Compilar y empujar la Solución IoT Edge.
Cuando se indica a Visual Studio Code que compile la solución, ejecuta dos comandos en el terminal integrado: docker build y docker push. Estos dos comandos compilan el código, contenedorizan el CSharpModule.dlly, a continuación, envían el código al registro de contenedores que especificó al inicializar la solución.
Se le pedirá que elija la plataforma del módulo. Seleccione amd64 correspondiente a Linux.
de plataforma
Importante
Solo se admiten los módulos de Linux.
Es posible que vea la siguiente advertencia que puede omitir:
Program.cs(77,44): advertencia CS1998: este método asincrónico carece de operadores "await" y se ejecutará sincrónicamente. Considere la posibilidad de usar el operador "await" para esperar llamadas API sin bloqueo o "await Task.Run(...)" para realizar el trabajo enlazado a la CPU en un subproceso en segundo plano.
Puede ver la dirección completa de la imagen del contenedor con su etiqueta correspondiente en el terminal integrado de VS Code. La dirección de imagen se crea a partir de información que se encuentra en el archivo module.json con el formato
<repository>:<version>-<platform>
. Para este artículo, debería tener un aspecto similar amycontreg2.azurecr.io/filecopymodule:0.0.1-amd64
.
Pasos siguientes
Para implementar y ejecutar este módulo en Azure Stack Edge Pro FPGA, consulte los pasos descritos en Adición de un módulo.