Incorporación y ejecución de scripts de C# en línea con flujos de trabajo estándar para Azure Logic Apps (versión preliminar)
Se aplica a: Azure Logic Apps (estándar)
Nota:
Esta funcionalidad está en versión preliminar y está sujeta a las Condiciones de uso complementarias para las versiones preliminares de Microsoft Azure.
Para realizar tareas de integración personalizadas insertadas con el flujo de trabajo Estándar en Azure Logic Apps, puede agregar y ejecutar directamente scripts de C# desde el flujo de trabajo. Para esta tarea, use la acción Código insertado denominada Ejecutar código de script CSharp. Esta acción devuelve los resultados del script para que pueda usar esa salida en las acciones posteriores del flujo de trabajo.
Esta funcionalidad proporciona las siguientes ventajas:
Escriba scripts propios en el diseñador de flujos de trabajo para que pueda resolver desafíos de integración más complejos sin tener que usar Azure Functions. No es necesario ningún otro plan de servicio.
Esta ventaja simplifica el desarrollo de flujos de trabajo, además de reducir la complejidad y el costo con la administración de más servicios.
Genere un archivo de código dedicado, que proporciona un espacio de scripting personalizado dentro del flujo de trabajo.
Implemente scripts junto con los flujos de trabajo.
En esta guía se muestra cómo agregar la acción en el flujo de trabajo y agregar el código de script de C# que desea ejecutar.
Requisitos previos
Una cuenta y una suscripción de Azure. Si aún no tiene una, regístrese para obtener una cuenta de Azure gratuita.
Flujo de trabajo de la aplicación lógica estándar donde desea agregar el script de C#. El flujo de trabajo ya debe comenzar con un desencadenador. Para obtener más información, consulte Creación de flujos de trabajo de aplicaciones lógicas estándar de ejemplo.
Puede usar cualquier desencadenador para su escenario, pero como ejemplo, en esta guía se usa el desencadenador Solicitud denominado Cuando se recibe una solicitud HTTP y también la acción Respuesta. El flujo de trabajo se ejecuta cuando otra aplicación o flujo de trabajo envía una solicitud a la dirección URL del punto de conexión del desencadenador. El script de ejemplo devuelve los resultados de la ejecución del código como salida que puede usar en acciones posteriores.
Escenarios de ejemplo
En la lista siguiente se describen algunos escenarios de ejemplo en los que puede usar un script ayuda con determinadas tareas de integración:
Analice y realice transformaciones o manipulaciones en una carga más allá de las funcionalidades integradas de expresiones y operaciones de datos. Por ejemplo, puede usar un script para devolver un esquema modificado para el procesamiento de bajada.
Administre recursos de Azure como máquinas virtuales e inícielos o deténgalos, en función de alguna lógica de negocios.
Ejecute un procedimiento almacenado en un servidor SQL Server que tenga que ejecutarse según una programación y almacenar los resultados en SharePoint.
Registre errores de flujo de trabajo con información detallada guardando en Azure Storage o en el correo electrónico o notificando a su equipo.
Cifre y descifre los datos para cumplir con los estándares de seguridad de API.
Pase un archivo al script para comprimir o descomprimir para una solicitud HTTP.
Agregar datos de varias API y archivos para crear informes diarios
Consideraciones
Azure Portal guarda el script como un archivo de script de C# (.csx) en la misma carpeta que el archivo workflow.json, que almacena la definición JSON para el flujo de trabajo e implementa el archivo en el recurso de la aplicación lógica junto con la definición de flujo de trabajo. Azure Logic Apps compila este archivo para que el script esté listo para su ejecución.
El formato de archivo .csx le permite escribir menos "código reutilizable" y centrarse solo en escribir una función de C#. Puede cambiar el nombre del archivo .csx para facilitar la administración durante la implementación. Sin embargo, cada vez que cambie el nombre del script, la nueva versión sobrescribe la versión anterior.
El script es local para el flujo de trabajo. Para usar el mismo script en otros flujos de trabajo, vea el archivo de script en la consola de KuduPlus y, a continuación, copie el script para reutilizarlo en otros flujos de trabajo.
Limitaciones
Nombre | Límite | Notas |
---|---|---|
Duración de la ejecución del script | 10 minutos | Si tiene escenarios que necesitan duraciones más largas, use la opción de comentarios del producto para proporcionar más información sobre sus necesidades. |
Tamaño de salida | 100 MB | El tamaño de salida depende del límite de tamaño de salida de las acciones, que suele ser de 100 MB. |
Agregar la acción Ejecutar código de script de CSharp
En Azure Portal, abra su recurso de aplicación lógica estándar y el flujo de trabajo en el diseñador.
En el diseñador, siga estos pasos generales para agregar la acción Operaciones de código insertadas denominada Ejecutar código de script CSharp al flujo de trabajo.
Una vez que se abra el panel de información de acción, en la pestaña Parámetros, en el cuadro Archivo de código, actualice el código de ejemplo rellenado previamente con su propio código de script.
En la parte superior del script, importe los espacios de nombres necesarios y agregue las referencias de ensamblado necesarias como de costumbre.
Implemente el método
Run
:El nombre del método
Run
está predefinido y el flujo de trabajo solo se ejecuta llamando a este método Run en tiempo de ejecución.Para acceder a los datos procedentes del flujo de trabajo, el método
Run
acepta estos datos a través de un parámetro con el tipo WorkflowContext. Puede usar el objeto WorkflowContext para las siguientes tareas:Para devolver los resultados del script u otros datos al flujo de trabajo, implemente el método
Run
con un tipo de valor devuelto. Para obtener más información, consulte Devolución de datos al flujo de trabajo.Para registrar la salida del script en C#, implemente el método
Run
para aceptar un registrador de funciones a través de un parámetro con tipoILogger
y uselog
como nombre de argumento para facilitar la identificación. Evite incluirConsole.Write
en el script.Importante
Si tiene un script de ejecución prolongada que requiere una terminación correcta en caso de que se cierre el host de función, incluya un token de cancelación, que es necesario, con el registrador de funciones.
Para obtener más información, consulte las secciones siguientes:
En el ejemplo siguiente se muestra la pestaña Parámetros de la acción con el código de script de ejemplo:
En el ejemplo siguiente se muestra el código de script de ejemplo:
/// 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 obtener más información, vea "#r" - Referencia a ensamblados externos.
Cuando termine, guarde el flujo de trabajo.
Después de ejecutar el flujo de trabajo, puede revisar la salida del flujo de trabajo en Application Insights, si está habilitado. Para más información, vea Visualización de registros en Application Insights.
Importar espacios de nombres
Para importar espacios de nombres, hágalo con la cláusula using
como de costumbre. En la lista siguiente se incluyen los espacios de nombres importados automáticamente, por lo que es opcional incluirlos en el script:
System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading.Tasks
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Incluir referencias a ensamblados externos
Para hacer referencia a ensamblados de .NET Framework, use la directiva #r "<assembly-name>
, por ejemplo:
/// 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
{
<...>
}
En la lista siguiente se incluyen ensamblados agregados automáticamente por el entorno de hospedaje de 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
Salida del registro en una secuencia
En el método Run
, incluya un parámetro con el tipo ILogger
y log
como nombre, por ejemplo:
public static void Run(WorkflowContext context, ILogger log)
{
log.LogInformation($"C# script successfully executed.");
}
Salida del registro en Application Insights
Para crear métricas personalizadas en Application Insights, use el método de extensión LogMetric
en ILogger
.
En el ejemplo siguiente se muestra una llamada de método de ejemplo:
logger.LogMetric("TestMetric", 1234);
Acceso a salidas de desencadenador y acción de flujo de trabajo en el script
Para acceder a los datos del flujo de trabajo, use los métodos siguientes disponibles para el objeto de contexto WorkflowContext
:
Método
GetTriggerResults
Para obtener acceso a las salidas del desencadenador, use este método para devolver un objeto que representa el desencadenador y sus salidas, que están disponibles a través de la propiedad
Outputs
. Este objeto tiene el tipo JObject y puede usar los corchetes ([]) como indizador para acceder a varias propiedades en las salidas del desencadenador.En el ejemplo siguiente se obtienen los datos de la propiedad
body
en las salidas del desencadenador: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 { <...> }
Método
GetActionResults
Para obtener acceso a las salidas de la acción, use este método para devolver un objeto que representa la acción y sus salidas, que están disponibles a través de la propiedad
Outputs
. Este método acepta un nombre de acción como parámetro. En el ejemplo siguiente se obtienen los datos de la propiedadbody
en las salidas de una acción denominada nombre_de_acción: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 { <...> }
Acceso a variables de entorno o valor de configuración de la aplicación
Para obtener una variable de entorno o un valor de configuración de aplicación, use el método System.Environment.GetEnvironmentVariable
, por ejemplo:
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);
}
Devolver datos al flujo de trabajo
Para esta tarea, implemente el método Run
con un tipo de valor devuelto y una instrucción return
. Si quiere una versión asincrónica, implemente el método Run
con un atributo Task<return-type>
y la palabra clave async
. El valor devuelto se establece en la propiedad body
de las salidas de la acción de script, a la que pueden hacer referencia las acciones de flujo de trabajo posteriores.
En el ejemplo siguiente se muestra un método Run
con un atributo Task<Results>
, la palabra clave async
y una instrucción 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;}
}
Visualización del archivo de script
En Azure Portal, abra el recurso de aplicación lógica Estándar que tenga el flujo de trabajo que desee.
En el menú de recursos de la aplicación lógica, en Herramientas de desarrollo, seleccione Herramientas avanzadas.
En la página Herramientas avanzadas, seleccione Ir, lo que abre la consola de KuduPlus.
Abra el menú Consola de depuración y seleccione CMD.
Vaya a la ubicación raíz de la aplicación lógica: sitio/wwwroot
Vaya a la carpeta del flujo de trabajo, que contiene el archivo .csx, en esta ruta de acceso: sitio/wwwroot/{nombre-de-flujo-de-trabajo}
Junto al nombre de archivo, seleccione Editar para abrir y ver el archivo.
Visualización de registros en Application Insights
En Azure Portal, en el menú del recurso de aplicación lógica, en Configuración, seleccione Application Insights y después la aplicación lógica.
En el menú Application Insights, en Supervisión, seleccione Registros.
Cree una consulta para buscar los seguimientos o errores de la ejecución del flujo de trabajo, por ejemplo:
union traces, errors | project TIMESTAMP, message
Errores de compilación
En esta versión, el editor basado en web incluye compatibilidad limitada con IntelliSense, que todavía está en mejora. Se detectan errores de compilación al guardar el flujo de trabajo y el entorno de ejecución de Azure Logic Apps compila el script. Estos errores aparecen en los registros de errores de la aplicación lógica.
Errores en tiempo de ejecución
Si se produce un error cuando se ejecuta el script, Azure Logic Apps realiza estos pasos:
- Vuelve a pasar el error al flujo de trabajo.
- Marca la acción de script como Error.
- Proporciona un objeto de error que representa la excepción producida desde el script.
En el ejemplo siguiente se muestra un error de ejemplo:
Error en la función "CSharp_MyLogicApp-InvalidAction_execute_csharp_script_code.csx" con el error "La acción 'nonexistent' no existe en el flujo de trabajo”. al ejecutar. Compruebe que el código de función es válido.
Scripts de ejemplo
Los siguientes scripts de ejemplo realizan varias tareas que puede
Descomprimir un archivo ZIP con archivos de texto de una acción HTTP en una matriz de cadenas
// 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;
}
Cifrado de datos mediante una clave de la configuración de la aplicación
// 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());
}
}
}
Clase WorkflowContext
Representa un contexto de flujo de trabajo.
Métodos
GetActionResult(string actionName)
Obtiene el resultado de una acción específica en el flujo de trabajo.
La versión asincrónica usa Task<> como tipo de valor devuelto, por ejemplo:
Task<WorkflowOperationResult> GetActionResult(string actionName)
Parámetros
actionName
: nombre de acción.
Devoluciones
La versión asincrónica devuelve un objeto Task
que representa la operación asincrónica. El resultado de la tarea contiene un objeto WorkflowOperationResult
. Para obtener información sobre las propiedades del objeto WorkflowOperationResult, vea la clase WorkflowOperationResult.
RunTriggerResult()
Obtiene el resultado del desencadenador en el flujo de trabajo.
La versión asincrónica usa Task<> como tipo de valor devuelto, por ejemplo:
Task<WorkflowOperationResult> RunTriggerResult()
Parámetros
Ninguno.
Devoluciones
La versión asincrónica devuelve un objeto Task
que representa la operación asincrónica. El resultado de la tarea contiene un objeto WorkflowOperationResult
. Para obtener información sobre las propiedades del objeto WorkflowOperationResult, vea la clase WorkflowOperationResult.
Clase WorkflowOperationResult
Representa el resultado de una operación de flujo de trabajo.
Propiedades
Nombre | Escribir | Descripción |
---|---|---|
Nombre | Cadena | Obtiene o establece el nombre de la operación. |
Entradas | JToken | Obtiene o establece las entradas de ejecución de la operación. |
Salidas | JToken | Obtiene o establece las salidas de ejecución de la operación. |
StartTime | DateTime? | Obtiene o establece la hora de inicio de la operación. |
EndTime | DateTime? | Obtiene o establece la hora de finalización de la operación. |
OperationTrackingId | Cadena | Obtiene o establece el id. de seguimiento de la operación. |
Código | Cadena | Obtiene o establece el código de estado de la acción. |
Estado | Cadena | Obtiene o establece el estado de la acción. |
Error | JToken | Obtiene o establece el error de la acción. |
TrackedProperties | JToken | Obtiene o establece las propiedades con seguimiento de la acción. |