Adicionar e executar scripts C# embutidos com fluxos de trabalho Standard para Aplicativos Lógicos do Azure (Versão Prévia)
Aplica-se a: Aplicativos Lógicos do Azure (Standard)
Observação
Esse recurso está em versão prévia e está sujeito aos Termos de uso suplementares para versões prévias do Microsoft Azure.
Para executar tarefas de integração personalizadas embutidas com seu fluxo de trabalho Standard nos Aplicativos Lógicos do Azure, você pode adicionar e executar diretamente scripts C# diretamente do seu fluxo de trabalho. Para essa 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 posteriores do fluxo de trabalho.
Essa funcionalidade fornece os seguintes benefícios:
Escreva seus próprios scripts dentro do designer de fluxo de trabalho para resolver problemas 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 de 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 oferece um espaço personalizado para scripts dentro do 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 uma assinatura do Azure. Se você não tem uma assinatura, inscreva-se em uma conta gratuita do Azure.
O fluxo de trabalho do aplicativo lógico Standard ao qual você deseja adicionar seu script C#. O fluxo de trabalho já precisa começar com um gatilho. Para obter mais informações, consulte Criar exemplos de fluxos de trabalho do aplicativo lógico Standard.
Você pode usar qualquer gatilho para seu cenário, mas, como exemplo, este guia usa o gatilho Solicitar 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 do código como saída que você pode usar em ações posteriores.
Cenários de exemplo
A lista a seguir descreve alguns cenários de exemplo em que o uso de um script ajuda com determinadas tarefas de integração:
Analise e execute transformações ou manipulações em um conteúdo 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 em etapas com base em alguma lógica de negócios.
Execute um procedimento armazenado em um SQL Server que precisa ser executado em um agendamento e armazene os resultados no SharePoint.
Registre erros de fluxo de trabalho com informações detalhadas salvando no Armazenamento do Microsoft Azure, enviando um email ou notificando sua equipe.
Criptografe e descriptografe dados para atender aos padrões de segurança da API.
Passe um arquivo para o script para compactar ou descompactar 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 de aplicativo lógico junto com a definição de fluxo de trabalho. Os Aplicativos Lógicos do Azure compilam esse arquivo para preparar o script para execução.
O formato de arquivo .csx permite que você escreva menos "código clichê" e concentre-se apenas em escrever uma função em C#. Você pode renomear o arquivo .csx para facilitar o gerenciamento durante a implantação. No entanto, sempre 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 reutilizá-lo em outros fluxos de trabalho.
Limitações
Nome | Limit | Observações |
---|---|---|
Duração da execução do script | 10 minutos | Se você tiver cenários que precisam de durações mais longas, use a opção de comentários 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
No portal do Azure, abra o recurso de aplicativo lógico Standard e o fluxo de trabalho no designer.
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é-preenchido com seu próprio código de script.
Na parte superior do script, importe os namespaces necessários e adicione as referências de assembly necessárias como de costume.
Implemente o método
Run
:O nome do método
Run
é predefinido e seu fluxo de trabalho é executado apenas chamando esse método Executar em runtime.Para acessar dados provenientes do fluxo de trabalho, o método
Run
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 fluxo de trabalho, implemente o método
Run
com um tipo de retorno. Para obter mais informações, consulte Retornar dados ao fluxo de trabalho.Para registrar a saída do script em C#, implemente o método
Run
para aceitar um agente de função por meio de um parâmetro com o tipoILogger
e uselog
como o nome do argumento para facilitar a identificação. Evite incluirConsole.Write
em seu script.Importante
Se você tiver um script de execução longa que exija um término amigável caso o host de função seja desligado, inclua um token de cancelamento, que é obrigatório, com o agente de função.
Para obter mais informações, consulte as seções a seguir:
O exemplo a seguir mostra a guia Parâmetros da ação com o código de script de exemplo:
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" – Referenciar assemblies externos.
Quando terminar, salve o fluxo de trabalho.
Depois de executar o seu fluxo de trabalho, você pode analisar a saída no Application Insights, caso esteja habilitado. Para obter mais informações, confira Exibir logs no Application Insights.
Importar namespaces
Importe namespaces com a cláusula using
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 diretiva #r "<assembly-name>
, 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
Saída de log para um fluxo
Em seu método Run
, inclua um parâmetro com o tipo ILogger
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 usar métricas personalizadas no Application Insights, use o método de extensão LogMetric
em ILogger
.
O exemplo a seguir mostra uma chamada de método de exemplo:
logger.LogMetric("TestMetric", 1234);
Acessar o gatilho de fluxo de trabalho e as saídas de ação em seu script
Para acessar dados do fluxo de trabalho, use os seguintes métodos disponíveis para o objeto de contexto WorkflowContext
:
GetTriggerResults
métodoPara 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 por meio da propriedade
Outputs
. Esse objeto tem o tipo JObject e você pode usar colchetes ([]) como um indexador para acessar várias propriedades nas saídas do gatilho.O exemplo a seguir obtém os dados da propriedade
body
nas saídas do 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étodoPara 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 propriedade
Outputs
. Esse método aceita um nome de ação como um parâmetro. O exemplo a seguir obtém os dados da propriedadebody
nas saídas de uma ação chamada nome-da-ação: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 { <...> }
Acessar variáveis de ambiente ou valor de configuração do aplicativo
Para obter uma variável de ambiente ou um valor de configuração do aplicativo, use o método System.Environment.GetEnvironmentVariable
, 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 fluxo de trabalho
Para essa tarefa, implemente o método Run
com um tipo de retorno e uma instrução return
. Se você quiser uma versão assíncrona, implemente o método Run
com um atributo Task<return-type>
e a palavra-chave async
. O valor de retorno é atribuído à propriedade body
das saídas da ação de script, que qualquer ação de fluxo de trabalho posterior poderá referenciar.
O exemplo a seguir mostra um método Run
com um atributo Task<Results>
, a palavra-chave async
e uma instrução return
:
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
No portal do Azure, abra o recurso de aplicativo lógico Standard que tem o fluxo de trabalho desejado.
No menu do aplicativo lógico, acesse Ferramentas de Desenvolvimento e selecione Ferramentas Avançadas.
Na página Ferramentas Avançadas, selecione Ir, que abrirá o console do KuduPlus.
Abra o menu Depurar console e selecione CMD.
Vá para o local da raiz do aplicativo lógico: site/wwwroot
Vá para a pasta do fluxo de trabalho, que contém o arquivo .csx, neste caminho: site/wwwroot/{workflow-name}
Ao lado do nome do arquivo, selecione Editar para abrir e exibir o arquivo.
Exibir logs no Application Insights
No portal do Azure, no menu de recursos do aplicativo lógico, em Configurações, selecione Application Insights e, em seguida, escolha o seu aplicativo lógico.
No menu Application Insights, em Monitoramento, selecione Logs.
Crie uma consulta para localizar os rastreamentos ou erros provenientes da execução do seu 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 do IntelliSense, que ainda está em aperfeiçoamento. Todos os erros de compilação são detectados quando você salva o fluxo de trabalho, e o runtime dos Aplicativos Lógicos do Azure compila seu script. Esses erros aparecem nos logs de erros do aplicativo lógico.
Erros de runtime
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 fluxo de trabalho.
- Marca a ação do script como De falha.
- Fornece um objeto de erro que representa a exceção gerada do script.
O exemplo a seguir mostra um parâmetro 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 objeto Task
que representa a operação assíncrona. O resultado da tarefa contém um objeto WorkflowOperationResult
. Para obter informações sobre as propriedades do objeto WorkflowOperationResult, consulte a 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 objeto Task
que representa a operação assíncrona. O resultado da tarefa contém um objeto WorkflowOperationResult
. Para obter informações sobre as propriedades do objeto WorkflowOperationResult, consulte a classe WorkflowOperationResult.
Classe WorkflowOperationResult
Representa o resultado de uma operação de fluxo de trabalho.
Propriedades
Nome | Tipo | Descrição |
---|---|---|
Nome | String | Obtém ou define o nome da operação. |
Entradas | 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. |
StartTime | DateTime? | Obtém ou define a hora de início da operação. |
EndTime | DateTime? | Obtém ou define a hora de término da operação. |
OperationTrackingId | String | Obtém ou define a ID de acompanhamento da operação. |
Código | String | Obtém ou define o código de status da ação. |
Status | String | Obtém ou define o status da ação. |
Erro | JToken | Obtém ou define o erro da ação. |
TrackedProperties | JToken | Obtém ou define as propriedades acompanhadas da ação. |