Whistle でスクリプトを作成する
このガイドでは、パーサー用の Whistle スクリプトを作成する際の一般的なガイダンスを提供します。Whistle の構文と使用可能な関数の詳細については、Whistle リファレンスをご覧ください。
Whistle スクリプトの作成
Whistle スクリプトの作成を開始する前に、次のことを行うことをおすすめします。
パーサーがサブスクライブするソース メッセージ クラスのメッセージのスキーマを理解します。マッピングの失敗を防ぎ、その結果としてメッセージがデッドレター キューに送られないようにするには、Whistle スクリプトがすべての受信メッセージをマッピングできる必要があります。メッセージ スキーマがメッセージごとに異なる場合は、Whistle スクリプトでこれらの違いを処理する必要があります。
移行元メッセージのスキーマを把握すると、移行元メッセージにどのようなフィールドが存在し、そのデータ型が何であるかを理解できます。これにより、移行元メッセージのフィールドをターゲット型のスキーマにマッピングする方法を決定できます。データのセマンティクスを理解することも重要です。これにより、移行元メッセージのどの部分を移行先スキーマの属性にマッピングするかを効果的に判断できます。
たとえば、属性値の変更頻度を把握することで、埋め込みメタデータとしてマッピングするデータとクラウド メタデータとしてマッピングするデータを決定できます。ソース メッセージ クラスのモデリングとデータのモデリングのセクションをご覧ください。
パーサーに定義されているタイプ バージョンのスキーマを理解します。パーサーの Whistle スクリプトは、ソース メッセージをパーサー用に定義されたタイプ バージョン スキーマにマッピングします。タイプ バージョンの要件を満たす proto レコードを構築する方法については、タイプ仕様をご覧ください。特に、
dataフィールドのスキーマと、メタデータ バケットの関連付けに注意する必要があります。メタデータ バケットの関連付けがrequired: trueとしてマークされている場合は、特に注意してください。値でメタデータ インスタンスを検索する場合は、関連付けられたバケットのスキーマをメモしておく必要があります。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
}
}
]