/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fujitsu.dc.engine.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 設定情報を保持するクラス. このクラスからクラスパス上にある dc-config.propertiesの内容にアクセスできます。 */ public class DcEngineConfig { /** * dc-config.propertiesの設定ファイルパスキー. */ static final String KEY_CONFIG_FILE = "io.personium.configurationFile"; /** * 本アプリで使うプロパティキーのプレフィクス. */ static final String KEY_ROOT = "io.personium.core."; static final String COMPATIBLE_KEY_ROOT = "io.personium.engine."; // For property compatibility. // Previous version of personium.io engine module had been used property names // starting with COMPATIBLE_KEY_ROOT. // Now, KEY_ROOT is used instead of COMPATIBLE_KEY_ROOT. static Map<String, String> compattibleToNormalKeyMap = new HashMap<String, String>(); /** * Converts old style property name to current style property name. * If the format is different from old style property name, returns the argument value as is. * @param compatibleKey Stale property name * @return Current property name */ static String convertCompatibleKeyToNormalKey(String compatibleKey) { if (compattibleToNormalKeyMap.containsKey(compatibleKey)) { return compattibleToNormalKeyMap.get(compatibleKey); } if (compatibleKey.startsWith(COMPATIBLE_KEY_ROOT)) { String normalKey = compatibleKey.replaceFirst(COMPATIBLE_KEY_ROOT, KEY_ROOT); compattibleToNormalKeyMap.put(compatibleKey, normalKey); return normalKey; } return compatibleKey; } /** * Elastic Search 関連の設定. */ public static final class ES { /** * Elastic Search ホスト設定のプロパティキー. */ public static final String HOSTS = KEY_ROOT + "elasticsearch.hosts"; /** * Elastic Search クラスタ名設定のプロパティキー. */ public static final String CLUSTERNAME = KEY_ROOT + "elasticsearch.cluster"; /** * ルーティングフラグ . */ public static final String ROUTING_FLAG = KEY_ROOT + "es.routingFlag"; /** * ユニットプレフィックス . */ public static final String UNIT_PREFIX = KEY_ROOT + "es.unitPrefix"; } /** * debug. */ public static final class DebugProp { /** 基底URL. */ public static final String KEY_DEFAULT_BASE_URL = KEY_ROOT + "defaultBaseUrl"; } /** * BinaryDataの設定. */ public static final class BinaryData { /** * ファイルへの書き込み時にfsyncを有効にするか否か(true:有効 false:無効(デフォルト)). */ public static final String FSYNC_ENABLED = KEY_ROOT + "binaryData.fsync.enabled"; } /** * Blobの設定. */ public static final class BlobStore { /** * Elastic Search を使用する際、blobデータを格納する方式設定のプロパティキー. 有効値: fs */ public static final String TYPE = KEY_ROOT + "blobStore.type"; /** * Elastic Search を使用する際、blobデータを格納するルート(URL, PATH)設定のプロパティキー. */ public static final String ROOT = KEY_ROOT + "blobStore.root"; } /** * マスタートークン設定のキー. */ public static final String MASTER_TOKEN = KEY_ROOT + "masterToken"; /** * X509廻りの設定. */ public static final class X509 { /** * X509ルート証明書を配置したパス設定のプロパティキー. */ public static final String ROOT_CRT = KEY_ROOT + "x509.root"; /** * X509秘密鍵を配置したパス設定のプロパティキー. */ public static final String KEY = KEY_ROOT + "x509.key"; /** * X509証明書を配置したパス設定のプロパティキー. */ public static final String CRT = KEY_ROOT + "x509.crt"; } /** * Security廻りの設定. */ public static final class Security { /** * トークンを暗号化する際に利用している秘密鍵. */ public static final String TOKEN_SECRET_KEY = KEY_ROOT + "security.sercret16"; } /** * バージョン廻りの設定. */ public static final String CONFIG_VERSION = KEY_ROOT + "version"; /** * バージョン情報を取得します. * @return バージョン情報 */ public static String getVersion() { return get(CONFIG_VERSION); } /** * ユニットマスタートークンの値を取得します. * @return マスタートークンの値 */ public static String getMasterToken() { return get(MASTER_TOKEN); } /** * 本UNITのX509秘密鍵ファイルのパスの設定値を取得します. * @return 設定値 */ public static String getX509PrivateKey() { return get(X509.KEY); } /** * 本UNITのX509ルート証明書ファイルのパスの設定値を取得します. * @return 設定値 */ public static String[] getX509RootCertificate() { String[] x509RootCertificate = null; String value = get(X509.ROOT_CRT); if (value != null) { x509RootCertificate = value.split(" "); } return x509RootCertificate; } /** * 本UNITのX509証明書ファイルのパスの設定値を取得します. * @return 設定値 */ public static String getX509Certificate() { return get(X509.CRT); } /** * トークンを暗号化する際に利用している秘密鍵設定. * @return 設定値 */ public static String getTokenSecretKey() { return get(Security.TOKEN_SECRET_KEY); } /** * singleton. */ private static DcEngineConfig singleton = new DcEngineConfig(); // static Logger log = LoggerFactory.getLogger(DcCoreConfig.class); /** * 設定値を格納するプロパティ実体. */ private final Properties props = new Properties(); /** * オーバーライドする設定値を格納するプロパティ実体. */ private final Properties propsOverride = new Properties(); /** * protectedなコンストラクタ. */ protected DcEngineConfig() { this.doReload(); } /** * 設定のリロード. */ private synchronized void doReload() { // Clear the compatible key map. compattibleToNormalKeyMap.clear(); Logger log = LoggerFactory.getLogger(DcEngineConfig.class); Properties properties = getDcConfigDefaultProperties(); Properties propertiesOverride = getDcConfigProperties(); // 読み込みに成功した場合、メンバ変数へ置換する if (!properties.isEmpty()) { this.props.clear(); for (Map.Entry<Object, Object> entry : properties.entrySet()) { if (!(entry.getKey() instanceof String)) { continue; } String key = convertCompatibleKeyToNormalKey((String) entry.getKey()); this.props.setProperty(key, (String) entry.getValue()); } } if (!propertiesOverride.isEmpty()) { this.propsOverride.clear(); for (Map.Entry<Object, Object> entry : propertiesOverride.entrySet()) { if (!(entry.getKey() instanceof String)) { continue; } String key = convertCompatibleKeyToNormalKey((String) entry.getKey()); this.propsOverride.setProperty(key, (String) entry.getValue()); } } for (Object keyObj : propsOverride.keySet()) { String key = (String) keyObj; String value = this.propsOverride.getProperty(key); if (value == null) { continue; } log.debug("Overriding Config " + key + "=" + value); this.props.setProperty(key, value); } } /** * dc-config-default.propertiesファイルを読み込む. * @return dc-config-default.properties */ protected Properties getDcConfigDefaultProperties() { Properties properties = new Properties(); InputStream is = DcEngineConfig.class.getClassLoader().getResourceAsStream("dc-config-default.properties"); try { properties.load(is); } catch (IOException e) { throw new RuntimeException("failed to load config!", e); } finally { try { is.close(); } catch (IOException e) { throw new RuntimeException("failed to close config stream", e); } } return properties; } /** * dc-config.propertiesファイルを読み込む. * @return dc-config.properties */ protected Properties getDcConfigProperties() { Logger log = LoggerFactory.getLogger(DcEngineConfig.class); Properties properties = new Properties(); String configFilePath = System.getProperty(KEY_CONFIG_FILE); InputStream is = getConfigFileInputStream(configFilePath); try { if (is != null) { properties.load(is); } else { log.debug("[dc-config.properties] file not found on the classpath. using default config."); } } catch (IOException e) { log.debug("IO Exception when loading [dc-config.properties] file."); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { log.debug("IO Exception when closing [dc-config.properties] file."); } } return properties; } /** * dc-config.propertiesをInputStream形式で取得する. * @param configFilePath 設定ファイルパス * @return dc-config.properties */ protected InputStream getConfigFileInputStream(String configFilePath) { Logger log = LoggerFactory.getLogger(DcEngineConfig.class); InputStream configFileInputStream = null; if (configFilePath == null) { configFileInputStream = DcEngineConfig.class.getClassLoader().getResourceAsStream("dc-config.properties"); return configFileInputStream; } try { // 設定ファイルを指定されたパスから読み込む File configFile = new File(configFilePath); configFileInputStream = new FileInputStream(configFile); log.info("dc-config.properties from system properties."); } catch (FileNotFoundException e) { // 指定されたパスにファイルが存在しない場合は、クラスパス上のファイルを読み込む configFileInputStream = DcEngineConfig.class.getClassLoader().getResourceAsStream("dc-config.properties"); log.info("dc-config.properties from class path."); } return configFileInputStream; } /** * 設定値の取得. * @param key キー * @return 設定値 */ private String doGet(final String key) { // For compatibility of old style property name prefix. String propKey = convertCompatibleKeyToNormalKey(key); return props.getProperty(propKey); } /** * すべてのプロパティを取得します。 * @return プロパティ一覧オブジェクト */ public static Properties getProperties() { return singleton.props; } /** * Key文字列を指定して設定情報を取得します. * @param key 設定キー * @return 設定値 */ public static String get(final String key) { return singleton.doGet(key); } /** * ElasticSearchのホスト名の設定値を取得します. * @return 設定値 */ public static String getEsHosts() { return get(ES.HOSTS); } /** * ElasticSearchのクラスタ名の設定値を取得します. * @return 設定値 */ public static String getEsClusterName() { return get(ES.CLUSTERNAME); } /** * 設定情報をリロードします. */ public static void reload() { singleton.doReload(); } /** * @return 基底URL. */ public static String getDefaultBaseUrl() { return get(DebugProp.KEY_DEFAULT_BASE_URL); } /** * @return blobデータを格納する方式. */ public static String getBlobStoreType() { return get(BlobStore.TYPE); } /** * @return blobデータを格納するルート(URL, PATH). */ public static String getBlobStoreRoot() { return get(BlobStore.ROOT); } /** * @return ルーティングフラグ (trueの場合、ルーティング処理を行う). */ public static boolean getRoutingFlag() { return Boolean.parseBoolean(get(ES.ROUTING_FLAG)); } /** * @return ユニットプレフィックス */ public static String getUnitPrefix() { return get(ES.UNIT_PREFIX); } /** * @return 有効である場合はtrue */ public static boolean getFsyncEnabled() { return Boolean.parseBoolean(get(BinaryData.FSYNC_ENABLED)); } }