Sviluppare un modulo IoT Edge C# per spostare i file in Azure Stack Edge Pro
SI APPLICA A: Azure Stack Edge Pro - GPUAzure Stack Edge Pro 2Azure Stack Edge Pro RAzure Stack Edge Mini R
Questo articolo illustra come creare un modulo IoT Edge per la distribuzione con il dispositivo Azure Stack Edge Pro. Azure Stack Edge Pro è una soluzione di archiviazione che consente di elaborare i dati e inviarli in rete ad Azure.
È possibile usare i moduli di Azure IoT Edge con Azure Stack Edge Pro per trasformare i dati durante lo spostamento in Azure. Il modulo usato in questo articolo implementa la logica per copiare un file da una condivisione locale a una condivisione cloud nel dispositivo Azure Stack Edge Pro.
In questo articolo vengono illustrate le operazioni seguenti:
- Creare un registro contenitori per archiviare e gestire i moduli, ossia immagini Docker.
- Creare un modulo IoT Edge da distribuire nel dispositivo Azure Stack Edge Pro.
Informazioni sul modulo IoT Edge
Il dispositivo Azure Stack Edge Pro può distribuire ed eseguire moduli IoT Edge. I moduli di Edge sono essenzialmente contenitori Docker che eseguono un'attività specifica, come inserire un messaggio da un dispositivo, trasformare un messaggio o inviare un messaggio a un hub IoT. In questo articolo si creerà un modulo che copia i file da una condivisione locale a una condivisione cloud nel dispositivo Azure Stack Edge Pro.
- I file vengono scritti nella condivisione locale nel dispositivo Azure Stack Edge Pro.
- Il generatore di eventi del file crea un evento di file per ogni file scritto nella condivisione locale. Gli eventi di file vengono generati anche quando viene modificato un file. Gli eventi di file vengono quindi inviati all'hub di IoT Edge, nel runtime di IoT Edge.
- Il modulo personalizzato di IoT Edge elabora l'evento di file per creare un oggetto dell'evento di file che contiene anche un percorso relativo del file. Il modulo genera un percorso assoluto usando il percorso relativo del file e copia il file dalla condivisione locale alla condivisione cloud. Il modulo elimina quindi il file dalla condivisione locale.
Quando il file è nella condivisione cloud, viene caricato automaticamente nell'account di Archiviazione di Azure.
Prerequisiti
Prima di iniziare, verifica di disporre di:
Un dispositivo Azure Stack Edge Pro in esecuzione.
- Il dispositivo ha anche una risorsa dell'hub IoT associata.
- Il dispositivo ha il ruolo di calcolo Edge configurato. Per altre informazioni, vedere Configurare il calcolo per Azure Stack Edge Pro.
Le risorse di sviluppo seguenti:
- Visual Studio Code.
- Estensione C# per Visual Studio Code con tecnologia OmniSharp.
- Azure IoT Edge: estensione per Visual Studio Code.
- .NET Core 2.1 SDK.
- Docker CE. È possibile che sia necessario creare un account per scaricare e installare il software.
Creare un registro contenitori
Un Registro Azure Container è un registro Docker privato in Azure nel quale è possibile archiviare e gestire le immagini del contenitore Docker privato. Due servizi molto diffusi per il registro Docker disponibili nel cloud sono il Registro Azure Container e Hub Docker. Questo articolo usa il Registro contenitori.
Da un browser, eseguire l'allineamento al portale di Azure.
Selezionare Crea un registro contenitori di > risorse>. Cliccare su Crea.
Provider:
Un valore Nome registro all'interno di Azure contenente da 5 a 50 caratteri alfanumerici.
Scegliere un abbonamento.
Scegliere un gruppo di risorse esistente oppure crearne uno nuovo.
Selezionare una località. È consigliabile che questo percorso sia uguale a quello associato alla risorsa Azure Stack Edge.
Impostare Utente amministratore su Abilita.
Impostare lo SKU Di base.
Seleziona Crea.
Dopo aver creato il registro contenitori, passare al registro e selezionare Chiavi di accesso.
Copiare i valori nei campi Server di accesso, Nome utente e Password. Questi valori vengono usati più avanti per pubblicare l'immagine Docker nel registro e per aggiungere le credenziali del registro al runtime di Azure IoT Edge.
Creare un progetto di modulo IoT Edge
La procedura seguente consente di creare un progetto di modulo di IoT Edge basato sull'SDK di.NET Core 2.1. Il progetto usa Visual Studio Code e l'estensione Azure IoT Edge.
Creare una nuova soluzione
Creare un modello di soluzione C# che è possibile personalizzare con il proprio codice.
In Visual Studio Code selezionare Visualizza > riquadro comandi per aprire il riquadro comandi di VS Code.
Nel riquadro comandi immettere ed eseguire il comando Azure: Sign in (Azure: Accedi) e seguire le istruzioni per accedere all'account Azure. Se è stato già effettuato l'accesso, è possibile ignorare questo passaggio.
Nel riquadro comandi immettere ed eseguire il comando Azure IoT Edge: New IoT Edge solution (Azure IoT Edge: Nuova soluzione IoT Edge). Nel riquadro comandi immettere le informazioni seguenti per creare la soluzione:
Selezionare la cartella in cui si vuole creare la soluzione.
Specificare un nome per la soluzione o accettare quello predefinito EdgeSolution.
Scegliere C# Module (Modulo C#) come modello di modulo.
Sostituire il nome del modulo predefinito con il nome che si desidera assegnare, in questo caso, FileCopyModule.
Specificare il registro contenitori creato nella sezione precedente come repository di immagini per il primo modulo. Sostituire localhost:5000 con il valore del server di accesso copiato.
La stringa finale sarà simile a
<Login server name>/<Module name>
. In questo esempio la stringa è:mycontreg2.azurecr.io/filecopymodule
.
Passare a File > Apri cartella.
Trovare e puntare alla cartella EdgeSolution creata in precedenza. La finestra di VS Code carica l'area di lavoro della soluzione IoT Edge con i cinque componenti di livello superiore. Non si modificherà la
.vscode
cartella, il file con estensione gitignore , il file con estensione env e il deployment.template.json** in questo articolo.L'unico componente che verrà modificato è la cartella dei moduli. Questa cartella include il codice C# per il modulo e i file Docker per compilare il modulo come un'immagine del contenitore.
Aggiornare il modulo con il codice personalizzato
Nello strumento di esplorazione di VS Code aprire i moduli > FileCopyModule Program.cs.>
Nella parte superiore dello spazio dei nomi CSharpModule aggiungere le istruzioni using seguenti per i tipi che verranno usati in un secondo momento. Microsoft.Azure.Devices.Client.Transport.Mqtt è un protocollo per inviare messaggi all'hub di IoT Edge.
namespace FileCopyModule { using Microsoft.Azure.Devices.Client.Transport.Mqtt; using Newtonsoft.Json;
Aggiungere la variabile InputFolderPath e OutputFolderPath alla classe Program.
class Program { static int counter; private const string InputFolderPath = "/home/input"; private const string OutputFolderPath = "/home/output";
Subito dopo il passaggio precedente, aggiungere la classe FileEvent per definire il corpo del messaggio.
/// <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; } }
Nel metodo Init il codice crea e configura un oggetto ModuleClient. Questo oggetto consente al modulo di connettersi al runtime locale di Azure IoT Edge tramite il protocollo MQTT per inviare e ricevere messaggi. La stringa di connessione usata nel metodo Init viene specificata nel modulo dal runtime di IoT Edge. Il codice registra un callback FileCopy per ricevere i messaggi da un hub di IoT Edge tramite l'endpoint input1. Sostituire il metodo Init con il codice seguente.
/// <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); }
Rimuovere il codice per il metodo PipeMessage e, al suo posto, inserire il codice per 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; }
Fare clic su Salva per salvare il file.
È anche possibile scaricare un esempio di codice esistente per questo progetto. È quindi possibile convalidare il file salvato nel file program.cs in questo esempio.
Compilare la soluzione IoT Edge
Nella sezione precedente è stata creata una soluzione IoT Edge ed è stato aggiunto il codice a FileCopyModule per copiare i file dalla condivisione locale alla condivisione cloud. È ora necessario compilare la soluzione come immagine del contenitore ed eseguirne il push nel registro contenitori.
In VSCode passare a Terminale > nuovo terminale per aprire un nuovo terminale integrato di Visual Studio Code.
Accedere a Docker immettendo il comando seguente nel terminale integrato.
docker login <ACR login server> -u <ACR username>
Usare il nome utente e il server di accesso copiati prima dal registro contenitori.
Quando richiesto, specificare la password. È anche possibile recuperare i valori per il server di accesso, il nome utente e la password dalle chiavi di accesso nel registro contenitori del portale di Azure.
Dopo aver specificato le credenziali, è quindi possibile eseguire il push dell'immagine del modulo in Registro Azure Container. Nello strumento di esplorazione di VS Code fare clic con il pulsante destro del mouse sul file module.json e scegliere Build and Push IoT Edge solution (Compila ed esegui il push della soluzione IoT Edge).
Quando si richiede di compilare la soluzione, Visual Studio Code esegue due comandi nel terminale integrato: docker build e docker push. Questi due comandi compilano il codice, includono CSharpModule.dll in contenitori e ne eseguono il push nel registro contenitori specificato quando è stata inizializzata la soluzione.
Verrà chiesto di scegliere la piattaforma del modulo. Selezionare amd64 corrispondente a Linux.
Importante
Sono supportati solo i moduli Linux.
È possibile che venga visualizzato l'avviso seguente che può essere ignorato:
Program.cs(77,44): avviso CS1998: Questo metodo asincrono non contiene operatori 'Await', pertanto verrà eseguito in modo sincrono. Provare a usare l'operatore 'await' per attendere chiamate ad API non di blocco oppure 'await Task.Run(...)' per effettuare elaborazioni basate sulla CPU in un thread in background.
È possibile visualizzare l'indirizzo completo dell'immagine del contenitore con tag nel terminale integrato di VS Code. L'indirizzo dell'immagine è costituito dalle informazioni presenti nel file module.json nel formato
<repository>:<version>-<platform>
. In questo articolo, dovrebbe essere simile amycontreg2.azurecr.io/filecopymodule:0.0.1-amd64
.
Passaggi successivi
Per distribuire ed eseguire questo modulo in Azure Stack Edge Pro, vedere la procedura descritta in Aggiungere un modulo.