Tutorial: Armazenar dados na periferia com bases de dados do SQL Server

Aplica-se a:IoT Edge IoT Edge de marca de verificação 1,1IoT Edge 1,2 IoT Edge 1,2 IoT Edge 1,3 IoT Edge 1,3 IoT Edge 1,4 IoT Edge 1.4

Implemente um módulo SQL Server para armazenar dados num dispositivo que executa o Azure IoT Edge com recipientes Linux.

Utilize o Azure IoT Edge e o SQL Server para armazenar e consultar dados na periferia. O Azure IoT Edge tem capacidades básicas de armazenamento para cache mensagens se um dispositivo ficar offline e, em seguida, encaminhá-las quando a ligação for restabelecida. No entanto, pode querer capacidades de armazenamento mais avançadas, como a capacidade de consultar dados localmente. Os seus IoT Edge dispositivos podem utilizar bases de dados locais para realizar computação mais complexa sem ter de manter uma ligação com Hub IoT.

Este artigo fornece instruções para implementar uma base de dados do SQL Server num dispositivo IoT Edge. As Funções do Azure, em execução no dispositivo IoT Edge, estruturam os dados recebidos e, em seguida, envia-os para a base de dados. Os passos neste artigo também podem ser aplicados a outras bases de dados que funcionam em contentores, como o MySQL ou o PostgreSQL.

Neste tutorial, ficará a saber como:

  • Utilize o Visual Studio Code para criar uma função do Azure
  • Implementar uma base de dados do SQL Server no seu dispositivo IoT Edge
  • Utilize o Visual Studio Code para criar módulos e implementá-los no seu dispositivo IoT Edge
  • Ver os dados gerados

Se não tiver uma subscrição do Azure, crie uma conta Azure gratuita antes de começar.

Pré-requisitos

Antes de iniciar este tutorial, você deveria ter passado pelo tutorial anterior para configurar o seu ambiente de desenvolvimento para o desenvolvimento de recipientes Linux: Desenvolver IoT Edge módulos para dispositivos Linux. Ao completar este tutorial, deverá ter os seguintes pré-requisitos no lugar:

Este tutorial utiliza um módulo Funções do Azure para enviar dados para o SQL Server. Para desenvolver um módulo IoT Edge com Funções do Azure, instale os seguintes pré-requisitos adicionais na sua máquina de desenvolvimento:

Criar um projeto de função

Para enviar dados numa base de dados, precisa de um módulo que possa estruturar corretamente os dados e, em seguida, armazená-los numa tabela.

Criar um novo projeto

Os passos a seguir mostram como criar uma função IoT Edge utilizando o Código do Estúdio Visual e o Azure IoT Tools.

  1. Abra o Visual Studio Code.

  2. Abra a paleta de comandos VS Code selecionando apaleta de comandodo View>.

  3. Na paleta de comandos, escreva e execute o comando Azure IoT Edge: Nova solução do IoT Edge. Na paleta de comandos, indique as seguintes informações para criar a sua solução:

    Campo Valor
    Selecionar pasta Escolha a localização no computador de desenvolvimento na qual o VS Code vai criar os ficheiros da solução.
    Indicar um nome para a solução Introduza um nome descritivo para a sua solução, como SqlSolution, ou aceite o padrão.
    Selecionar modelo de módulo Escolha Funções do Azure - C#.
    Indicar um nome para o módulo Atribua o nome sqlFunction ao módulo.
    Indicar o repositório de imagens do Docker para o módulo Os repositórios de imagens incluem o nome do seu registo de contentor e o nome da sua imagem de contentor. A imagem de contentor é pré-preenchida no passo anterior. Substitua o local:5000 pelo valor do servidor de login do registo do seu contentor Azure. Pode recuperar o servidor 'Início de Sessão' na página 'Vista Geral' do registo do seu contentor no portal do Azure.

    A corda final parece <o nome> do registo.azurecr.io/sqlfunction.

    A janela do VS Code carrega a área de trabalho da solução do IoT Edge.

Adicionar as credenciais do registo

O ficheiro de ambiente armazena as credenciais do seu registo de contentor e partilha-as com o runtime do IoT Edge. O runtime precisa destas credenciais para solicitar as imagens privadas para o dispositivo IoT Edge.

A extensão IoT Edge tenta retirar as credenciais de registo do seu contentor do Azure e povoá-las no ficheiro ambiente. Verifique se as suas credenciais já estão incluídas. Caso contrário, adicione-os agora:

  1. No explorador do VS Code, abra o ficheiro .env.
  2. Atualize os campos com os valores nome de utilizador e palavra-passe que copiou do seu Azure Container Registry.
  3. Guarde este ficheiro.

Nota

Este tutorial usa credenciais de login de administração para Azure Container Registry, que são convenientes para cenários de desenvolvimento e teste. Quando estiver pronto para cenários de produção, recomendamos uma opção de autenticação de menor privilégio, como os principais de serviço. Para mais informações, consulte Gerir o acesso ao registo do seu contentor.

Selecione a sua arquitetura-alvo

Você precisa selecionar qual arquitetura você está dirigindo com cada solução, porque o recipiente é construído e executado de forma diferente para cada tipo de arquitetura. O padrão é Linux AMD64.

  1. Abra a paleta de comando e procure IoT Edge Azure: Definir Plataforma-alvo Padrão para solução de borda ou selecione o ícone de atalho na barra lateral na parte inferior da janela.

  2. Na paleta de comando, selecione a arquitetura-alvo da lista de opções. Para este tutorial, estamos a usar uma máquina virtual Ubuntu como o dispositivo IoT Edge, por isso manteremos o amd64 padrão.

Atualizar o módulo com o código personalizado

  1. No explorador de código VS, abra os módulos>sqlFunction>sqlFunction.csproj.

  2. Encontre o grupo de referências de pacotes e adicione um novo para incluir o SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. Guarde o ficheiro sqlFunction.csproj .

  4. Abra o ficheiro sqlFunction.cs .

  5. Substitua todo o conteúdo do ficheiro pelo seguinte código:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Sql = System.Data.SqlClient;
    
    namespace Functions.Samples
    {
        public static class sqlFunction
        {
            [FunctionName("sqlFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    //Store the data in SQL db
                    const string str = "<sql connection string>";
                    using (Sql.SqlConnection conn = new Sql.SqlConnection(str))
                    {
                        conn.Open();
                        var insertMachineTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'machine', " + messageBody.machine.temperature + ");";
                        var insertAmbientTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'ambient', " + messageBody.ambient.temperature + ");";
                        using (Sql.SqlCommand cmd = new Sql.SqlCommand(insertMachineTemperature + "\n" + insertAmbientTemperature, conn))
                        {
                            //Execute the command and log the # rows affected.
                            var rows = await cmd.ExecuteNonQueryAsync();
                            logger.LogInformation($"{rows} rows were updated");
                        }
                    }
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threashold.
                        using (var filteredMessage = new Message(messageBytes))
                        {
                             // Copy the properties of the original message into the new Message object.
                             foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                             {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                             // Add a new property to the message to indicate it is an alert.
                             filteredMessage.Properties.Add("MessageType", "Alert");
                             // Send the message.
                             await output.AddAsync(filteredMessage);
                             logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                        }
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        class MessageBody
        {
            public Machine machine {get; set;}
            public Ambient ambient {get; set;}
            public string timeCreated {get; set;}
        }
        class Machine
        {
            public double temperature {get; set;}
            public double pressure {get; set;}
        }
        class Ambient
        {
            public double temperature {get; set;}
            public int humidity {get; set;}
        }
    }
    
  6. Na linha 35, substitua a corda> de ligação de sql de corda< com a seguinte corda. A propriedade Data Source refere-se ao SQL Server contentor, que ainda não existe. Irá criá-lo com o nome SQL na secção seguinte.

    Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=Strong!Passw0rd;TrustServerCertificate=False;Connection Timeout=30;
    
  7. Guarde o ficheiro sqlFunction.cs .

Adicione o recipiente SQL Server

Um Manifesto de implementação declara os módulos que o runtime do IoT Edge irá instalar no seu dispositivo IoT Edge. Forneceu o código para fazer um módulo de Função personalizado na secção anterior, mas o módulo SQL Server já está construído e disponível no Azure Marketplace. Apenas tem de indicar ao runtime do IoT Edge para o incluir e configurar no seu dispositivo.

  1. No Código do Estúdio Visual, abra a paleta de comando selecionando apaleta de Comandover>.

  2. Na paleta de comando, escreva e execute o IoT Edge de comando Azure: Adicione IoT Edge módulo. Na paleta de comando, forneça as seguintes informações para adicionar um novo módulo:

    Campo Valor
    Selecione o ficheiro de modelo da implementação A paleta de comando realça o ficheiro deployment.template.json na sua pasta de solução atual. Selecione o ficheiro.
    Selecionar modelo de módulo Selecione o Módulo de Azure Marketplace.
  3. No mercado de módulos Azure IoT Edge, procure e selecione SQL Server Módulo.

  4. Mude o nome do módulo para sql, todos os minúsculos. Este nome corresponde ao nome do recipiente declarado na cadeia de ligação no ficheiro sqlFunction.cs.

  5. Selecione Importar para adicionar o módulo à sua solução.

  6. Na sua pasta de solução, abra o ficheiro deployment.template.json .

  7. Encontre a secção de módulos . Devia ver três módulos. O módulo SimulatedTemperatureSensor está incluído por padrão em novas soluções e fornece dados de teste para utilizar com os seus outros módulos. O módulo sqlFunction é o módulo que inicialmente criou e atualizou com novo código. Finalmente, o módulo sql foi importado do Azure Marketplace.

    Dica

    O módulo SQL Server vem com uma senha padrão definida nas variáveis ambientais do manifesto de implementação. Sempre que criar um contentor do SQL Server num ambiente de produção, deve alterar a palavra-passe de administrador do sistema predefinida.

  8. Feche o ficheiro deployment.template.json .

Criar a sua solução do IoT Edge

Nas secções anteriores, criou uma solução com um módulo e, em seguida, adicionou outra ao modelo de manifesto de implementação. O módulo SQL Server é hospedado publicamente por Microsoft, mas é necessário contentorizar o código no módulo Funções. Nesta secção, constrói a solução, cria imagens de contentores para o módulo sqlFunction e empurra a imagem para o registo do seu contentor.

  1. No Código do Estúdio Visual, abra o terminal integrado selecionando o View>Terminal.

  2. Inicie sessão no seu registo de contentor do Visual Studio Code para que possa enviar as imagens para o seu registo. Utilize as mesmas credenciais Azure Container Registry (ACR) que adicionou ao ficheiro .env. Introduza o seguinte comando no terminal integrado:

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

    Pode ver um aviso de segurança recomendando a utilização do parâmetro --password-stdin. Enquanto a sua utilização está fora do âmbito deste artigo, recomendamos que siga esta melhor prática. Para obter mais informações, consulte a referência de comando de login do estivador .

  3. No explorador de código VS, clique com o botão direito no ficheiro implementação.template.json e selecione Construir e empurrar IoT Edge solução.

    O comando de construção e pressão inicia três operações. Em primeiro lugar, cria uma nova pasta na solução chamada config que detém o manifesto de implantação completo, que é construído a partir de informações no modelo de implementação e outros ficheiros de solução. Em segundo lugar, funciona docker build para construir a imagem do contentor com base no arquivo apropriado para a sua arquitetura alvo. Em seguida, corre docker push para empurrar o repositório de imagem para o seu registo de contentores.

    Este processo pode demorar vários minutos na primeira vez, mas é mais rápido da próxima vez que executar os comandos.

    Pode verificar se o módulo sqlFunction foi empurrado com sucesso para o registo do seu contentor. Na portal do Azure, navegue para o seu registo de contentores. Selecione repositórios e procure sqlFunction. Os outros dois módulos, SimulatedTemperatureSensor e sql, não serão empurrados para o registo do seu contentor porque os seus repositórios já estão nos registos Microsoft.

Implementar a solução num dispositivo

Pode definir módulos num dispositivo através do Hub IoT, mas também pode aceder o seu Hub IoT e dispositivos através do Visual Studio Code. Nesta secção, pode configurar o acesso ao Hub IoT e, em seguida, utilizar o VS Code para implementar a solução no seu dispositivo IoT Edge.

  1. No explorador visual Studio Code, na secção Hub IoT do Azure, expanda os Dispositivos para ver a sua lista de dispositivos IoT.

  2. Clique com o botão direito no dispositivo que pretende atingir com a sua implementação e selecione Criar Implementação para Dispositivo Único.

  3. Selecione o ficheiro deployment.amd64.json na pasta config e, em seguida, clique em Select Edge Deployment Manifest. Não utilize o ficheiro deployment.template.json.

  4. Sob o seu dispositivo, expanda os Módulos para ver uma lista de módulos implantados e em funcionamento. Clique no botão Atualizar. Deverá ver os novos módulos sql e sqlFunction a funcionar juntamente com o módulo SimulaçãoTemperatureSensor e o $edgeAgent e $edgeHub.

    Também pode verificar se todos os módulos estão em execução no seu dispositivo. No dispositivo IoT Edge, execute o seguinte comando para ver o estado dos módulos.

    iotedge list
    

    Pode levar alguns minutos para os módulos começarem. O IoT Edge tempo de execução precisa de receber o seu novo manifesto de implantação, retirar as imagens do módulo do tempo de funcionamento do contentor e, em seguida, iniciar cada novo módulo.

Criar uma base de dados SQL

Ao aplicar o manifesto de implementação ao seu dispositivo, obtém três módulos em execução. O módulo SimuladoTemperatureSensor gera dados de ambiente simulados. O módulo sqlFunction utiliza os dados e formata-os para uma base de dados. Esta secção orienta-o na configuração da base de dados do SQL Server para armazenar os dados de temperatura.

Execute os seguintes comandos no seu dispositivo IoT Edge. Estes comandos ligam-se ao módulo sql em funcionamento no seu dispositivo e criam uma base de dados e uma tabela para conter os dados de temperatura que lhe são enviados.

  1. Numa ferramenta de linha de comando no seu dispositivo IoT Edge, ligue-se à sua base de dados.

    sudo docker exec -it sql bash
    
  2. Abra a ferramenta de comandos SQL.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'Strong!Passw0rd'
    
  3. Criar a base de dados:

    CREATE DATABASE MeasurementsDB
    ON
    (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf')
    GO
    
  4. Defina a tabela.

    CREATE TABLE MeasurementsDB.dbo.TemperatureMeasurements (measurementTime DATETIME2, location NVARCHAR(50), temperature FLOAT)
    GO
    

Pode personalizar o ficheiro de docker do SQL Server para configurar automaticamente o SQL Server para ser implementado em vários dispositivos IoT Edge. Para obter mais informações, veja o Projeto de demonstração de contentor do Microsoft SQL Server.

Ver os dados locais

Assim que a tabela for criada, o módulo sqlFunction começa a armazenar os dados numa base de dados local do SQL Server 2017 no seu dispositivo IoT Edge.

A partir da ferramenta de comandos SQL, execute o seguinte comando para ver os dados de tabela formatados:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

Ver conteúdo da base de dados local

Limpar os recursos

Se planeia avançar para o próximo artigo recomendado, pode manter os recursos e as configurações que criou e reutilizá-los. Também pode continuar a utilizar o mesmo dispositivo IoT Edge como um dispositivo de teste.

Caso contrário, pode eliminar as configurações locais e os recursos do Azure que criou neste artigo para evitar custos.

Eliminar recursos do Azure

A eliminação de recursos e grupos de recursos do Azure é irreversível. Confirme que não elimina acidentalmente o grupo de recursos ou recursos errados. Se criou o hub IoT dentro de um grupo de recursos existente que tem recursos que pretende manter, elimine apenas o próprio recurso do hub IoT, e não o grupo de recursos.

Para eliminar os recursos:

  1. Inicie sessão no Portal do Azure e selecione Grupos de recursos.

  2. Selecione o nome do grupo de recursos que contém os recursos de teste do IoT Edge.

  3. Reveja a lista de recursos que estão contidos no seu grupo de recursos. Se quiser eliminá-los todos, pode selecionar Eliminar grupo de recursos. Se quiser eliminar apenas alguns dos recursos, pode clicar em cada um para eliminá-los individualmente.

Neste tutorial, criou um módulo das Funções do Azure que contém código para filtrar dados não processados gerados pelo seu dispositivo IoT Edge. Quando estiver pronto para construir os seus próprios módulos, poderá aprender mais sobre como desenvolver Funções do Azure com o Azure IoT Edge para o Código do Estúdio Visual.

Passos seguintes

Se quiser experimentar outro método de armazenamento na borda, leia como usá Armazenamento de Blobs do Azure no IoT Edge.