# ルールの作成

このページでは、EMQX ダッシュボードを使用してデータ処理のルールを作成し、ルールにアクションを追加する方法について説明します。また、ルールのテスト方法やルール作成後の確認方法も紹介します。

本ページのデモでは、再パブリッシュアクションを例に取り、トピック `t/#` で受信したメッセージを処理し、トピック `a/1` に再パブリッシュするルールの作成方法を説明します。ただし、アクションとして「コンソールへの出力」や「Sinks を使った転送」も [アクションの追加](#add-actions) にて触れています。

## ルール SQL の定義

EMQX ダッシュボードにログインし、左側ナビゲーションメニューの **Integration** -> **Rules** をクリックします。

**Rules** ページで **Create** ボタンをクリックすると、**Create Rule** ページに遷移します。ここでルールのデータソースを定義し、フィルタリングされたメッセージに対して実行するアクションを決定します。

ルール名を入力し、将来の管理を容易にするためにメモを追加してください。**SQL Editor** では、ビジネスニーズに合わせたデータソースを追加するためのカスタムステートメントを記述できます。本チュートリアルでは、デフォルト設定のままにしておきます。これは、`"t/#"` パターンにマッチするトピック（例：`t/a`、`t/a/b`、`t/a/b/c` など）に属するすべてのメッセージを選択して返します。

::: tip

本チュートリアルではメッセージのペイロードが JSON 形式であることを前提としています。もしペイロードが他の形式の場合は、[スキーマレジストリ](./schema-registry.md) を使ってデータ型を変換できます。

EMQX には豊富な SQL ステートメントのサンプルが組み込まれており、**SQL Editor** 下の **SQL Examples** ボタンから参照可能です。SQL の文法や使い方の詳細は [SQL Syntax](./rule-sql-syntax.md) をご覧ください。

:::

<img src="./assets/rules/create-rules.png" alt="ルール作成画面" style="zoom:50%;" />

### SQL ジェネレーター

EMQX 5.10.0 以降、SQL Editor は AI を活用した自然言語によるルール SQL 生成機能（SQL ジェネレーター）をサポートしています。この機能により、自然言語で意図を記述すると、システムが適切な SQL ステートメントを自動生成します。

SQL ジェネレーターはデフォルトで有効になっています。ダッシュボード右上の **Settings** メニューからトグルスイッチで無効化可能です。

利用手順は以下の通りです：

1. **Create Rule** ページの **SQL Editor** セクションに移動します。

2. エディター下の **SQL Generator** ボタンをクリックし、**Generate SQL with AI** ダイアログを開きます。以下の項目を指定してください：

   - **Task Description**（必須）：SQL に何をさせたいかを自然言語で記述します。
     
      例：
      *「MQTT メッセージのメタデータから `clientid` を抽出し、ペイロードから `device_id` と `temperature` を抽出する。トピック `sensors/temperature` のメッセージで温度が 30 を超える場合のみ適用する。」*
      
   - **Related Topics**（任意）：`sensors/temperature` のようなトピックフィルターを指定します。

   - **Input Example (JSON)**（任意だが推奨）：AI がデータ構造を理解しやすくするためのサンプル MQTT メッセージペイロードを提供します。
     例：

     ```json
     {
       "device_id": "sensor001",
       "temperature": 32.5,
       "unit": "C"
     }
     ```

   - **Output Example (JSON)**（任意）：期待する結果のフォーマットを指定します。
     例：

     ```json
     {
       "clientid": "client_a1b2c3",
       "device_id": "sensor001",
       "temperature": 32.5
     }
     ```
     
     ::: tip 
     
     入力／出力例を含めることで生成される SQL の精度が向上します。
     
     :::

3. **Generate** をクリックして生成された SQL をプレビューします。

4. プレビュー画面では以下が可能です：

   - 生成された SQL の確認および手動編集
   - **Apply SQL** をクリックして SQL Editor に挿入
   - **Back to Form** をクリックして入力を修正し再生成

5. SQL Editor に挿入すると、SQL が自動的に表示され、確認・編集が可能です。

#### 出力例

上記のタスクと入力例を用いると、生成される SQL は以下のようになります：

```sql
SELECT
  clientid,
  payload.device_id AS device_id,
  payload.temperature AS temperature
FROM
  "sensors/temperature"
WHERE
  payload.temperature > 30
```

このルールは、トピック `sensors/temperature` のメッセージから `clientid`、`device_id`、`temperature` を抽出し、温度が 30 を超える場合にのみ適用されます。

#### SQL ジェネレーターの利用シーン

SQL ジェネレーターは以下のような場合に特に有用です：

- EMQX の SQL 文法に不慣れな場合
- ルールのプロトタイプを素早く作成したい場合
- 構造化された JSON ペイロードを扱う場合

より詳細なカスタマイズや文法については、[Rule SQL Syntax](./rule-sql-syntax.md) を参照してください。

### SQL ステートメントのテスト

SQL ステートメントはシミュレーションデータを使って実行テストできます。アクションを追加してルールを作成する前に、SQL の実行結果が期待通りか確認できます。これは必須ではありませんが、EMQX ルールに慣れていない場合は推奨されます。ルール全体の実行テストを行いたい場合は、[ルールのテスト](#test-rules) を参照してください。

SQL テストの手順は以下の通りです：

1. **Create Rule** ページで **Try It Out** トグルスイッチをオンにして SQL テストを有効化します。
2. SQL に合致する **Data Source** を選択し、ルールの指定ソース（FROM 句）と一致していることを確認します。
3. テストデータを入力します。データソースを選択すると、EMQX は **Client ID**、**Username**、**Topic**、**QoS**、**Payload** などのシミュレーションデータのデフォルト値を提供します。必要に応じて適切な値に修正してください。
4. **Run Test** ボタンをクリックしてテストを実行します。正常に動作すれば **Test Passed** のメッセージが表示されます。

![test-sql](./assets/test-sql.png)

SQL の処理結果は JSON 形式で **Output Result** セクションに表示されます。SQL 処理結果のすべてのフィールドは、その後のアクション（組み込みアクションや Sink）で `${key}` の形式で参照可能です。フィールドの詳細は [SQL Data Sources and Fields](./rule-sql-events-and-fields.md) をご覧ください。

本デモはペイロードが JSON 形式であることを前提としていますが、実際には [スキーマレジストリ](./schema-registry.md) を用いて他形式のメッセージも扱えます。

次に、**Create Rule** ページ右側の **Add Action** ボタンをクリックして、ルールにさまざまな種類のアクションを追加できます。

## アクションの追加

**Create Rule** ページで右側の **Add Action** ボタンをクリックすると、**Add Action** ページが表示されます。**Action** のドロップダウンリストから、Republish、Console Output、Data Bridge を使った転送のいずれかのアクションを選択できます。

<img src="./assets/add_action.png" alt="アクション追加画面" style="zoom:67%;" />

### 再パブリッシュアクションの追加

ここでは、トピック `t/#` で受信した元のメッセージを別のトピック `a/1` に再パブリッシュするアクションの追加方法を示します。

**Add Action** ページで、**Type of Action** ドロップダウンから **Republish** を選択し、以下の設定を行ってから **Add** ボタンをクリックして確定します：

- **Topic**：転送先トピックを設定します。ここでは例として `"a/1"` を指定します。

- **QoS**：再パブリッシュするメッセージの QoS を設定します。例では `"0"`。

- **Retain**：メッセージを保持メッセージとして転送するかどうかを設定します。本チュートリアルではデフォルトの **false** のままにします。

- **Payload**：`"${payload}"` と入力し、再パブリッシュするメッセージのペイロードが元のメッセージと同じであることを示します。

- **MQTT 5.0 メッセージプロパティ**：トグルスイッチをクリックして、必要に応じてユーザープロパティや MQTT プロパティを設定できます。これにより、再パブリッシュメッセージにリッチなメタデータを付加できます。

  - **Payload Format Indicator**：メッセージのペイロードが特定の形式であるかを示す値を入力します。`false` の場合は不定のバイト列、`true` の場合は UTF-8 エンコードされた文字データとみなされます。これにより MQTT クライアントやサーバーがメッセージ内容を効率的に解析できます。
  - **Message Expiry Interval**：メッセージが配信されない場合に無効となるまでの秒数を指定します。
  - **Content Type**：再パブリッシュメッセージのペイロードの種類や形式（MIME タイプ）を指定します。例：`text/plain`（テキストファイル）、`audio/aac`（音声ファイル）、`application/json`（JSON 形式のアプリケーションメッセージ）など。
  - **Response Topic**：応答メッセージを送信する MQTT トピックを指定します。例：`response/my_device`。
  - **Correlation Data**：応答メッセージと元のリクエストメッセージを関連付けるための一意の識別子やデータを入力します。例：リクエスト ID、トランザクション ID など。

- **Direct Dispatch**：トグルスイッチで直接ディスパッチを有効／無効にします。有効にすると、メッセージはサブスクライバーに直接配信され、追加のルール発動や同一ルールの再帰的な発動を防止します。

::: tip 注意

EMQX 6.1.5 以降、ルールがネームスペースに属し、かつ `rule_engine.limit_selects_in_namespace` が有効（デフォルト）な場合、EMQX は再パブリッシュアクションの出力トピックをルールのネームスペース内に制限します。トピックテンプレートのレンダリング後、レンダリングされたトピックが `<namespace>/` で始まらない場合、EMQX は `<namespace>/` を先頭に付加します。すでに `<namespace>/` で始まるトピックは変更されません。この挙動は `mqtt.namespace_as_mountpoint` の設定には依存しません。グローバルルールや `rule_engine.limit_selects_in_namespace = false` のデプロイメントは、レンダリングされたトピックにネームスペースを付加せずにパブリッシュします。

詳細は [Rule Namespace Isolation](../../guides/multi-tenancy/namespace-overview.md#rule-namespace-isolation) を参照してください。

:::

**Create Rule** ページ下部の **Create** ボタンをクリックしてルール作成を完了します。このルールは **Rule** ページに新規エントリとして追加されます。

::: tip
再パブリッシュアクションは元のメッセージの配信を妨げません。例えば、ルールによりトピック `"t/1"` のメッセージが `"a/1"` に再パブリッシュされても、元の `"t/1"` メッセージは `"t/1"` をサブスクライブしているクライアントに引き続き配信されます。
:::

### コンソール出力アクションの追加

::: tip
コンソール出力アクションはデバッグ用途のみに使用してください。本番環境で使用するとパフォーマンス問題を引き起こす可能性があります。
:::

コンソール出力アクションはルールの出力結果を確認するために使います。結果メッセージはコンソールやログファイルに出力されます。

- EMQX が `console` または `foreground` モードで起動されると（Docker 環境のデフォルトは `foreground`）、出力はコンソールに向けられます。
- systemd 経由で起動される場合は、出力はジャーナルシステムにキャプチャされ、`journalctl` コマンドで確認可能です。

出力は以下の形式になります：

```bash
[rule action] rule_id1
    Action Data: #{key1 => val1}
    Envs: #{key1 => val1, key2 => val2}
```

ここで、

- `[rule action]` は再パブリッシュアクションがトリガーされたルール ID です。
- `Action Data` はルールの出力結果であり、アクション実行時に渡されるデータやパラメータ（再パブリッシュアクション設定時のペイロード部分）を示します。
- `Envs` は再パブリッシュ時に設定される環境変数で、データソースやアクション実行に関連する内部情報が含まれます。

### Sinks を使った転送アクションの追加

処理結果を Sinks を使って転送するアクションも追加可能です。ダッシュボードの **Type of Action** ドロップダウンリストから対象の Sink を選択するだけです。EMQX における各 Sink の詳細は [データ統合](./data-bridges.md) をご覧ください。

## ルールのテスト

ルールエンジンはルールテスト機能を提供しており、シミュレーションデータや実際のクライアントデータを使ってルールをトリガーし、ルール SQL を実行し、追加されたすべてのアクションを実行して各ステップの結果を取得できます。

ルールをテストすることで、期待通りに動作するか検証でき、問題の早期発見・解決が可能です。これにより開発効率が向上し、本番環境での失敗を防げます。

### テスト手順

1. **Try It Out** スイッチをオンにし、テスト対象として **Rule** を選択します。テスト開始前にルールを保存しておく必要があります。
2. **Start Test** ボタンをクリックしてテストを開始します。ブラウザはルールがトリガーされるのを待機し、テスト結果を取得します。
3. ルールをトリガーしてテストします。以下の 2 通りの方法が利用可能です：
   - **シミュレーションデータを使う**：**Input Simulated Data** ボタンをクリックし、ポップアップで SQL に合致する **Data Source** を選択し、ルールの指定ソース（FROM 句）と一致していることを確認します。EMQX は **Client ID**、**Username**、**Topic**、**QoS**、**Payload** などのフィールドにデフォルト値を提供します。必要に応じて修正し、**Submit Test** ボタンを押して一度だけルールをトリガーします。
   - **実際のデバイスデータを使う**：現在のページを開いたままにし、実際のクライアントや MQTT クライアントツールで EMQX に接続し、該当イベントを発生させてテストします。
4. テスト結果を確認します。ルールがトリガーされると、ダッシュボードに実行結果が出力され、各ステップの詳細な実行結果が表示されます。

### テスト例

[MQTTX](https://mqttx.app/) を使って再パブリッシュアクション付きルールをテストできます。クライアントを 1 つ作成し、そのクライアントで `a/1` トピックをサブスクライブし、`t/1` メッセージを送信します。ダイアログボックスにこのメッセージが `a/1` トピックに再パブリッシュされていることが表示されます。

MQTTX クライアントツールと EMQX の接続方法の詳細は [MQTTX - はじめに](https://mqttx.app/docs/get-started) を参照してください。

<img src="./assets/rules/en_rule_overview_mqttx.png" alt="MQTTX を使ったルールテスト" style="zoom: 50%;" />

対応して、ダッシュボードのテストインターフェースにはルール全体の実行結果が表示され、以下の内容が含まれます：

- 左側にルール実行の記録が表示されます。ルールがトリガーされるたびに記録が生成され、クリックすると該当メッセージやイベントの詳細に切り替えられます。
- 右側には選択されたルールのアクション記録一覧が表示され、クリックでアクションの実行結果やログを展開して確認できます。

ルール SQL やいずれかのアクションの実行に失敗すると、該当ルールの記録全体が失敗としてマークされます。記録を選択すると該当アクションのエラー情報を確認でき、トラブルシューティングに役立ちます。

<img src="./assets/rule-test-result.png" alt="ルールテスト結果" style="zoom:50%;" />

上記例では、ルールは 4 回トリガーされ、3 回は完全に成功しています。4 回目は **HTTP Server** アクションの実行失敗により失敗となり、エラー原因は 302 ステータスコードのレスポンスでした。

ルールテストの詳細な利用ガイドはブログ [Enhancing Data Integration Stability: A Guide on EMQX Platform E2E Rule Testing](https://www.emqx.com/en/blog/emqx-platform-e2e-rule-testing-guide) をご覧ください。

## ルールの確認

**Rules** ページでは、作成したすべてのルールの一覧を包括的に表示します。

一覧の各エントリには、ルール ID、関連するソース、有効状態、アクション数などの基本情報が表示されます。ソースにカーソルを合わせると対応する SQL ステートメントの詳細が表示されます。ルールの設定を変更するには、**Actions** 列の **Settings** をクリックします。また、**More** ボタンからルールの複製や削除も可能です。

![view_rules](./assets/view_rules.png)

また、[Flowデザイナー](../flow-designer/introduction.md) の **Integration** -> **Flow Designer** からもルールを確認できます。**Rules** ページで作成したルールと Flowデザイナーで作成したルールは完全に相互運用可能です。

ルールの統計情報やアクション実行情報を確認するには、**Rules** ページのルール ID または **Flows** ページのルール名をクリックしてください。

![view_rules_flows](./assets/view_rules_flows.png)

::: tip

ルールアクションを更新したりデータソースを再定義した場合、以下のページに表示される統計はリセットされて再集計が始まります。

:::

![Rule Statistics](./assets/rule_statistics.png)

### ルールの検索

ルールが多数ある場合は、フィルター機能を使って検索対象を絞り込み、表示したいルールを効率的に探せます。ルール ID、受信メッセージのトピックやワイルドカード、有効状態、ルールメモ、ルールに関連付けられたアクションやソースでフィルター可能です。

![search_rules](./assets/search_rules.png)

### アクション（Sink）およびソースの確認

**Rule** ページの **Actions (Sink)** タブと **Sources** タブには、作成済みのすべてのアクション（Sink）とソースが表示されます。名前、接続状態、関連ルール、有効状態、作成日時、最終更新日時などの重要な情報が含まれます。列名横の矢印をクリックするとソートが可能です。

**Enable** 列のトグルスイッチをクリックして Sink やソースの有効／無効を切り替えられます。**Associated Rules** 列の **View Rules** をクリックすると、その Sink やソースを含むルール一覧が表示され、データ統合設定の管理が容易になります。

**Action** 列から Sink やソースの再接続や設定変更が可能です。**More** からは削除や、それらを利用した新規ルール作成が行えます。

多数の Sink やソースがリストにある場合は、フィルターを使って名前、状態、有効状態で絞り込み表示できます。

![view_sink_source](./assets/view_sink_source.png)

Sink やソースの統計情報やレート指標を確認するには、名前をクリックしてください。

![action_statistics](./assets/action_statistics.png)
