# スキーマバリデーション

EMQXには、指定されたトピックからサブスクライバーにパブリッシュされるメッセージがあらかじめ定義されたデータフォーマットに準拠していることを保証するための組み込みスキーマバリデーション機能があります。スキーマバリデーションはJSON Schema、Protobuf、Avroなど複数のスキーマフォーマットおよび組み込みのSQL文バリデーションをサポートしています。本ページではスキーマバリデーション機能の概要と利用方法について説明します。

## なぜデータをバリデートするのか

クライアントはブローカーに非標準のメッセージをパブリッシュする可能性があり、それがサブスクライバーやデータシステムの例外やセキュリティリスクを引き起こすことがあります。EMQXはデータフォーマットを早期にバリデートすることでこれらの非準拠メッセージを検出・ブロックし、システムの安定性と信頼性を確保します。スキーマバリデーションは以下のような利点をもたらします。

- **データ整合性**：MQTTメッセージの構造とフォーマットを検証し、データの一貫性と正確性を保証します。
- **データ品質**：欠落や無効なフィールド、データ型、フォーマットをチェックし、データの一貫性と品質を維持します。
- **統一データモデル**：チームやプロジェクト全体で統一されたデータモデルを使用し、不整合やエラーを減らします。
- **再利用と共有**：スキーマをチームメンバー間で再利用・共有でき、協力効率を高め、繰り返し作業やエラーを削減します。
- **セキュリティ**：悪意あるまたは誤ったフォーマットのメッセージの処理を防ぎ、セキュリティ脆弱性のリスクを低減します。
- **相互運用性**：メッセージが標準化されたフォーマットに準拠することで、異なるデバイスやシステム間の通信を円滑にします。
- **デバッグ**：無効または誤ったフォーマットのメッセージを容易に特定し、デバッグできます。

## ワークフロー

メッセージがパブリッシュされると、あらかじめ定義されたルールに基づいてバリデーションが行われます。バリデーションが成功すれば処理は継続され、失敗した場合はユーザー設定のアクションが実行されます（メッセージ破棄や切断など）。

1. メッセージがパブリッシュされると、まずEMQXの[認可機構](../../guides/access-control/authz/authz.md)でパブリッシュ権限がチェックされます。権限チェックを通過した後、ユーザー設定のバリデータリストからパブリッシュされたトピックに基づいてバリデーションルールがマッチングされます。1つのバリデータは複数のトピックまたはトピックフィルターに設定可能です。

2. バリデーションルールがマッチすると、メッセージはあらかじめ設定されたスキーマまたはSQLに対してバリデートされます。

   - JSON Schema、Protobuf、Avroなど複数のスキーマタイプをサポートします。
   - EMQXルールエンジンの構文に準拠したSQL文もサポートします。
   - 1つのポリシーに複数のスキーマやSQLを追加し、その関係性を指定できます：
     - **All Pass**：すべてのバリデーションが成功した場合のみ成功とみなします。
     - **Any Pass**：いずれかのバリデーションが成功した時点で成功とみなしてバリデーションを停止します。

3. バリデーションが成功すると、ルールエンジンのトリガーやサブスクライバーへの配信など次の処理に進みます。

4. バリデーションが失敗した場合、以下のユーザー設定のアクションが実行されます。

   - **メッセージ破棄**：パブリッシュを終了しメッセージを破棄、QoS 1およびQoS 2メッセージにはPUBACKで特定の理由コード（131 - Implementation Specific Error）を返します。
   - **切断してメッセージ破棄**：メッセージを破棄し、パブリッシュクライアントを切断します。
   - **無視**：追加のアクションは行いません。

   設定されたアクションにかかわらず、バリデーション失敗時にログを出力可能で、ログの出力レベルはユーザーが設定でき、デフォルトは`warning`です。バリデーション失敗はルールエンジンイベント`$events/schema_validation/failed`をトリガーでき、ユーザーはこのイベントをキャッチして、誤ったメッセージを別トピックにパブリッシュしたりKafkaに送信して解析するなどのカスタム処理が可能です。

## ユーザーガイド

このセクションではスキーマバリデーション機能の設定方法とテスト方法を説明します。

### ダッシュボードでのスキーマバリデーション設定

ダッシュボードでスキーマバリデータを作成・設定する手順を示します。

1. ダッシュボードの左ナビゲーションで **Smart Data Hub** -> **Schema Validation** をクリックします。
2. **Schema Validation** ページ右上の **Create** をクリックします。
3. Create Schema Validationページで以下を設定します：
   - **Name**：バリデータ名を入力します。
   - **Message Source Topic**：バリデーション対象のメッセージトピックを設定します。複数トピックやトピックフィルターを設定可能です。
   - **Note**（任意）：メモを入力します。
   - **Validation Method**：
     - **Validation Strategy**：複数のバリデーション戦略間の関係を指定します。
       - **All Pass**（デフォルト）：すべてのバリデーションが成功した場合に成功とみなします。
       - **Any Pass**：いずれかのバリデーションが成功した時点で成功とみなしてバリデーションを停止します。
     - **Validation List**：**Type** ドロップダウンからスキーマを選択し、スキーマまたはSQLを追加します。スキーマの作成方法は[Create Validation Schema](#create-validation-schema)を参照してください。
   - **Validation Failure Operation**：
     - **Action After Failure**：バリデーション失敗時のアクションを選択します。
       - **Drop Message**：パブリッシュを終了しメッセージを破棄、QoS 1およびQoS 2メッセージにはPUBACKで特定の理由コードを返します。
       - **Disconnect and Drop Message**：メッセージを破棄し、パブリッシュクライアントを切断します。
       - **Ignore**：追加アクションは行いません。
   - **Output Logs**：バリデーション失敗時にログを出力するか選択します。デフォルトは有効です。
   - **Logs Level**：ログ出力レベルを設定します。デフォルトは`warning`です。

4. **Create** をクリックして設定を完了します。

これで有効な新しいバリデータがSchema Validationページのリストに表示されます。必要に応じて無効化できます。**Actions**列の**Settings**をクリックすると設定を更新でき、**More**からバリデータの削除や順序変更も可能です。

### 設定ファイルでのスキーマバリデーション設定

設定の詳細は[Configuration Manual](https://docs.emqx.com/en/enterprise/v6.3.1/hocon/)を参照してください。

### バリデーションスキーマの作成

ここではJSON Schemaを例にバリデーションスキーマの作成方法を示します。JSON Schemaは以下の条件を満たす必要があります。

EMQX 6.0.4以降、スキーマレジストリはdraft-03、draft-04、draft-06に加え、JSON Schema draft 2019-09およびdraft 2020-12をサポートしています。`$schema`が省略された場合はdraft-06が使用されます。対応範囲や制限、完全な例については[スキーマレジストリの例 - JSON Schema](./schema-registry-example-json.md)を参照してください。

- JSONオブジェクトに`temp`という名前のプロパティが含まれていること。
- `temp`プロパティは整数型であること。
- `temp`プロパティの値は101以上であること。

```json
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "type": "object",
  "properties": {
    "temp": {
      "type": "integer",
      "minimum": 101
    }
  },
  "required": ["temp"]
}
```

### スキーマバリデーションのテスト

[Create Validation Schema](#create-validation-schema)で作成した例のスキーマを使ってスキーマバリデーションの設定をテストできます。

[mqttx](https://mqttx.app/cli)を使用し、MQTTメッセージルールに準拠したペイロードでメッセージをパブリッシュします。

```bash
mqttx pub -t t/1 -m '{"temp": 102}'
```

MQTTメッセージルールに準拠しないペイロードでメッセージをパブリッシュします。

```bash
mqttx pub -t t/1 -m '{"temp": 100}'
```

ログ出力は以下のようになります。

```bash
2024-05-16T06:24:10.733827+00:00 [warning] tag: SCHEMA_VALIDATION, clientid: mqttx_1db4547e, msg: validation_failed, peername: 127.0.0.1:40850, action: drop, validation: <<"check-json">>
```

### REST API

REST APIを通じたスキーマバリデーションの詳細な利用方法は[EMQX Enterprise API](https://docs.emqx.com/en/enterprise/v6.3/admin/api-docs.html)を参照してください。

## 統計と指標

スキーマバリデーションを有効にすると、ダッシュボードに統計と指標が表示されます。Schema Validationページでバリデータ名をクリックすると以下を確認できます。

**統計情報**：

- **Total**：システム起動以降のトリガー総数
- **Success**：成功したデータバリデーション数
- **Failed**：失敗したデータバリデーション数

**レート指標**：

- 現在の検証速度
- 過去5分間の速度
- 過去の最大速度

統計はリセット可能で、Prometheusにも追加されており、`/prometheus/schema_validation`パスからアクセス可能です。
