# RDFサーバー RDFサーバーはローカルのApache Jena Fusekiエンドポイントに対してSPARQLクエリを実行するためのREST APIを提供します。 航路更新時に通知を受け取るためのMQTT統合機能を備えており、外部システムAPIから航路データを取得してRDFモデルに変換します。 航路データについては、リソースとしてDiscovery Serviceへ登録・更新します。 また、離着陸場と機体については一定間隔でデータを取得し、RDFモデルへ変換、Discovery Serviceへ登録します。 RDFデータ更新の際は、差分データをRDF PatchとしてAMQPで配信します。 --- ## 目次 - [RDFサーバー](#rdfサーバー) - [目次](#目次) - [システム全体図](#システム全体図) - [入手方法](#入手方法) - [前提環境](#前提環境) - [Docker](#docker) - [ネットワーク](#ネットワーク) - [ローカル環境](#ローカル環境) - [本番環境](#本番環境) - [準備](#準備) - [他システムとの調整](#他システムとの調整) - [`.env`作成](#env作成) - [`.env.shared`作成](#envshared作成) - [`.env.rabbitmq`作成](#envrabbitmq作成) - [サービスインスタンス格納](#サービスインスタンス格納) - [ビルド](#ビルド) - [起動](#起動) - [起動方法](#起動方法) - [起動確認方法](#起動確認方法) - [停止](#停止) - [利用](#利用) - [SPARQLクエリ](#sparqlクエリ) - [OpenAPI](#openapi) - [Fuseki管理ページ](#fuseki管理ページ) - [RabbitMQ管理ページ](#rabbitmq管理ページ) - [管理](#管理) - [Fuseki管理者パスワードの変更](#fuseki管理者パスワードの変更) - [データ永続化](#データ永続化) - [開発](#開発) - [ライセンス](#ライセンス) - [免責事項](#免責事項) --- ## システム全体図 ![システム全体図](./docs/uml/system-overview.png "RDFサーバーと関連システム") ## 入手方法 RDFサーバーのソースコードは次のいずれかの方法で入手できます。 - GitHubからクローンする場合 リポジトリをクローンし、プロジェクトルートに移動してから設定に進んでください。 - zipを取得する場合 zipファイルを解凍し、解凍したディレクトリ(プロジェクトルート)に移動してから設定に進んでください。 ```sh # クローンの例 git clone <リポジトリURL> rdf-server cd rdf-server ``` ## 前提環境 ### Docker Dockerがインストールされていることが前提です。 Docker Engine 24以降必須、28以降を推奨します。 ### ネットワーク #### ローカル環境 ポート8080, 3030, 5672, 5552, 15672が他のプロセスに使用されていない必要があります。 #### 本番環境 ポートは以下のように許可されている必要があります。 | 方向 | ポート | 用途 | |------|--------|------| | インバウンド | 80 | HTTP(Traefik、Let's Encrypt HTTP-01チャレンジ) | | インバウンド | 443 | HTTPS(API公開) | | インバウンド | 5671 | AMQP over TLS(RDF Patch配信、必要な場合のみ) | | インバウンド | 22 | SSH管理(管理者IPのみ許可) | | アウトバウンド | 443 | 外部API通信、Docker Hubからのイメージ取得 | | アウトバウンド | 1883/8883 | MQTTブローカー接続 | SSLでアクセスする場合、DNSの設定が必要です。 必要な設定については、.reverse-proxyのREADMEを参照してください。 ## 準備 ### 他システムとの調整 以下の情報・データを他システムから入手します。 - SDK - サービスインスタンスファイル (RDFサーバURLなどが記載されているファイル) - 航路画定システム - APIのURL (パスなし) - MQTTブローカーのホスト名 - MQTTブローカーのユーザー名・パスワード - 離着陸場管理システム - APIのURL (パスなし) - APIのキー(機体管理と共通) - 機体管理システム - APIのURL (パスなし) - APIのキー(離着陸場管理と共通) - Discovery Finder & Discovery Service - Discovery FinderのURL (パスなし) - キーワード - ドメインアプリID (RDFサーバのSPARQLクエリエンドポイント) - 航路ドメイン (航路を表す文字列) - 離着陸場ドメイン (離着陸場を表す文字列) - 機体ドメイン (機体を表す文字列) 以下の情報を決めて、他システムに伝えます。 - 分散カタログ - AMQPのユーザー名・パスワード - AMQPのキュー名 (rdf.patch.test等の文字列) ### `.env`作成 `.env.template`ファイルを`.env`にコピーし、設定項目を記入します。 | 変数名 | 要記入 | 説明 | |--------|------|------| | `FUSEKI_ADMIN_PASSWORD` | ○ | Fuseki管理ページのログインパスワード | | `SPRING_API_KEY` | ○ | Spring Boot APIの認証キー | | `FUSEKI_JVM_ARGS` | - | FusekiのJVMオプション | | `AIRWAY_RESERVATION_API_KEY` | ○ | 航路予約API認証キー(外部連携時) | | `MQTT_BROKER_USERNAME` | - | MQTTブローカー認証ユーザー名(外部連携時) | | `MQTT_BROKER_PASSWORD` | - | MQTTブローカー認証パスワード(外部連携時) | **注意1:** `FUSEKI_ADMIN_PASSWORD` は初回起動時にのみ適用されます。変更方法は[Fuseki管理者パスワードの変更](#fuseki管理者パスワードの変更)を参照してください。 **注意2:** 航路一括予約には対応していません。`AIRWAY_RESERVATION_API_KEY` にはダミーの値をセットしてください。 **注意3:** `MQTT_BROKER_USERNAME`, `MQTT_BROKER_PASSWORD`は航路画定システムの設定に合わせて設定します。認証が必要ない場合は、コメントアウトや値なしでもかまいません。 ### `.env.shared`作成 `.env.shared.template`ファイルを`.env.shared`にコピーし、設定項目を記入します。 | 変数名 | 要記入 | 説明 | |--------|------|------| | `SPRING_LOG_LEVEL` | - | ログレベル | | `LOGGING_TIMEZONE` | - | ログのタイムゾーン | | `API_URL` | ○ | RDFサーバーのURL(パスなし) | | `UASL_API_URL` | ○ | 航路画定APIのURL(パスなし) | | `AIRWAY_RESERVATION_API_URL` | - | | | `DRONE_PORT_API_URL` | ○ | 離着陸場情報APIのURL(パスなし) | | `AIRCRAFT_INFO_API_URL` | ○ | 機体情報APIのURL(パスなし) | | `ASSET_AUTH_HEADER` | - | 離着陸場&機体情報APIキーのヘッダー名 | | `ASSET_AUTH_VALUE` | ○ | 離着陸場&機体情報APIキーの値 | | `MQTT_BROKER_ADDRESS` | ○ | MQTTブローカーのURI | | `AIRCRAFT_INFO_ENABLED` | - | true/false | | `AIRCRAFT_INFO_INTERVAL` | - | polling間隔、ミリ秒単位 | | `AIRCRAFT_INFO_INITIAL_DELAY` | - | 初期polling間隔、ミリ秒単位 | | `DRONE_PORT_ENABLED` | - | true/false | | `DRONE_PORT_INTERVAL` | - | polling間隔、ミリ秒単位 | | `DRONE_PORT_INITIAL_DELAY` | - | 初期polling間隔、ミリ秒単位 | | `RDF_PATCH_ENABLED` | - | true/false | | `RDF_PATCH_DIRECTORY` | - | RDF Patch格納先、Fusekiの設定と合わせる | | `RDF_PATCH_POLL_INTERVAL` | - | polling間隔、ミリ秒単位 | | `RABBITMQ_HOST` | - | 通常はrabbitmqのまま | | `RABBITMQ_RDF_PATCH_QUEUE` | - | キュー名 | | `DISCOVERY_FINDER_URL` | ○ | Discovery FinderのURL(パスなし) | | `DISCOVERY_SERVICE_KEYWORD` | ○ | Discovery Finderに渡すキーワード | | `DISCOVERY_SERVICE_DOMAIN_APP_ID` | ○ | Discovery Serviceに渡すID | | `DISCOVERY_SERVICE_AIRCRAFT_INFO_DOMAIN` | ○ | 機体を指定する文字列 | | `DISCOVERY_SERVICE_DRONE_PORT_DOMAIN` | ○ | 離着陸場を指定する文字列 | | `DISCOVERY_SERVICE_UASL_DOMAIN` | ○ | 航路を指定する文字列 | **注意1:** `API_URL`はローカル環境の場合はhttp://localhost:8080とします。 **注意2:** 航路一括予約には対応していません。`AIRWAY_RESERVATION_API_URL` にはダミーの値をセットしてください。 **注意3:** `ASSET_AUTH_VALUE`は離着陸場&機体情報の指定に従い設定します。(`ASSET_AUTH_HEADER`はテンプレートのままです) **注意4:** `MQTT_BROKER_ADDRESS`はtcp://ホスト名:1883とします。 **注意5:** `RABBITMQ_RDF_PATCH_QUEUE`には分散カタログへ伝えたキュー名を設定します。デフォルト値は、`rdf.patch.test`です。 **注意6:** `DISCOVERY_*`の設定値はDiscovery FinderとDiscovery Serviceの指定に従い設定します。 ### `.env.rabbitmq`作成 `.env.rabbitmq.template`ファイルを`.env.rabbitmq`にコピーし、設定項目を記入します。 | 変数名 | 要記入 | 説明 | |--------|------|------| | `RABBITMQ_DEFAULT_USER` | ○ | RabbitMQのユーザー名 | | `RABBITMQ_DEFAULT_PASS` | ○ | RabbitMQのパスワード | **注意:** 分散カタログとユーザー名・パスワードについて調整しておきます。 ### サービスインスタンス格納 Discovery FinderやDiscovery Serviceの管理者より、サービスインスタンスファイルを取得します。 サービスインスタンスファイルはTurtle形式(mimetype: `text/turtle`, 拡張子: `.ttl`)です。 サービスインスタンスファイルをプロジェクトルートの`fuseki/datasets/resource`下にコピーします。 サービスインスタンスファイルがないとSemantic Client LibraryはDiscovery Service経由でRDFサーバーを発見することができません。 ## ビルド 以下を実行します。 ```sh docker compose -f docker-compose.yml build ``` ## 起動 ### 起動方法 航路画定、機体情報、離着陸場情報の各システム、Discovery FinderおよびDiscovery Serviceが起動した後で、以下を実行します。 ```sh docker compose -f docker-compose.yml up -d ``` **注意:** `-f`オプションでファイルを指定しない場合、意図せぬ動作になりますので、必ず指定してください。 プロジェクトルートのスクリプトを実行しても、起動できます。 ```sh ./default-run.sh ``` このスクリプトでは.envをチェックしてからdocker composeコマンドを実行します。 ### 起動確認方法 以下のコマンドより、app、fuseki、rabbitmqの各サービスの起動状況がわかります。 ```sh docker compose -f docker-compose.yml ps ``` 以下のコマンドより、app、fuseki、rabbitmqの各サービスのログがわかります。 ```sh docker compose -f docker-compose.yml logs app docker compose -f docker-compose.yml logs fuseki docker compose -f docker-compose.yml logs rabbitmq ``` 以下のようにすると各サービスのアクセスを確認できます。 **app** ブラウザより~/api/v1/sparqlへアクセスします。サービス記述が表示されます。 (ローカル環境の場合、 http://localhost:8080/api/v1/sparql となります。) **fuseki** ブラウザより~:3030へアクセスします。ログインダイアログが表示されます。 (ローカル環境の場合、 http://localhost:3030 となります。) **rabbitmq** ブラウザより~:15672へアクセスします。ログインダイアログが表示されます。 (ローカル環境の場合、http://localhost:15672 となります。) ## 停止 以下を実行します。 ```sh docker compose -f docker-compose.yml down ``` ## 利用 ### SPARQLクエリ 以下のようにして検索できます。 (ローカル環境の場合の例です。本番環境の場合は適宜URLを指定します。) ```sh curl -X POST \ http://localhost:8080/api/v1/sparql/query \ -H 'Content-Type: text/plain' \ -d 'SELECT * WHERE { ?s ?p ?o } LIMIT 10' ``` ### OpenAPI 以下のエンドポイントがあります。いずれもデバッグ用エンドポイントは記載されていません。 (ローカル環境のURLを示しています。本番環境については適宜読み替えて下さい。) - http://localhost:8080/swagger-ui/index.html (閲覧用) - http://localhost:8080/v3/api-docs (JSON表示用) - http://localhost:8080/v3/api-docs.yaml (YAML表示用) ### Fuseki管理ページ 以下にアクセスし、管理者ユーザー名とパスワードでログインすると、RDFデータを管理できます。 (ローカル環境のURLを示しています。本番環境については適宜読み替えて下さい。) - http://localhost:3030 ### RabbitMQ管理ページ 以下にアクセスし、RabbitMQユーザー名とパスワードでログインすると、キューの概要を管理できます。 (ローカル環境のURLを示しています。本番環境については適宜読み替えて下さい。) - http://localhost:15672 ## 管理 ### Fuseki管理者パスワードの変更 Fuseki管理者パスワードは、コンテナの/fusekiディレクトリが空のときにのみ生成されるため、最初にFusekiボリュームを削除する必要があります。 1. Fusekiコンテナが停止して削除されていることを確認します。 2. `docker volume rm rdf-server_fuseki-data` を実行してボリュームを削除します。 3. `.env`内の`FUSEKI_ADMIN_PASSWORD`の値を変更します。 4. `docker compose -f docker-compose.yml build fuseki`でFusekiを再ビルドします。 コマンド中のボリューム名は本RDFサーバーのディレクトリ名に基づいています(通常は rdf-server です)。 ディレクトリ名を変更した場合は、ボリューム名も同様に置き換えてください。 ### データ永続化 データ永続化のため、以下のボリュームを使用します。 - `fuseki-data` Fusekiデータ用 - `rdf-patch-log` RDF Patchログ用 - `rabbitmq-data` RabbitMQデータ用 - `rabbitmq-log` RabbitMQログ用 ## 開発 プロジェクトにはVS Code Dev Containersを使用した開発設定が含まれています。WSL2の使用が推奨されます。 1. VS CodeとDev Containers拡張機能をインストールします 2. プロジェクトをVS Codeで開きます 3. 重要: "Reopen in Container"をクリックする前にdocker compose upを実行しないでください。 4. プロンプトが表示されたら、"Reopen in Container"をクリックします 5. fusekiなどの追加コンテナを実行する必要がある場合は、docker compose up [YOUR_SERVICE]を手動で実行します。重要: "app"サービスを指定しないでください。 **注意:** 開発セットアップでは、環境がdeveloperユーザー(UIDとGIDが1000に設定)としてログインするように構成されています。 ## ライセンス - 本リポジトリはMITライセンスで提供されています。 - ソースコードおよび関連ドキュメントの著作権はIntentExchange株式会社に帰属します。 ## 免責事項 - 本リポジトリの内容は予告なく変更・削除する可能性があります。 - 本リポジトリの利用により生じた損失及び損害等について、いかなる責任も負わないものとします。