Поделиться через


Разработка модуля C# IoT Edge для перемещения файлов с помощью ППВМ Azure Stack Edge Pro

Внимание

Поддержка устройств ППВМ Azure Stack Edge Pro будет прекращена в феврале 2024 г. Если вы рассматриваете новые развертывания, рекомендуется изучить устройства Azure Stack Edge Pro 2 или Azure Stack Edge Pro с GPU для рабочих нагрузок.

В этой статье приведены пошаговые инструкции по созданию модуля IoT Edge для развертывания на вашем устройстве ППВМ Azure Stack Edge Pro. ППВМ Azure Stack Edge Pro — это решение хранилища, которое позволяет обрабатывать данные и отправлять их по сети в Azure.

Вы можете использовать модули Azure IoT Edge с ППВМ Azure Stack Edge Pro для преобразования данных по мере их перемещения в Azure. Модуль, используемый в этой статье, реализует логику копирования файла из локального общего ресурса в общий ресурс облака на вашем устройстве ППВМ Azure Stack Edge Pro.

Вы узнаете, как выполнять следующие задачи:

  • Создание реестра контейнеров для хранения модулей (в виде образов Docker) и управление ими.
  • Создание модуля IoT Edge для развертывания на вашем устройстве ППВМ Azure Stack Edge Pro.

Общая информация о модулях IoT Edge

Ваше устройство ППВМ Azure Stack Edge Pro может развертывать и запускать модули IoT Edge. Модули Edge — это по сути контейнеры Docker, предназначенные для выполнения конкретной задачи, например для приема сообщений от устройства, преобразования сообщений или отправки сообщений в Центр Интернета вещей. В этой статье вы создадите модуль, который копирует файлы из локальной общей папки в общий облачный ресурс на вашем устройстве ППВМ Azure Stack Edge Pro.

  1. Файлы записываются в локальную общую папку на устройстве ППВМ Azure Stack Edge Pro.
  2. Генератор файловых событий создает файловое событие для каждого файла, сохраненного в общий локальный ресурс. При изменении файла также создаются события файла. Эти файловые события отправляются в концентратор IoT Edge, который расположен в среде выполнения IoT Edge.
  3. Пользовательский модуль IoT Edge обрабатывает файловое событие и создает объект файлового события с относительным путем к соответствующему файлу. Модуль вычисляет абсолютный путь, используя этот относительный путь, и копирует файл из общего локального ресурса в общий облачный ресурс. Затем модуль удаляет файл из общего локального ресурса.

Принципы работы модуля Azure IoT Edge на устройстве ППВМ Azure Stack Edge Pro

Как только файл попадает в общий облачный ресурс, он автоматически загружается в учетную запись хранения Azure.

Необходимые компоненты

Перед началом работы убедитесь, что у вас есть следующие ресурсы:

Создание реестра контейнеров

Реестр контейнеров Azure — это частный реестр Docker в Azure, где можно хранить частные образы контейнеров Docker и управлять ими. Две самые популярные облачные службы реестров Docker — Реестр контейнеров Azure и Центр Docker. В этой статье используется Реестр контейнеров.

  1. В браузере войдите в портал Azure.

  2. Выберите "Создать реестр контейнеров ресурсов > >". Нажмите кнопку Создать.

  3. Предоставить.

    1. Создайте уникальное в пределах Azure имя реестра, которое содержит от 5 до 50 буквенно-цифровых символов.

    2. Выберите Подписка.

    3. Выберите существующую группу ресурсов или создайте новую.

    4. Выберите расположение. Рекомендуем, чтобы это расположение было таким же, как у ресурса, связанного с Azure Stack Edge.

    5. Включите параметр Пользователь-администратор.

    6. Для номера SKU выберите вариант Базовый.

      Создание реестра контейнеров

  4. Нажмите кнопку создания.

  5. После создания реестра контейнеров просмотрите его и выберите Ключи доступа.

    Получение ключей доступа

  6. Скопируйте значения Сервер входа, Имя пользователя и Пароль. Эти значения вам потребуются позже при публикации образа Docker в реестре и добавлении учетных данных реестра в среду выполнения Azure IoT Edge.

Создание проекта модуля IoT Edge

На следующих шагах создается проект модуля IoT Edge на основе пакета SDK для .NET Core 2.1. В этом проекте используется Visual Studio Code с расширением Azure IoT Edge.

Создание нового решения

Создайте шаблон решения C#, который можно настроить с помощью собственного кода.

  1. В Visual Studio Code выберите представление > палитры команд, чтобы открыть палитру команд VS Code.

  2. В палитре команд введите и выполните команду Azure: Sign in (Azure: Вход) и следуйте инструкциям, чтобы войти в свою учетную запись Azure. Если вход был выполнен, то этот шаг можно пропустить.

  3. В палитре команд введите и выполните команду Azure IoT Edge: New IoT Edge solution. В палитре команд укажите следующие сведения для создания решения:

    1. Выберите папку, где требуется создать решение.

    2. Введите имя своего решения или примите имя по умолчанию EdgeSolution.

      Создание решения 1

    3. Выберите C# Module (Модуль C#) в качестве шаблона модуля.

    4. Замените имя модуля, предложенное по умолчанию, любым именем на ваш выбор. В нашем примере это FileCopyModule.

      Создание решения 2

    5. В качестве репозитория образов первого модуля укажите Реестр контейнеров Azure, который вы создали в предыдущем разделе. Замените localhost:5000 скопированным значением имени входа на сервер.

      Строка должна выглядеть так: <Login server name>/<Module name>. В нашем примере это строка mycontreg2.azurecr.io/filecopymodule.

      Создание решения 3

  4. Перейдите в папку "Открыть файл>".

    Создание решения 4

  5. Найдите и выберите папку EdgeSolution, которую вы создали ранее. Окно VS Code загружает рабочую область решения IoT Edge, в которой размещены пять элементов верхнего уровня. В этой статье мы не будем изменять папку .vscode, а также файлы .gitignore, .env и deployment.template.json.

    Сейчас из этих компонентов нас интересует только папка modules. Эта папка содержит код C# для модуля и файлы Docker для сборки модуля в образ контейнера.

    Создание решения 5

Обновление модуля с помощью пользовательского кода

  1. В обозревателе VS Code откройте модули > FileCopyModule > Program.cs.

  2. В верхней части пространства имен CSharpModule добавьте следующие операторы using для типов, которые будут использоваться позже. Microsoft.Azure.Devices.Client.Transport.Mqtt — это протокол отправки сообщений в центр IoT Edge.

    namespace FileCopyModule
    {
        using Microsoft.Azure.Devices.Client.Transport.Mqtt;
        using Newtonsoft.Json;
    
  3. Добавьте в класс Program переменные InputFolderPath и OutputFolderPath.

    class Program
        {
            static int counter;
            private const string InputFolderPath = "/home/input";
            private const string OutputFolderPath = "/home/output";
    
  4. Сразу после выполнения предыдущего шага добавьте класс FileEvent для определения текста сообщения.

    /// <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; }
    }
    
  5. В Init-метод код создает объект ModuleClient и настраивает его параметры. Этот объект позволяет модулю подключаться к локальной среде выполнения Azure IoT Edge по протоколу MQTT для отправки и получения сообщений. Строка подключения, используемая в методе Init, предоставляется модулю средой выполнения IoT Edge. Этот код регистрирует обратный вызов FileCopy для получения сообщений от центра IoT Edge через конечную точку input1. Замените Init-метод следующим кодом.

    /// <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);
    }
    
  6. Удалите код для метода PipeMessage и вместо него вставьте код для 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;
        }
    
  7. Сохраните этот файл.

  8. Вы также можете загрузить существующий пример кода для этого проекта. Затем вы можете проверить файл, который вы сохранили c program.cs из этого примера.

Сборка решения IoT Edge

В предыдущем разделе описано, как создать решение IoT Edge и добавить в FileCopyModule код для копирования файлов из общего локального ресурса в общий облачный ресурс. Теперь необходимо создать решение в качестве образа контейнера и передать его в реестр контейнеров.

  1. В VSCode перейдите в терминал > New Terminal, чтобы открыть новый интегрированный терминал Visual Studio Code.

  2. Войдите в Docker, введя следующую команду во встроенном терминале.

    docker login <ACR login server> -u <ACR username>

    Укажите имя пользователя и сервер входа, которые вы скопировали из Реестра контейнеров Azure.

    Создание и отправка решения IoT Edge

  3. В ответ на запрос введите пароль. Сервер входа, имя пользователя и пароль можно также получить в разделе Ключи доступа Реестра контейнеров на портале Azure.

  4. Предоставив учетные данные, вы сможете отправить образ модуля в Реестр контейнеров Azure. В обозревателе VS Code щелкните правой кнопкой мыши файл module.json и выберите действие Build and Push IoT Edge solution (Собрать и отправить решение IoT Edge).

    Создание и отправка решения IoT Edge 2

    Получив команду на сборку решения, Visual Studio Code выполнит в интегрированном окне терминала две команды: docker build и docker push. Они создают код, упаковывают его в контейнер CSharpModule.dll и передают в реестр контейнера, который был указан при инициализации решения.

    Вам будет предложено выбрать платформу модуля. Выберите amd64, которая соответствует Linux.

    Выбор платформы

    Внимание

    Поддерживаются только модули Linux.

    Возможно, вы увидите следующее предупреждение, которое можно игнорировать:

    Program.cs(77,44): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. (Program.cs(77,44): предупреждение CS1998. В асинхронном методе отсутствуют операторы await; будет выполнен синхронный запуск. Воспользуйтесь оператором await для ожидания неблокирующих вызовов API или оператором await Task.Run(...) для выполнения связанных с ЦП заданий в фоновом потоке.)

  5. Полный адрес образа контейнера с тегом можно увидеть в окне интегрированного терминала VS Code. Адрес образа создается на основе информации, сохраненной в файле module.json в формате <repository>:<version>-<platform>. Для этой статьи адрес должен выглядеть так: mycontreg2.azurecr.io/filecopymodule:0.0.1-amd64.

Следующие шаги

Инструкции по развертыванию и запуску этого модуля на ППВМ Azure Stack Edge Pro см. в разделе Добавление модуля.