Fessのスケジューラ起動APIでジョブログIDを返すようにする

Fessのスケジューラには、REST APIからジョブを起動する機能があります。しかし、これまでのAPIでは起動後にジョブの実行状況を追跡するための情報が返されていませんでした。そこで、スケジューラ起動API(PUT /api/admin/scheduler/{id}/start)のレスポンスにジョブログIDを含めるようにしました。

背景

Fessの管理APIを使ってスケジュールジョブを起動した際、そのジョブの実行ログを確認するには、ジョブログの一覧から該当するものを探す必要がありました。ジョブの起動時にログIDがわかれば、APIを通じてジョブの実行状況を直接追跡できるようになります。

変更内容

APIレスポンスの変更

PUT /api/admin/scheduler/{id}/start のレスポンスに jobLogId フィールドを追加しました。

ジョブログが有効な場合:

{
  "response": {
    "version": "14.x",
    "status": 0,
    "jobLogId": "a1b2c3d4e5f6..."
  }
}

ジョブログが無効な場合:

{
  "response": {
    "version": "14.x",
    "status": 0,
    "jobLogId": null
  }
}

仕組み

ジョブの起動リクエストを受けると、以下の流れで処理されます。

  1. ジョブログが有効な場合、32文字の16進数UUID(ハイフンなし)を事前生成する
  2. 生成したIDをパラメータとしてジョブの起動時に渡す
  3. ジョブ実行時に、渡されたIDをジョブログのドキュメントIDとして設定する
  4. APIのレスポンスにこのIDを含めて返す

launchNow() は非同期で実行されるため、APIのレスポンスが返った時点ではジョブログがまだ存在しない場合があります。IDは事前に生成されているので、ジョブが実行された際に確実にそのIDが使用されます。

主な変更ファイル

  • Constants.javaJOB_LOG_ID 定数の追加
  • ScheduledJob.java – パラメータ付きの start(Map) メソッドを追加
  • ScriptExecutorJob.java – ランタイムパラメータからジョブログIDを取得して設定
  • ApiResult.javaApiStartJobResponse クラスを追加
  • ApiAdminSchedulerAction.java – UUID生成とレスポンスへの設定

後方互換性

既存の引数なしの start() メソッドは変更されていません。管理画面やウィザードからの起動は従来通り動作します。APIレスポンスに jobLogId フィールドが追加されるのみで、破壊的変更はありません。

まとめ

この変更により、APIからジョブを起動した際にジョブログIDを取得でき、プログラムからジョブの実行状況を追跡しやすくなりました。詳細は PR #3103 を参照してください。

Fessのクロール設定を複製する機能を追加

Fessでクロール設定を新規作成するとき、既存の設定と似た内容で作りたいことがあります。これまでは手動で各項目を入力し直す必要がありましたが、既存の設定を複製して新しい設定を作成できる機能を追加しました。

背景

Fessでは、Webクロール、ファイルクロール、データストアクロールの3種類のクロール設定を管理できます。運用中に新しいクロール対象を追加する際、既存の設定とほぼ同じ内容(クロール間隔、認証情報、パーミッションなど)で、URLやパスだけを変えたいケースはよくあります。

従来は新規作成画面を開いて一つずつ設定項目を入力する必要がありましたが、設定項目が多いため手間がかかり、設定ミスの原因にもなっていました。

複製機能の使い方

管理画面で複製したいクロール設定の詳細画面を開くと、フッター部分に「Duplicate」ボタンが追加されています。このボタンをクリックすると、既存の設定内容がコピーされた状態で新規作成画面が開きます。

名前(Name)フィールドだけは空欄になるので、新しい設定名を入力して保存します。それ以外の項目(URL、クロール深度、間隔、パーミッションなど)はすべて元の設定からコピーされます。

この機能は以下の3つのクロール設定すべてで利用できます。

  • Webクロール設定(Web Config)
  • ファイルクロール設定(File Config)
  • データストアクロール設定(Data Config)

技術的な仕組み

各クロール設定のAdminActionクラスにduplicate(String id)メソッドを追加しています。このメソッドは既存のcreatenew()パターンをベースに、指定されたIDの設定エンティティを読み込み、CreateFormにフィールド値をコピーします。

コピー時には、作成者や作成日時などの監査フィールド(createdBycreatedTimeなど)は除外されるため、複製先の設定に元の監査情報が引き継がれることはありません。また、パーミッションやバーチャルホストは適切にデコードされた状態でフォームにセットされます。

セキュリティ面では、既存のアクション同様に@Securedアノテーションによるロールベースのアクセス制御と、saveToken()によるCSRF対策が適用されています。

まとめ

クロール設定の複製機能により、似た設定を効率的に作成できるようになりました。特に多数のクロール対象を管理している環境では、設定作業の手間を大幅に削減できます。

関連リンク

Fessに複数インスタンス間の分散協調機能を追加 

Fessを複数インスタンスで運用している場合に、各インスタンスの状態を把握し、メンテナンス操作の競合を防止するための分散協調機能(CoordinatorHelper)を追加しました。

背景

Fessは同じOpenSearchクラスタに複数のインスタンスを接続して運用できますが、これまではインスタンス間で状態を共有する仕組みがなく、例えば複数のインスタンスから同時にリインデックスを実行してしまうといった問題が起こり得ました。この問題を解決するために、OpenSearchを利用した分散協調の仕組みを導入しました。

主な機能

インスタンスのハートビート管理

各Fessインスタンスは定期的にOpenSearchのfess_config.coordinatorインデックスにハートビートを送信します。ハートビートにはTTL(有効期限)が設定されており、期限切れのインスタンスは非アクティブとみなされます。これにより、現在稼働中のインスタンス一覧を取得できます。

メンテナンス操作の排他制御

リインデックス、設定インデックスの再構築、ドキュメントインデックスのリロード、クローラインデックスのクリアといったメンテナンス操作に対して、分散ロックの仕組みを導入しました。OpenSearchのop_type=createによる原子的なドキュメント作成を利用して排他制御を実現しています。

あるインスタンスが操作を開始すると、他のインスタンスからの同一操作の実行はブロックされ、どのインスタンスで実行中かを示すエラーメッセージが表示されます。ロックの解放にはif_seq_no/if_primary_termによる楽観的並行性制御を使用し、所有者のみがロックを解放できるようになっています。

また、ロックを保持しているインスタンスがダウンした場合は、TTLの期限切れやハートビートの不在を検知して、古いロックを自動的にクリーンアップします。

イベント通知

インスタンス間でイベントを通知する仕組みも用意しています。特定のインスタンスや全インスタンスに対してイベントを発行でき、定期的なポーリングで消費されます。将来的には、設定変更の通知や辞書の更新伝播などへの活用が予定されています。

設定

以下の設定項目が追加されています。

  • coordinator.poll.interval: ポーリング間隔(デフォルト60秒)
  • coordinator.heartbeat.ttl: ハートビートの有効期限
  • coordinator.operation.ttl: 操作ロックの有効期限
  • coordinator.event.ttl: イベントの有効期限

技術的なポイント

fess_config.coordinatorインデックスはnumber_of_shards: 1で作成されます。これは、op_type=createによる原子的なドキュメント作成が同一プライマリシャード上でのみ保証されるためです。

インスタンスIDはホスト名とPIDを組み合わせて生成されるため、同一ホスト上で複数のFessプロセスを実行している場合でも一意に識別できます。

関連リンク