ここでは、複数のBaseURLを持つシステムにおいて、BaseURL単位でテナントを解決する方法について説明します。
まず、複数のBaseURLを持つシステムの作成方法として、以下のいずれかを実装していること前提とします。
上記、CookBookを実装している場合、HTTP Header(x-com-base-url)には BaseURLが常に設定されます。
この x-com-base-url を用いたテナント解決の実装を行います。
なお、テナント解決の仕様については以下のリンクを参照してください。
https://document.intra-mart.jp/library/iap/public/setup/iap_setup_guide/texts/appendix/tenant_resolution/index.html
1.テナント解決用クラスを作成します。
このクラスは、プラグイン設定ファイル(後述)の BaseURL と TenantID を紐付けたパラメータを読み込みます。
また、すべての「テナントの環境情報」のベースURL 設定も読み込みます。
「テナントの環境情報」のベースURL
https://document.intra-mart.jp/library/iap/public/setup/iap_setup_guide/texts/tenant/setup_to_tenant_env.html
BaseURL からテナントを解決する優先順位は以下の通りです。
1、 テナント設定画面の BaseURL 設定
2、 プラグイン設定ファイル のパラメータ
【注意事項】
各設定を読み込むのは、このクラスが初期化されたタイミングとなるため、 各テナント設定画面の BaseURL を設定および変更した場合は、アプリケーションサーバの再起動が行われるまで反映されません。
また、分散環境の場合、全てのアプリケーションサーバの再起動が必要です。
com/example/HttpHeaderTenantIdResolver.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
package com.example; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.servlet.http.HttpServletRequest; import jp.co.intra_mart.common.platform.log.Logger; import jp.co.intra_mart.foundation.admin.tenant.TenantInfoManager; import jp.co.intra_mart.foundation.admin.tenant.context.RequestBasedTenantIdResolver; import jp.co.intra_mart.foundation.security.PropertyInitParamable; public class HttpHeaderTenantIdResolver implements RequestBasedTenantIdResolver, PropertyInitParamable { private static final class LazyHolder { public static final Map<String, String> TENANT_STATIC_MAP = new ConcurrentHashMap<String, String>(); public static Map<String, String> TENANT_MAP = new ConcurrentHashMap<String, String>(); } private static final String BASE_URL_ATTR_KEY = "im_base_url"; private static final String BASE_URL_HEADER_KEY = "x-com-base-url"; private static final Logger LOGGER = Logger.getLogger(HttpHeaderTenantIdResolver.class); @Override public void init(final Map<String, String> params) { // プラグイン設定情報の読み込み LazyHolder.TENANT_STATIC_MAP.clear(); LazyHolder.TENANT_STATIC_MAP.putAll(params); // BaseURLとテナント情報の読み込み load(); } @Override public String getTenantId(final HttpServletRequest request) { if (request == null) { return null; } // 一致する情報が無い時は、null を返却することで、後続の RequestBasedTenantIdResolver に処理を委ねることができます。 return LazyHolder.TENANT_MAP.get(request.getHeader(BASE_URL_HEADER_KEY)); } /** * BaseURLとテナント情報の読み込み */ private void load() { try { Map<String, String> newTenantMap = new ConcurrentHashMap<String, String>(); // プラグイン設定よりテナント設定が優先とする処理 newTenantMap.putAll(LazyHolder.TENANT_STATIC_MAP); newTenantMap.putAll(loadTenantInfo()); // 作成された情報の置き換え。 LazyHolder.TENANT_MAP = newTenantMap; } catch (Exception e) { LOGGER.error("Loading error.", e); } } /** * テナント情報からテナントIDとBaseURLのMapを作成。 * * @return テナントIDとBaseURLのMap * @throws Exception テナント情報取得時にエラーが発生した場合にスローされます。 */ private Map<String, String> loadTenantInfo() throws Exception { Map<String, String> newTenantMap = new ConcurrentHashMap<String, String>(); TenantInfoManager manager = new TenantInfoManager(); // 全テナント情報を取得し、BaseURLが設定されている場合は保管する。 for (final String tenantId : manager.getTenantIds()) { final String baseUrl = manager.getTenantInfo(tenantId).getAttributes() .get(HttpHeaderTenantIdResolver.BASE_URL_ATTR_KEY); if (baseUrl != null && baseUrl.trim().length() > 0) { newTenantMap.put(baseUrl.trim(), tenantId); } } return newTenantMap; } } |
2 .プラグイン設定ファイルの作成します。
WEB-INF/plugin/com.example.http.header.tenant.resolver_1.0.0/plugin.xml を作成します。
<param-name> には BaseURL、<param-value> には紐付けたい TenantID を記述します。
なお、この設定の値は、各テナントの設定画面のBaseURLに記述がない場合のみ使われます。
plugin.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="UTF-8"?> <plugin> <extension point="jp.co.intra_mart.foundation.admin.tenant.context.tenant.resolvers"> <tenant-id-resolvers id="com.example.http.header.tenant.resolver" version="1.0.0" rank="1"> <tenant-id-resolver class="com.example.HttpHeaderTenantIdResolver"> <init-param> <param-name>http://test1.sample.com/imart</param-name> <param-value>default</param-value> </init-param> <init-param> <param-name>http://test2.sample.com/imart</param-name> <param-value>default2</param-value> </init-param> </tenant-id-resolver> </tenant-id-resolvers> </extension> </plugin> |
これらの実装を行うことで、アクセスするBaseURL毎にテナントを解決することが可能です。