| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 |
| * <p> |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * <p> |
| * 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 org.apache.hadoop.hdds.conf; |
| |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.concurrent.TimeUnit; |
| |
| /** |
| * Lightweight interface to defined the contract of the Configuration objects. |
| */ |
| public interface ConfigurationSource { |
| |
| String[] EMPTY_STRING_ARRAY = {}; |
| |
| String get(String key); |
| |
| Collection<String> getConfigKeys(); |
| |
| char[] getPassword(String key) throws IOException; |
| |
| @Deprecated |
| //TODO: user read only configs and don't use it to store actual port |
| // numbers. |
| void set(String key, String value); |
| |
| default String get(String key, String defaultValue) { |
| String value = get(key); |
| return value != null ? value : defaultValue; |
| } |
| |
| default int getInt(String key, int defaultValue) { |
| String value = get(key); |
| return value != null ? Integer.parseInt(value) : defaultValue; |
| } |
| |
| /** |
| * Get the value of the <code>name</code> property as a set of comma-delimited |
| * <code>int</code> values. |
| * <p> |
| * If no such property exists, an empty array is returned. |
| * |
| * @param name property name |
| * @return property value interpreted as an array of comma-delimited |
| * <code>int</code> values |
| */ |
| default int[] getInts(String name) { |
| String[] strings = getTrimmedStrings(name); |
| int[] ints = new int[strings.length]; |
| for (int i = 0; i < strings.length; i++) { |
| ints[i] = Integer.parseInt(strings[i]); |
| } |
| return ints; |
| } |
| |
| default long getLong(String key, long defaultValue) { |
| String value = get(key); |
| return value != null ? Long.parseLong(value) : defaultValue; |
| } |
| |
| default boolean getBoolean(String key, boolean defaultValue) { |
| String value = get(key); |
| return value != null ? Boolean.parseBoolean(value) : defaultValue; |
| } |
| |
| default float getFloat(String key, float defaultValue) { |
| String value = get(key); |
| return value != null ? Float.parseFloat(value) : defaultValue; |
| } |
| |
| default double getDouble(String key, double defaultValue) { |
| String value = get(key); |
| return value != null ? Double.parseDouble(value) : defaultValue; |
| } |
| |
| default String getTrimmed(String key) { |
| String value = get(key); |
| return value != null ? value.trim() : null; |
| } |
| |
| default String getTrimmed(String key, String defaultValue) { |
| String value = getTrimmed(key); |
| return value != null ? value : defaultValue; |
| } |
| |
| default String[] getTrimmedStrings(String name) { |
| String valueString = get(name); |
| if (null == valueString || valueString.trim().isEmpty()) { |
| return EMPTY_STRING_ARRAY; |
| } |
| |
| return valueString.trim().split("\\s*[,\n]\\s*"); |
| } |
| |
| default Map<String, String> getPropsWithPrefix(String confPrefix) { |
| Map<String, String> configMap = new HashMap<>(); |
| for (String name : getConfigKeys()) { |
| if (name.startsWith(confPrefix)) { |
| String value = get(name); |
| String keyName = name.substring(confPrefix.length()); |
| configMap.put(keyName, value); |
| } |
| } |
| return configMap; |
| } |
| |
| /** |
| * Create a Configuration object and inject the required configuration values. |
| * |
| * @param configurationClass The class where the fields are annotated with |
| * the configuration. |
| * @return Initiated java object where the config fields are injected. |
| */ |
| default <T> T getObject(Class<T> configurationClass) { |
| |
| T configObject; |
| |
| try { |
| configObject = configurationClass.newInstance(); |
| } catch (InstantiationException | IllegalAccessException e) { |
| throw new ConfigurationException( |
| "Configuration class can't be created: " + configurationClass, e); |
| } |
| ConfigGroup configGroup = |
| configurationClass.getAnnotation(ConfigGroup.class); |
| |
| String prefix = configGroup.prefix(); |
| |
| ConfigurationReflectionUtil |
| .injectConfiguration(this, configurationClass, configObject, |
| prefix); |
| |
| ConfigurationReflectionUtil |
| .callPostConstruct(configurationClass, configObject); |
| |
| return configObject; |
| |
| } |
| |
| /** |
| * Get the value of the <code>name</code> property as a <code>Class</code> |
| * implementing the interface specified by <code>xface</code>. |
| * <p> |
| * If no such property is specified, then <code>defaultValue</code> is |
| * returned. |
| * <p> |
| * An exception is thrown if the returned class does not implement the named |
| * interface. |
| * |
| * @param name the class name. |
| * @param defaultValue default value. |
| * @param xface the interface implemented by the named class. |
| * @return property value as a <code>Class</code>, |
| * or <code>defaultValue</code>. |
| */ |
| default <U> Class<? extends U> getClass(String name, |
| Class<? extends U> defaultValue, |
| Class<U> xface) { |
| try { |
| Class<?> theClass = getClass(name, defaultValue); |
| if (theClass != null && !xface.isAssignableFrom(theClass)) { |
| throw new RuntimeException(theClass + " not " + xface.getName()); |
| } else if (theClass != null) { |
| return theClass.asSubclass(xface); |
| } else { |
| return null; |
| } |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Get the value of the <code>name</code> property as a <code>Class</code>. |
| * If no such property is specified, then <code>defaultValue</code> is |
| * returned. |
| * |
| * @param name the class name. |
| * @param defaultValue default value. |
| * @return property value as a <code>Class</code>, |
| * or <code>defaultValue</code>. |
| */ |
| default Class<?> getClass(String name, Class<?> defaultValue) { |
| String valueString = getTrimmed(name); |
| if (valueString == null) { |
| return defaultValue; |
| } |
| try { |
| return Class.forName(name); |
| } catch (ClassNotFoundException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| default Class<?>[] getClasses(String name, Class<?>... defaultValue) { |
| String valueString = get(name); |
| if (null == valueString) { |
| return defaultValue; |
| } |
| String[] classnames = getTrimmedStrings(name); |
| try { |
| Class<?>[] classes = new Class<?>[classnames.length]; |
| for (int i = 0; i < classnames.length; i++) { |
| classes[i] = Class.forName(classnames[i]); |
| } |
| return classes; |
| } catch (ClassNotFoundException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| default long getTimeDuration(String name, long defaultValue, |
| TimeUnit unit) { |
| String vStr = get(name); |
| if (null == vStr) { |
| return defaultValue; |
| } else { |
| return TimeDurationUtil.getTimeDurationHelper(name, vStr, unit); |
| } |
| } |
| |
| default long getTimeDuration(String name, String defaultValue, |
| TimeUnit unit) { |
| String vStr = get(name); |
| if (null == vStr) { |
| return TimeDurationUtil.getTimeDurationHelper(name, defaultValue, unit); |
| } else { |
| return TimeDurationUtil.getTimeDurationHelper(name, vStr, unit); |
| } |
| } |
| |
| default double getStorageSize(String name, String defaultValue, |
| StorageUnit targetUnit) { |
| String vString = get(name); |
| if (vString == null) { |
| vString = defaultValue; |
| } |
| |
| // Please note: There is a bit of subtlety here. If the user specifies |
| // the default unit as "1GB", but the requested unit is MB, we will return |
| // the format in MB even thought the default string is specified in GB. |
| |
| // Converts a string like "1GB" to to unit specified in targetUnit. |
| |
| StorageSize measure = StorageSize.parse(vString); |
| |
| double byteValue = measure.getUnit().toBytes(measure.getValue()); |
| return targetUnit.fromBytes(byteValue); |
| } |
| |
| default Collection<String> getTrimmedStringCollection(String key) { |
| return Arrays.asList(getTrimmedStrings(key)); |
| } |
| |
| /** |
| * Return value matching this enumerated type. |
| * Note that the returned value is trimmed by this method. |
| * |
| * @param name Property name |
| * @param defaultValue Value returned if no mapping exists |
| * @throws IllegalArgumentException If mapping is illegal for the type |
| * provided |
| */ |
| default <T extends Enum<T>> T getEnum(String name, T defaultValue) { |
| final String val = getTrimmed(name); |
| return null == val |
| ? defaultValue |
| : Enum.valueOf(defaultValue.getDeclaringClass(), val); |
| } |
| |
| } |