Fessのダッシュボード画面の改善

FessにはKopfというクラスター管理UIがバンドルされている。元々はelasticsearch-kopfをfess用にフォークしたものを使っていたのだけど、今回fess-kopfとして新しいリポジトリに移行しました。

なぜ移行したのか

Kopfはクラスターの状態確認やインデックス管理ができるWebベースの管理ツールで、結構便利に使えるものだったりする。ただ、元々のelasticsearch-kopfはもうメンテナンスされていない状態で、何か改善しようにも手を入れづらい状態だった。

ということで、Fess専用として独自にメンテナンスできるようにフォークすることにしました。

何を変えたか

OpenSearch対応

OpenSearch 2.x/3.xで動くように、以下のあたりを対応した。

  • OpenSearchのバージョン検出を追加
  • 廃止された機能をメニューから削除
  • Percolator(Elasticsearch 5.xで非推奨になったやつ)
  • Index Warmers(同上)
  • Benchmark API(Elasticsearch 5.xで消えた)
  • 設定名をelasticsearch_root_pathからopensearch_root_pathに変更(古い設定名でも動くようにはしてある)

見た目の改善

せっかくなので、見た目も今風にしてみた。

  • AdminLTE風のボタンやレイアウトに変更
  • dark、light、fessの3テーマ対応
  • 全体的にスペーシングとか見やすさを改善

古いコードも結構残っていたので、その辺も整理した。

開発環境まわり

  • Node.js 20.0.0以上を必須に
  • GitHub ActionsでCI/CDを整備
  • テストも追加

今後について

fess-kopfとして独立したことで、Fessの管理画面で利用しているダッシュボードのUIも改善していけるようになった。今まではメンテされていないkopfをそのまま使っていたので、なかなか手を入れられなかったのだけど、これからは必要に応じて改善を進めていけるはずです。

 FessのMicrosoft Entra ID対応

MicrosoftがAzure Active Directory (Azure AD)をMicrosoft Entra IDにリブランディングしたことに伴い、Fess 15.4では命名規則を新しいブランドに合わせて変更しました。また、ネストしたグループメンバーシップを持つユーザーのログイン遅延を解消するため、親グループの遅延読み込み機能を実装しました。

Azure ADからEntra IDへの名称変更

以下のクラス名と設定キーが変更されました。

クラス名の変更

旧クラス名新クラス名
AzureAdCredentialEntraIdCredential
AzureAdAuthenticatorEntraIdAuthenticator
AzureAdUserEntraIdUser

設定キーの変更

設定キーはaad.*からentraid.*に変更されました。

# 旧設定
sso.type=aad
aad.tenant=<tenant_name>.onmicrosoft.com
aad.client.id=...
aad.client.secret=...

# 新設定
sso.type=entraid
entraid.tenant=<tenant_name>.onmicrosoft.com
entraid.client.id=...
entraid.client.secret=...

後方互換性

既存のaad.*設定キーは引き続き動作するように後方互換性が維持されています。SSOタイプとしてaadを指定した場合も、内部的にentraidとして処理されます。既存の設定を変更する必要はありませんが、新規設定ではentraid.*の使用を推奨します。

親グループの遅延読み込み

Entra IDでは、ユーザーが複数のネストしたグループに所属している場合、ログイン時にすべてのグループ情報を取得するのに時間がかかることがありました。この問題を解消するため、親グループの取得を非同期で行う遅延読み込み機能を実装しました。

動作の仕組み

  1. ログイン時: ユーザーの直接所属グループのみを同期的に取得
  2. ログイン後: 親グループ(ネストしたグループ)をバックグラウンドで非同期取得
  3. 取得完了時: パーミッションを再計算して更新

この改善により、多くのネストしたグループメンバーシップを持つユーザーでもログインが高速化されます。

スレッドセーフティの改善

非同期処理に対応するため、EntraIdUserクラスには以下のスレッドセーフティ改善が行われました。

  • groupsrolespermissionsフィールドにvolatile修飾子を追加
  • setGroups()setRoles()メソッドをsynchronizedに変更
  • 非同期更新後にパーミッション再計算を行うresetPermissions()メソッドを追加

詳細

詳細は以下のPRを参照してください。

  • PR #2976 – Rename Azure AD to Microsoft Entra ID
  • PR #2977 – Add lazy loading for parent group lookup in EntraIdAuthenticator

Fessのサムネイル生成スクリプトのリファクタリング

Fessのサムネイル生成スクリプト(generate-thumbnail)をリファクタリングしました。主な変更点は以下の通りです。

ImageMagick v7対応

ImageMagick v7ではconvertコマンドがmagickコマンドに変わりました。今回の修正で、v7のmagickコマンドを優先的に使用し、存在しない場合はv6のconvertコマンドにフォールバックするようにしました。

get_imagemagick_cmd() {
  if command -v magick >/dev/null 2>&1; then
    echo "magick"
  elif command -v convert >/dev/null 2>&1; then
    echo "convert"
  else
    echo ""
  fi
}

SVGサムネイル生成

SVGファイルのサムネイル生成に対応しました。rsvg-convertコマンドを使用してSVGをPNGに変換します。

elif [[ x"${cmd_type}" = "xsvg" ]] ; then
  check_command rsvg-convert
  target_file=$(echo "$url" | sed -e "s#^file:/*#/#g")
  rsvg-convert -w 100 -h 100 --keep-aspect-ratio "${target_file}" -o "${output_file}"

MIMEタイプによるフォーマット検出

画像ファイルのサムネイル生成時にMIMEタイプを渡せるようにしました。ImageMagickはファイル拡張子からフォーマットを判定することがありますが、一時ファイルには適切な拡張子がない場合があります。MIMEタイプからフォーマットヒントを生成してImageMagickに渡すことで、より確実にフォーマットを識別できるようになりました。

format_hint=""
case "${mimetype}" in
  "image/gif")  format_hint="gif:" ;;
  "image/tiff") format_hint="tiff:" ;;
  "image/png")  format_hint="png:" ;;
  "image/jpeg") format_hint="jpeg:" ;;
  "image/bmp"|"image/x-windows-bmp"|"image/x-ms-bmp") format_hint="bmp:" ;;
  "image/vnd.adobe.photoshop"|"image/photoshop"|"application/x-photoshop"|"application/photoshop") format_hint="psd:" ;;
esac
${im_cmd} -thumbnail ${image_size} "${format_hint}${target_file}" "${output_file}"

Java側でも、MIMEタイプに基づいて適切な拡張子を持つ一時ファイルを作成するようにしました。

protected String getExtensionFromMimeType(final String mimeType) {
    if (mimeType == null) {
        return "";
    }
    return switch (mimeType) {
    case "image/gif" -> ".gif";
    case "image/tiff" -> ".tiff";
    case "image/svg+xml" -> ".svg";
    case "image/jpeg" -> ".jpg";
    case "image/png" -> ".png";
    case "image/bmp", "image/x-windows-bmp", "image/x-ms-bmp" -> ".bmp";
    case "image/vnd.adobe.photoshop", "image/photoshop", "application/x-photoshop", "application/photoshop" -> ".psd";
    default -> "";
    };
}

macOS互換性

rootユーザーのHOMEディレクトリチェックにmacOS対応を追加しました。Linuxでは/rootですが、macOSでは/var/rootになるため、両方をチェックするようにしています。

if [[ x"$HOME" = "x/root" ]] || [[ x"$HOME" = "x/var/root" ]] ; then
  HOME=/var/lib/fess
fi

これらの変更はFess 15.4.0に含まれる予定です。