Adicionar e executar scripts C# em linha com fluxos de trabalho padrão para Aplicativos Lógicos do Azure (Visualização)

Aplica-se a: Aplicativos Lógicos do Azure (Padrão)

Nota

Esta funcionalidade está em pré-visualização e está sujeita aos Termos de Utilização Suplementares para Pré-visualizações do Microsoft Azure.

Para executar tarefas de integração personalizadas em linha com seu fluxo de trabalho padrão nos Aplicativos Lógicos do Azure, você pode adicionar e executar scripts C# diretamente de dentro do seu fluxo de trabalho. Para esta tarefa, use a ação Código embutido chamada Executar código de script CSharp. Essa ação retorna os resultados do script para que você possa usar essa saída nas ações subsequentes do fluxo de trabalho.

Esse recurso oferece os seguintes benefícios:

  • Escreva seus próprios scripts no designer de fluxo de trabalho para que você possa resolver desafios de integração mais complexos sem precisar usar o Azure Functions. Não são necessários outros planos de serviço.

    Esse benefício simplifica o desenvolvimento do fluxo de trabalho e reduz a complexidade e o custo com o gerenciamento de mais serviços.

  • Gere um arquivo de código dedicado, que fornece um espaço de script personalizado em seu fluxo de trabalho.

  • Implante scripts junto com seus fluxos de trabalho.

Este guia mostra como adicionar a ação em seu fluxo de trabalho e adicionar o código de script C# que você deseja executar.

Pré-requisitos

  • Uma conta e subscrição do Azure. Se não tiver uma subscrição, inscreva-se numa conta do Azure gratuita.

  • O fluxo de trabalho do aplicativo lógico padrão onde você deseja adicionar seu script C#. O fluxo de trabalho já deve começar com um gatilho. Para obter mais informações, consulte Criar exemplos de fluxos de trabalho de aplicativos lógicos padrão.

    Você pode usar qualquer gatilho para seu cenário, mas, como exemplo, este guia usa o gatilho de solicitação chamado Quando uma solicitação HTTP é recebida e também a ação Resposta . O fluxo de trabalho é executado quando outro aplicativo ou fluxo de trabalho envia uma solicitação para a URL do ponto de extremidade do gatilho. O script de exemplo retorna os resultados da execução de código como saída que você pode usar em ações subsequentes.

Cenários de exemplo

A lista a seguir descreve alguns cenários de exemplo em que você pode usar um script para ajudar em determinadas tarefas de integração:

  • Analise e execute transformações ou manipulações em uma carga útil além das expressões internas e dos recursos de operações de dados. Por exemplo, você pode usar um script para retornar um esquema modificado para processamento downstream.

  • Gerencie recursos do Azure, como máquinas virtuais, e inicie-os ou execute-os, com base em alguma lógica de negócios.

  • Execute um procedimento armazenado em um servidor SQL que precisa ser executado em uma agenda e armazenar os resultados no SharePoint.

  • Registre erros de fluxo de trabalho com informações detalhadas salvando no Armazenamento do Azure ou enviando um email ou notificando sua equipe.

  • Criptografe e descriptografe dados para estar em conformidade com os padrões de segurança da API.

  • Passe um arquivo para o script para compactar ou descompactar para uma solicitação HTTP.

  • Agregar dados de várias APIs e arquivos para criar relatórios diários

Considerações

  • O portal do Azure salva seu script como um arquivo de script C# (.csx) na mesma pasta que o arquivo workflow.json , que armazena a definição JSON para seu fluxo de trabalho e implanta o arquivo no recurso do aplicativo lógico junto com a definição do fluxo de trabalho. Os Aplicativos Lógicos do Azure compilam esse arquivo para tornar o script pronto para execução.

    O formato de arquivo .csx permite que você escreva menos "clichê" e se concentre apenas em escrever uma função C#. Você pode renomear o arquivo .csx para facilitar o gerenciamento durante a implantação. No entanto, cada vez que você renomeia o script, a nova versão substitui a versão anterior.

  • O script é local para o fluxo de trabalho. Para usar o mesmo script em outros fluxos de trabalho, exiba o arquivo de script no console do KuduPlus e copie o script para reutilizar em outros fluxos de trabalho.

Limitações

Nome Limite Notas
Duração da execução do script 10 minutos Se você tiver cenários que precisam de durações maiores, use a opção de feedback do produto para fornecer mais informações sobre suas necessidades.
Tamanho da saída 100 MB O tamanho da saída depende do limite de tamanho de saída para ações, que geralmente é de 100 MB.

Adicionar a ação Executar código de script CSharp

  1. No portal do Azure, abra o recurso e o fluxo de trabalho do aplicativo lógico padrão no designer.

  2. No designer, siga estas etapas gerais para adicionar a ação Inline Code Operations chamada Executar código de script CSharp ao seu fluxo de trabalho.

  3. Depois que o painel de informações da ação for aberto, na guia Parâmetros , na caixa Arquivo de código , atualize o código de exemplo pré-atualizado com seu próprio código de script.

    • Na parte superior do script, importe os namespaces necessários e adicione todas as referências de assembly necessárias como de costume.

    • Implemente o Run método:

      • O Run nome do método é predefinido e seu fluxo de trabalho é executado somente chamando esse método Run em tempo de execução.

      • Para acessar dados provenientes do seu fluxo de trabalho, o Run método aceita esses dados por meio de um parâmetro com o tipo WorkflowContext . Você pode usar o objeto WorkflowContext para as seguintes tarefas:

      • Para retornar os resultados do script ou outros dados ao seu fluxo de trabalho, implemente o Run método com um tipo de retorno. Para obter mais informações, consulte Retornar dados ao seu fluxo de trabalho.

      • Para registrar a saída do script em C#, implemente o Run método para aceitar um registrador de funções por meio de um parâmetro com ILogger tipo e use log como o nome do argumento para facilitar a identificação. Evite incluir Console.Write no seu script.

        Importante

        Se você tiver um script de longa execução que exija terminação normal caso o host da função seja desligado, inclua um token de cancelamento, que é necessário, com seu registrador de funções.

        Para obter mais informações, consulte as seguintes seções:

    O exemplo a seguir mostra a guia Parâmetros da ação com o código de script de exemplo:

    A captura de tela mostra o portal do Azure, o designer de fluxo de trabalho padrão, o gatilho de solicitação, a ação Executar código de script CSharp com o painel de informações aberto e a ação Resposta. O painel Informações mostra um exemplo de script C#.

    O exemplo a seguir mostra o código de script de exemplo:

    /// Add the required libraries.
    #r "Newtonsoft.Json"
    #r "Microsoft.Azure.Workflows.Scripting"
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Microsoft.Extensions.Logging;
    using Microsoft.Azure.Workflows.Scripting;
    using Newtonsoft.Json.Linq;
    
    /// <summary>
    /// Executes the inline C# code.
    /// </summary>
    /// <param name="context">The workflow context.</param>
    /// <remarks> The entry-point to your code. The function signature should remain unchanged.</remarks>
    public static async Task<Results> Run(WorkflowContext context, ILogger log)
    {
        var triggerOutputs = (await context.GetTriggerResults().ConfigureAwait(false)).Outputs;
    
        /// Dereferences the 'name' property from the trigger payload.
        var name = triggerOutputs?["body"]?["name"]?.ToString();
    
        /// To get the outputs from a preceding action, you can uncomment and repurpose the following code.
        // var actionOutputs = (await context.GetActionResults("<action-name>").ConfigureAwait(false)).Outputs;
    
        /// The following logs appear in the Application Insights traces table.
        // log.LogInformation("Outputting results.");
        // var name = null;
    
        return new Results
        {
            Message = !string.IsNullOrEmpty(name) ? $"Hello {name} from CSharp action" : "Hello from CSharp action."
        };
    }
    
    public class Results
    {
        public string Message {get; set;}
    }
    

    Para obter mais informações, consulte "#r" - Fazer referência a assemblies externos.

  4. Quando terminar, salve seu fluxo de trabalho.

Depois de executar o fluxo de trabalho, você pode revisar a saída do fluxo de trabalho no Application Insights, se habilitado. Para obter mais informações, consulte Exibir logs no Application Insights.

Importar namespaces

Para importar namespaces, faça isso com a using cláusula como de costume. A lista a seguir inclui namespaces importados automaticamente, portanto, eles são opcionais para você incluir no script:

System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading.Tasks
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host

Adicionar referências a assemblies externos

Para fazer referência a assemblies do .NET Framework, use a #r "<assembly-name> diretiva , por exemplo:

/// Add the required libraries.
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Workflows.Scripting;
using Newtonsoft.Json.Linq;

public static async Task<Results> Run(WorkflowContext context)
{
    <...>
}

public class Results
{
    <...>
}

A lista a seguir inclui assemblies adicionados automaticamente pelo ambiente de hospedagem do Azure Functions:

mscorlib
System
System.Core
System.Xml
System.Net.Http
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Microsoft.Azure.WebJobs.Extensions
System.Web.Http
System.Net.Http.Formatting
Newtonsoft.Json

Registrar saída em um fluxo

No seu Run método, inclua um parâmetro com ILogger o tipo e log como o nome, por exemplo:

public static void Run(WorkflowContext context, ILogger log)
{
    log.LogInformation($"C# script successfully executed.");
}

Saída de log para o Application Insights

Para criar métricas personalizadas no Application Insights, use o LogMetric método de extensão em ILogger.

O exemplo a seguir mostra uma chamada de método de exemplo:

logger.LogMetric("TestMetric", 1234);

Acesse o gatilho do fluxo de trabalho e as saídas de ação em seu script

Para acessar dados do seu fluxo de trabalho, use os seguintes métodos disponíveis para o WorkflowContext objeto de contexto:

  • GetTriggerResults método

    Para acessar saídas de gatilho, use esse método para retornar um objeto que representa o gatilho e suas saídas, que estão disponíveis através da Outputs propriedade. Este objeto tem o tipo JObject e você pode usar os colchetes ([]) como um indexador para acessar várias propriedades nas saídas do gatilho.

    O exemplo a seguir obtém os dados da body propriedade nas saídas de gatilho:

    public static async Task<Results> Run(WorkflowContext context, ILogger log)
    {
    
        var triggerOutputs = (await context.GetTriggerResults().ConfigureAwait(false)).Outputs;
        var body = triggerOutputs["body"];
    
        return new Results;
    
    }
    
    public class Results
    {
        <...>
    }
    
  • GetActionResults método

    Para acessar saídas de ação, use esse método para retornar um objeto que representa a ação e suas saídas, que estão disponíveis por meio da Outputs propriedade. Este método aceita um nome de ação como um parâmetro. O exemplo a seguir obtém os dados da body propriedade nas saídas de uma ação chamada action-name:

    public static async Task<Results> Run(WorkflowContext context, ILogger log)
    {
    
        var actionOutputs = (await context.GetActionResults("action-name").ConfigureAwait(false)).Outputs;
        var body = actionOutputs["body"];
    
        return new Results;
    
    }
    
    public class Results
    {
        <...>
    }
    

Variáveis de ambiente do Access ou valor de configuração do aplicativo

Para obter uma variável de ambiente ou um valor de configuração de aplicativo, use o System.Environment.GetEnvironmentVariable método, por exemplo:

public static void Run(WorkflowContext context, ILogger log)
{
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
    log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
    log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}

public static string GetEnvironmentVariable(string name)
{
    return name + ": " +
    System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}

Retornar dados ao seu fluxo de trabalho

Para esta tarefa, implemente seu Run método com um tipo de retorno e return instrução. Se você quiser uma versão assíncrona, implemente o Run método com um Task<return-type> atributo e a async palavra-chave. O valor de retorno é definido como a propriedade outputs da ação de script, que qualquer ação de fluxo de body trabalho subsequente pode referenciar.

O exemplo a seguir mostra um Run método com um Task<Results> atributo, a async palavra-chave e uma return instrução:

public static async Task<Results> Run(WorkflowContext context, ILogger log)
{
    return new Results
    {
        Message = !string.IsNullOrEmpty(name) ? $"Returning results with status message."
    };
}

public class Results
{
    public string Message {get; set;}
}

Exibir o arquivo de script

  1. No portal do Azure, abra seu recurso de aplicativo lógico padrão que tem o fluxo de trabalho desejado.

  2. No menu de recursos do aplicativo lógico, em Ferramentas de Desenvolvimento, selecione Ferramentas Avançadas.

  3. Na página Ferramentas Avançadas, selecione Ir, que abre o console KuduPlus.

  4. Abra o menu Depurar console e selecione CMD.

  5. Vá para o local raiz do seu aplicativo lógico: site/wwwroot

  6. Vá para a pasta do seu fluxo de trabalho, que contém o arquivo .csx, ao longo deste caminho: site/wwwroot/{workflow-name}

  7. Ao lado do nome do arquivo, selecione Editar para abrir e exibir o arquivo.

Exibir logs no Application Insights

  1. No portal do Azure, no menu de recursos do aplicativo lógico, em Configurações, selecione Application Insights e selecione seu aplicativo lógico.

  2. No menu Application Insights, em Monitoramento, selecione Logs.

  3. Crie uma consulta para localizar quaisquer vestígios ou erros da execução do fluxo de trabalho, por exemplo:

    union traces, errors
    | project TIMESTAMP, message
    

Erros de compilação

Nesta versão, o editor baseado na Web inclui suporte limitado ao IntelliSense, que ainda está em melhoria. Quaisquer erros de compilação são detetados quando você salva seu fluxo de trabalho, e o tempo de execução dos Aplicativos Lógicos do Azure compila seu script. Esses erros aparecem nos logs de erros do seu aplicativo lógico.

Erros de tempo de execução

Se ocorrer um erro quando o script for executado, os Aplicativos Lógicos do Azure executarão estas etapas:

  • Passa o erro de volta para o seu fluxo de trabalho.
  • Marca a ação de script como Falha.
  • Fornece um objeto de erro que representa a exceção lançada do script.

O exemplo a seguir mostra um erro de exemplo:

A função 'CSharp_MyLogicApp-InvalidAction_execute_csharp_script_code.csx' falhou com o erro 'A ação 'inexistente' não existe no fluxo de trabalho'. ao executar. Verifique se o código da função é válido.

Scripts de exemplo

Os scripts de exemplo a seguir executam várias tarefas que você pode

Descompactar um arquivo ZIP com arquivos de texto de uma ação HTTP em uma matriz de cadeia de caracteres

// Add the required libraries.
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Azure.Workflows.Scripting;
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Collections.Generic;

/// <summary>
/// Executes the inline C# code.
/// </summary>
/// <param name="context">The workflow context.</param>
public static async Task<List<string>> Run(WorkflowContext context)
{

    var outputs = (await context.GetActionResults("HTTP_1").ConfigureAwait(false)).Outputs;
    var base64zipFileContent = outputs["body"]["$content"].ToString();

    // Decode base64 to bytes.
    byte[] zipBytes = Convert.FromBase64String(base64zipFileContent);

    List<string> fileContents = new List<string>();

    // Creates an in-memory stream from the zip bytes.
    using (MemoryStream zipStream = new MemoryStream(zipBytes))
    {

        // Extracts files from the zip archive.
        using (ZipArchive zipArchive = new ZipArchive(zipStream))
        {

            foreach (ZipArchiveEntry entry in zipArchive.Entries)
            {

                // Read each file's content.
                using (StreamReader reader = new StreamReader(entry.Open()))
                {
                    string fileContent = reader.ReadToEnd();
                    fileContents.Add(fileContent);
                }
            }
        }
    }

    return fileContents;
}

Criptografar dados usando uma chave das configurações do aplicativo

// Add the required libraries.
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Azure.Workflows.Scripting;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// Executes the inline csharp code.
/// </summary>
/// <param name="context">The workflow context.</param>
public static async Task<string> Run(WorkflowContext context)
{

    var compose = (await context.GetActionResults("compose").ConfigureAwait(false)).Outputs;
    var text = compose["sampleData"].ToString();

    return EncryptString(text);

}

public static string EncryptString(string plainText)
{

    var key = Environment.GetEnvironmentVariable("app-setting-key");
    var iv = Environment.GetEnvironmentVariable("app-setting-iv");

    using (Aes aesAlg = Aes.Create())
    {

        aesAlg.Key = Encoding.UTF8.GetBytes(key);
        aesAlg.IV = Encoding.UTF8.GetBytes(iv);
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msEncrypt = new MemoryStream())
        {

            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {

                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                }

            }

             return Convert.ToBase64String(msEncrypt.ToArray());

        }
    }
}

Classe WorkflowContext

Representa um contexto de fluxo de trabalho.

Métodos

GetActionResult(string actionName)

Obtém o resultado de uma ação específica no fluxo de trabalho.

A versão assíncrona usa Task<> como o tipo de retorno, por exemplo:

Task<WorkflowOperationResult> GetActionResult(string actionName)

Parâmetros

actionName: O nome da ação.

Devoluções

A versão assíncrona retorna um Task objeto que representa a operação assíncrona. O resultado da tarefa contém um WorkflowOperationResult objeto. Para obter informações sobre as propriedades do objeto WorkflowOperationResult , consulte Classe WorkflowOperationResult.

RunTriggerResult()

Obtém o resultado do gatilho no fluxo de trabalho.

A versão assíncrona usa Task<> como o tipo de retorno, por exemplo:

Task<WorkflowOperationResult> RunTriggerResult()

Parâmetros

Nenhum.

Devoluções

A versão assíncrona retorna um Task objeto que representa a operação assíncrona. O resultado da tarefa contém um WorkflowOperationResult objeto. Para obter informações sobre as propriedades do objeto WorkflowOperationResult , consulte Classe WorkflowOperationResult.

Classe WorkflowOperationResult

Representa o resultado de uma operação de fluxo de trabalho.

Propriedades

Nome Tipo Description
Nome Cadeia (de carateres) Obtém ou define o nome da operação.
Insumos JToken Obtém ou define as entradas de execução da operação.
Saídas JToken Obtém ou define as saídas de execução da operação.
Horário de Início DateTime? Obtém ou define a hora de início da operação.
Tempo de Fim DateTime? Obtém ou define a hora de término da operação.
OperationTrackingId String Obtém ou define o ID de acompanhamento da operação.
Código String Obtém ou define o código de status para a ação.
Status String Obtém ou define o status da ação.
Erro JToken Obtém ou define o erro para a ação.
TrackedProperties JToken Obtém ou define as propriedades controladas para a ação.

Adicionar e executar trechos de código JavaScript