Whistle でスクリプトを作成する

このガイドでは、パーサー用の Whistle スクリプトを作成する際の一般的なガイダンスを提供します。Whistle の構文と使用可能な関数の詳細については、Whistle リファレンスをご覧ください。

Whistle スクリプトの作成

Whistle スクリプトの作成を開始する前に、次のことを行うことをおすすめします。

  1. パーサーがサブスクライブするソース メッセージ クラスのメッセージのスキーマを理解します。マッピングの失敗を防ぎ、その結果としてメッセージがデッドレター キューに送られないようにするには、Whistle スクリプトがすべての受信メッセージをマッピングできる必要があります。メッセージ スキーマがメッセージごとに異なる場合は、Whistle スクリプトでこれらの違いを処理する必要があります。

    移行元メッセージのスキーマを把握すると、移行元メッセージにどのようなフィールドが存在し、そのデータ型が何であるかを理解できます。これにより、移行元メッセージのフィールドをターゲット型のスキーマにマッピングする方法を決定できます。データのセマンティクスを理解することも重要です。これにより、移行元メッセージのどの部分を移行先スキーマの属性にマッピングするかを効果的に判断できます。

    たとえば、属性値の変更頻度を把握することで、埋め込みメタデータとしてマッピングするデータとクラウド メタデータとしてマッピングするデータを決定できます。ソース メッセージ クラスのモデリングデータのモデリングのセクションをご覧ください。

  2. パーサーに定義されているタイプ バージョンのスキーマを理解します。パーサーの Whistle スクリプトは、ソース メッセージをパーサー用に定義されたタイプ バージョン スキーマにマッピングします。タイプ バージョンの要件を満たす proto レコードを構築する方法については、タイプ仕様をご覧ください。特に、data フィールドのスキーマと、メタデータ バケットの関連付けに注意する必要があります。メタデータ バケットの関連付けが required: true としてマークされている場合は、特に注意してください。値でメタデータ インスタンスを検索する場合は、関連付けられたバケットのスキーマをメモしておく必要があります。

  3. Whistle スクリプトを作成します。Whistle スクリプトは、ソースからターゲットへの実際の変換を実行します。ソース メッセージは $root という入力に読み込まれます。言語と使用可能な関数の概要については、Whistle リファレンスをご覧ください。また、このセクションの他のガイド(レコードをメタデータ インスタンスにリンクする方法など)もご覧ください。

ベスト プラクティス

このセクションでは、Whistle スクリプトを作成するためのベスト プラクティスについて説明します。

メッセージ プロパティにアクセスする際に null チェックを実行

プロパティが定義されていない可能性がある場合は、メッセージ プロパティにアクセスするときに null を確認することをおすすめします。

//Add metadata from source bucket if metadata.source attribute is present
if(isNotNil(input.metadata) and isNotNil(input.metadata.source)) then {
{
    var metadataArray[]: {
        bucketReference: {
            bucketName: "source";
            version: 1;
        };
            naturalKey: input.metadata.source;
        }
    }
}

以降のセクションでは、Whistle を使用した基本的な操作の例を示します。

シンプルな Whistle マッピング

次のソース メッセージがあるとします。

{
  "sensor": "rotation-speed-sensor",
  "machine": "m-234",
  "timestamp": "1687973092857",
  "value": 1200
}

次の Whistle スクリプト:

package mde

[
    {
        tagName: $root.machine + " - " + $root.sensor;
        data: {
            numeric: $root.value;
        };
        timestamps: {
            eventTimestamp: $root.timestamp;
        }
    }
]

パーサーは次の proto レコード出力を生成します。

[
  {
    "tagName": "m-234-rotation-speed-sensor",
    "data": {
      "numeric": 1200
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

関数を使用したシンプルな Whistle マッピング

次のソース メッセージがあるとします。

{
  "sensor": "rotation-speed-sensor",
  "machine": "m-234",
  "timestamp": "1687973092857",
  "value": 1200
}

次の Whistle スクリプト:

package mde

[
    {
        tagName: getTagName($root);
        data: getValue($root);
        timestamps: getTimestamp($root)
    }
]

def getTagName(input) {
    input.machine + "-" + input.sensor;
}

def getTimestamp(input) {
    eventTimestamp: input.timestamp;
}

def getValue(input) {
    numeric: input.value;
}

パーサーは次の proto レコード出力を生成します。

[
  {
    "tagName": "m-234-rotation-speed-sensor",
    "data": {
      "numeric": 1200
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

パーサー 1 から複数の proto レコードを出力する

次のソース メッセージがあるとします。

{
  "tag": "plc-34",
  "machine": "controller",
  "timestamp": "1687973092857",
  "values": [200, 499]
}

次の Whistle スクリプト:

package mde

var valueLen: listLen($root.values);
var indexes: range(0, valueLen);

[
    getProtoRecords($root.values[], indexes[], $root)
]

def getProtoRecords(value, index, input) {
        tagName: input.machine + "-" + input.tag + "-" + index;
        data: {
            numeric: value;
        };
        timestamps: {
            eventTimestamp: input.timestamp;
        };
}

パーサーは次の proto レコード出力を生成します。

[
  {
    "tagName": "controller-plc-34-0",
    "data": {
      "value": 200.0
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  },
  {
    "tagName": "controller-plc-34-1",
    "data": {
      "value": 499.0
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

パーサー 2 から複数の proto レコードを出力する

次のソース メッセージがあるとします。

{
  "machine": "controller",
  "timestamp": "1687973092857",
  "sensors": [
    {
      "tag": "plc-34",
      "value": 200
    },
    {
      "tag": "plc-35",
      "value": 499
    }
  ]
}

次の Whistle スクリプト:

package mde

[$$
    getProtoRecords($root.sensors[], $root)
]

def getProtoRecords(sensor, input) {
        tagName: input.machine + "-" + sensor.tag;
        data: {
            numeric: sensor.value;
        };
        timestamps: {
            eventTimestamp: input.timestamp;
        };
}

パーサーは次の proto レコード出力を生成します。

[
  {
    "tagName": "controller-plc-34",
    "timestamps": {
      "eventTimestamp": "1687973092857"
    },
    "data": {
      "numeric": 200
    }
  },
  {
    "tagName": "controller-plc-35",
    "timestamps": {
      "eventTimestamp": "1687973092857"
    },
    "data": {
      "numeric": 499
    }
  }
]