Azure Logic Apps の標準ワークフローを使用して C# スクリプトをインラインで追加して実行する (プレビュー)

適用対象: Azure Logic Apps (Standard)

Note

この機能はプレビュー段階にあり、「Microsoft Azure プレビューの追加使用条件」が適用されます。

Azure Logic Apps で標準ワークフローを使用してインラインでカスタム統合タスクを実行するには、ワークフロー内から C# スクリプトを直接追加して実行できます。 このタスクでは、CSharp スクリプトコードの実行という名前のインライン コード アクションを使用します。 このアクションはスクリプトから結果を返すので、その出力をワークフローの後続のアクションで使用できます。

この機能には、次の利点があります。

  • Azure Functions を使用しなくても、より複雑な統合の課題を解決できるように、ワークフロー デザイナー内で独自のスクリプトを記述します。 他のサービス プランは必要ありません。

    この利点により、ワークフロー開発が合理化され、より多くのサービスを管理する複雑さとコストが削減されます。

  • 専用のコード ファイルを生成します。このファイルは、ワークフロー内でカスタマイズされたスクリプト領域を提供します。

  • ワークフローと共にスクリプトをデプロイします。

このガイドでは、ワークフローにアクションを追加し、実行する C# スクリプト コードを追加する方法について説明します。

前提条件

  • Azure アカウントとサブスクリプション。 サブスクリプションをお持ちでない場合には、無料の Azure アカウントにサインアップしてください。

  • C# スクリプトを追加する Standard ロジック アプリ ワークフロー。 このワークフローは、トリガーで既に開始されている必要があります。 詳細については、Standard ロジック アプリ ワークフロー の例の作成に関するページを参照してください。

    ご自分のシナリオには任意のトリガーを使用できますが、例として、このガイドでは HTTP 要求の受信時という名前の要求トリガーと、応答アクションを使用します。 ワークフローは、別のアプリケーションまたはワークフローがトリガーのエンドポイント URL に要求を送信したときに実行されます。 サンプル スクリプトは、コード実行の結果を出力として返しますが、これは、後続のアクションで使用できます。

シナリオの例

次の一覧では、特定の統合タスクに役立つスクリプトを使用できるシナリオの例をいくつか示します。

  • 組み込みの式やデータ操作機能を超えて、ペイロードを解析し、変換や操作を実行する。 たとえば、スクリプトを使用して、ダウンストリーム処理用に変更されたスキーマを返すことができる。

  • 仮想マシンなどの Azure リソースを管理し、ビジネス ロジックに基づいて開始またはステップ実行する。

  • スケジュールに基づく実行が必要な SQL サーバー上でストアド プロシージャを実行し、結果を SharePoint に保存する。

  • ワークフロー エラーを、Azure Storage に保存するか、チームにメールまたは通知して詳細情報と共にログする。

  • API セキュリティ標準に準拠するためにデータを暗号化および暗号化を解除する。

  • ファイルをスクリプトに渡して、HTTP 要求を zip 圧縮または圧縮を解除する。

  • さまざまな API とファイルのデータを集計して日次レポートを作成する

考慮事項

  • Azure portal では、スクリプトを C# スクリプト ファイル (.csx) として workflow.json ファイルと同じフォルダーに保存します。これにはワークフローの JSON 定義が格納されており、ワークフロー定義と共にファイルがロジック アプリ リソースにデプロイされます。 Azure Logic Apps によってこのファイルがコンパイルされ、スクリプトを実行できる状態にします。

    .csx ファイル形式を使用すると、記述する "定型句" が減り、C# 関数を書くことだけに集中できます。 デプロイ中の管理を容易にするために、.csx ファイルの名前を変更できます。 ただし、スクリプトの名前を変更するたびに、新しいバージョンで以前のバージョンが上書きされます。

  • スクリプトはワークフローに対してローカルです。 他のワークフローで同じスクリプトを使用するには、KuduPlus コンソールでスクリプト ファイルを表示し、スクリプトをコピーして他のワークフローで再利用します。

制限事項

名前 Limit メモ
スクリプトの実行期間 10 分 より長い期間が必要なシナリオがある場合は、製品フィードバック オプションを使用して、ニーズに関する詳細情報を提供してください。
出力サイズ 100 MB 出力サイズは、アクションの出力サイズの制限によりますが、通常は 100 MB です。

CSharp スクリプト コードの実行アクションを追加する

  1. Azure portal で、Standard ロジック アプリ リソースとワークフローをデザイナーで開きます。

  2. デザイナーで、次の一般的な手順に従って、[CSharp スクリプト コードの実行] という名前のインライン コード操作アクションをワークフローに追加します

  3. アクション情報ペインが開いたら、[パラメーター] タブの [コード ファイル] ボックスで、事前に設定されたサンプル コードを独自のスクリプト コードで更新します。

    次の例は、サンプル スクリプト コードを含むアクションの [パラメーター] タブを示しています。

    スクリーンショットは、Azure portal、標準ワークフロー デザイナー、要求トリガー、情報ペインが開いている CSharp スクリプト コードの実行アクション、応答アクションを示しています。情報ペインには、C# スクリプトのサンプルが表示されています。

    次の例は、サンプル スクリプト コードを示しています。

    /// 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;}
    }
    

    詳細については、#r - 外部アセンブリの参照に関するページを参照してください。

  4. 完了したら、ワークフローを保存します。

ワークフローを実行した後、Application Insights (有効になっている場合) でワークフローの出力を確認できます。 詳細については、「Application Insights でログを表示する」を参照してください。

名前空間のインポート

名前空間をインポートするには、通常どおりに using 句を使用します。 次の一覧には、自動的にインポートされた名前空間が含まれているため、スクリプトに含めるかどうかは任意です。

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

外部アセンブリへの参照を追加する

.NET Framework アセンブリを参照するには、 #r "<assembly-name> ディレクティブを使用します。次に例を示します。

/// 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
{
    <...>
}

次の一覧には、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

ストリームへの出力をログする

Run メソッドに、ILogger 型で名前が log のパラメーターを含めます。次に例を示します。

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

Application Insights への出力をログする

Application Insights でカスタム メトリックを作成するには、ILoggerLogMetric 拡張メソッドを使用します。

次の例に、メソッド呼び出しのサンプルを示します。

logger.LogMetric("TestMetric", 1234);

スクリプト内のワークフロー トリガーとアクションの出力にアクセスする

ワークフローからデータにアクセスするには、WorkflowContext コンテキスト オブジェクトで使用できる次のメソッドを使用します。

  • GetTriggerResults メソッド

    トリガー出力にアクセスするには、このメソッドを使用して、トリガーとその出力を表すオブジェクトを返します。このオブジェクトは、Outputs プロパティを使って取得できます。 このオブジェクトには JObject 型があり、角かっこ ([]) をインデクサーとして使って、トリガー出力のさまざまなプロパティにアクセスできます。

    次の例では、トリガー出力の body プロパティからデータを取得しています。

    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 メソッド

    アクションの出力にアクセスするには、このメソッドを使用して、アクションとその出力を表すオブジェクトを返します。このオブジェクトは、Outputs プロパティを使って取得できます。 このメソッドは、アクション名をパラメーターとして受け入れます。 次の例では、action-name という名前のアクションからの出力の body プロパティからデータを取得します。

    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
    {
        <...>
    }
    

環境変数またはアプリ設定値にアクセスする

環境変数またはアプリ設定値を取得するには、次の例のように、System.Environment.GetEnvironmentVariable メソッドを使用します。

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);
}

ワークフローにデータを返す

このタスクでは、戻り値の型と return ステートメントを使用して Run メソッドを実装します。 非同期バージョンが必要な場合は、Task<return-type> 属性と async キーワードを使用して Run メソッドを実装します。 戻り値は、スクリプト アクションの出力 body プロパティに設定され、後続のワークフロー アクションで参照できるようになります。

次の例は、Task<Results> 属性、async キーワード、return ステートメントを使用した Run メソッドを示しています。

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;}
}

スクリプト ファイルを表示する

  1. Azure portal で、希望するワークフローが含まれている Standard ロジック アプリ リソースを開きます。

  2. ロジック アプリのリソース メニューの [開発ツール] で、[高度なツール] を選びます。

  3. [高度なツール] ページで、[移動] を選択すると、KuduPlus コンソールが開きます。

  4. [デバッグ コンソール] メニューを開き、[CMD] を選択します。

  5. ロジック アプリのルートの場所 (site/wwwroot) に移動します

  6. .csx ファイルを含むワークフローのフォルダーに次のパスで移動します。site/wwwroot/{workflow-name}

  7. ファイル名の横にある [編集] を選択して、ファイルを開いて表示します。

Application Insights のログの表示

  1. Azure portal で、ロジック アプリのリソース メニューにある [設定][Application Insights] を選択し、ロジック アプリを選択します。

  2. Application Insights メニューの [監視] で、[ログ] を選択します。

  3. ワークフローの実行からトレースまたはエラーを検索するクエリを作成します。次に例を示します。

    union traces, errors
    | project TIMESTAMP, message
    

コンパイル エラー

このリリースでは、Web ベースのエディターに制限付きの IntelliSense サポートが含まれており、引き続き改善中です。 ワークフローを保存するとコンパイル エラーが検出され、Azure Logic Apps ランタイムによってスクリプトがコンパイルされます。 これらのエラーは、ロジック アプリのエラー ログに表示されます。

実行時エラー

スクリプトの実行時にエラーが発生した場合、Azure Logic Apps で次の手順が実行されます。

  • エラーをワークフローに戻します。
  • スクリプト アクションを失敗としてマークします。
  • スクリプトからスローされた例外を表すエラー オブジェクトを提供します。

次の例に、エラーのサンプルを示します。

関数 'CSharp_MyLogicApp-InvalidAction_execute_csharp_script_code.csx' は、実行時に、エラー 'The action 'nonexistent' does not exist in the workflow.' で 失敗しました。 関数コードが有効であることを確認してください。

サンプル スクリプト

次のスクリプト例では、さまざまなタスクを実行できます。

テキスト ファイルを含む ZIP ファイルを HTTP アクションから文字列配列に展開する

// 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;
}

アプリ設定のキーを使用してデータを暗号化する

// 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());

        }
    }
}

WorkflowContext クラス

ワークフロー コンテキストを表します。

メソッド

GetActionResult(string actionName)

ワークフロー内の特定のアクションから結果を取得します。

非同期バージョンでは、戻り値の型として Task<> が使用されます。次に例を示します。

Task<WorkflowOperationResult> GetActionResult(string actionName)

パラメーター

actionName: アクション名。

返品

非同期バージョンは、非同期操作を表す Task オブジェクトを返します。 タスクの結果には、WorkflowOperationResult オブジェクトが含まれます。 WorkflowOperationResult オブジェクトのプロパティの詳細については、「WorkflowOperationResult クラス」を参照してください。

RunTriggerResult()

ワークフロー内のトリガーから結果を取得します。

非同期バージョンでは、戻り値の型として Task<> が使用されます。次に例を示します。

Task<WorkflowOperationResult> RunTriggerResult()

パラメーター

ありません。

返品

非同期バージョンは、非同期操作を表す Task オブジェクトを返します。 タスクの結果には、WorkflowOperationResult オブジェクトが含まれます。 WorkflowOperationResult オブジェクトのプロパティの詳細については、「WorkflowOperationResult クラス」を参照してください。

WorkflowOperationResult クラス

ワークフロー操作の結果を表します。

プロパティ

件名 種類 説明
名前 String 操作名を取得または設定します。
入力 JToken 操作の実行入力を取得または設定します。
出力 JToken 操作の実行出力を取得または設定します。
StartTime DateTime? 操作の開始時刻を取得または設定します。
EndTime DateTime? 操作の終了時刻を取得または設定します。
OperationTrackingId String 操作追跡 ID を取得または設定します。
コード String アクションの状態コードを取得または設定します。
Status String アクションの状態を取得または設定します。
エラー JToken アクションのエラーを取得または設定します。
TrackedProperties JToken アクションの追跡されるプロパティを取得または設定します。

JavaScript コード スニペットを追加して実行する