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プロセスを実行している場合でも一意に識別できます。

関連リンク

Fess管理画面の検索結果編集でバリデーションとカスタムフィールド対応を改善

Fessの管理画面には、検索結果一覧からドキュメントを直接編集できる機能があります。今回、この編集画面のバリデーションメッセージの改善と、カスタムフィールドの編集対応を行いました。

背景

管理画面の検索結果編集画面(Admin Search List)では、ドキュメントのフィールドを編集する際にバリデーションが実行されます。しかし、いくつかの問題がありました。

  • バリデーションエラーのメッセージに doc. プレフィックスが表示され、ユーザーにとってわかりにくい表示になっていた
  • 配列フィールドのバリデーションで、配列用ではなく必須チェック用のエラーメッセージが誤って使われていた
  • 標準フィールド以外のカスタムフィールドが編集画面に表示されず、編集できなかった

バリデーションメッセージの修正

validateFields() メソッドでのエラーメッセージ生成を修正しました。従来は .map(s -> "doc." + s) でフィールド名にプレフィックスを付与した後、そのプレフィックス付きの名前をエラーメッセージの表示テキストとしても使っていました。

修正後は、"doc." プレフィックスはプロパティキー(JSPのバインディング用)にのみ使用し、表示テキストにはフィールド名そのものを使うようにしています。これにより、「doc.url is required.」ではなく「url is required.」と表示されるようになります。

// 修正前
.map(s -> "doc." + s)
.forEach(s -> messages.addErrorsPropertyRequired(s, s));

// 修正後
.forEach(s -> messages.addErrorsPropertyRequired("doc." + s, s));

配列フィールド用バリデーションメッセージの追加

配列フィールドのバリデーションでは、errors.property_required が誤って使用されていたため、専用の errors.property_type_array メッセージキーを新設しました。17言語すべてに翻訳を追加しています。

# 英語
errors.property_type_array={0} must be an array.

# 日本語
errors.property_type_array={0}は配列でなければなりません。

FessMessages クラスにも addErrorsPropertyTypeArray() メソッドを追加し、validateFields() メソッドから呼び出すようにしています。

カスタムフィールドの編集対応

編集画面では、URLやタイトルなどの標準フィールドはハードコードされた入力フォームで表示されますが、ユーザーが追加したカスタムフィールドは表示されていませんでした。

今回、registerExtraFields() メソッドを追加し、ドキュメントに含まれるフィールドのうち標準フィールド(STANDARD_EDIT_FIELDS)に含まれないものを動的に検出して編集画面に表示するようにしました。

フィールドの型は FessConfig の設定に基づいて自動判定されます。

  • 配列フィールド → テキストエリア
  • 日付フィールド → テキスト入力(日付フォーマットのバリデーション付き)
  • 数値フィールド(integer、long、float、double) → 数値入力
  • その他 → テキスト入力

また、_id_version_seq_no_primary_term などの内部メタデータフィールドは、セキュリティの観点から編集画面に表示されないよう除外しています。

カスタムフィールドの候補は、ドキュメントに含まれるキーだけでなく、FessConfig で定義されたフィールド定義からも取得されます。これにより、新規作成時やドキュメントにまだ値が設定されていないフィールドも編集画面に表示されます。

テストの追加

AdminSearchlistActionTest として27件のユニットテストを追加し、以下をカバーしています。

  • フォームの初期化とフィールドの割り当て
  • validateFields() の正常系・異常系(必須、float、long、日付)
  • バリデーションメッセージのプロパティキー形式
  • STANDARD_EDIT_FIELDS 定数の内容
  • registerExtraFields() のカスタムフィールド検出、型判定、ソート順、null処理
  • 予約フィールドの除外

まとめ

この改善により、管理画面の検索結果編集画面がより使いやすくなりました。バリデーションメッセージがわかりやすくなり、カスタムフィールドも直接編集できるようになっています。詳細は PR #3102 を参照してください。