001package io.avaje.config; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005 006import java.math.BigDecimal; 007import java.net.URL; 008import java.util.Optional; 009import java.util.Properties; 010import java.util.function.Consumer; 011 012/** 013 * Provides application Configuration based on loading properties and yaml files 014 * as well as plugins that supply properties (like dynamic configuration loaded from a db). 015 * <p> 016 * The application can register onChange listeners to handle changes to configuration 017 * properties at runtime. Plugins or code can dynamically load and change properties and 018 * this can fire any registered callback handlers. 019 * </p> 020 * 021 * <h3>Examples</h3> 022 * <pre>{@code 023 * 024 * int port = Config.getInt("app.port", 8090); 025 * 026 * String topicName = Config.get("app.topic.name"); 027 * 028 * List<Integer> codes = Config.getList().ofInt("my.codes", 42, 54); 029 * 030 * }</pre> 031 */ 032public class Config { 033 034 static final Logger log = LoggerFactory.getLogger("io.avaje.config"); 035 036 private static final Configuration data = CoreConfiguration.initialise(); 037 038 /** 039 * Hide constructor. 040 */ 041 private Config() { 042 } 043 044 /** 045 * Return the loaded properties as standard Properties map. 046 */ 047 public static Properties asProperties() { 048 return data.asProperties(); 049 } 050 051 /** 052 * Return the underlying configuration. 053 */ 054 public static Configuration asConfiguration() { 055 return data; 056 } 057 058 /** 059 * Put all loaded properties into System properties. 060 */ 061 public static void loadIntoSystemProperties() { 062 data.loadIntoSystemProperties(); 063 } 064 065 /** 066 * Return a required configuration value as String. 067 * <p> 068 * IllegalStateException is thrown if the value is not defined in configuration. 069 * </p> 070 * 071 * @param key The configuration key 072 * @return The configured value 073 */ 074 public static String get(String key) { 075 return data.get(key); 076 } 077 078 /** 079 * Return a configuration string value with a given default. 080 * 081 * @param key The configuration key 082 * @param defaultValue The default value used 083 * @return The configured or default value 084 */ 085 public static String get(String key, String defaultValue) { 086 return data.get(key, defaultValue); 087 } 088 089 /** 090 * Return a configuration value that might not exist. 091 * 092 * @param key The configuration key 093 * @return The configured value wrapped as optional 094 */ 095 public static Optional<String> getOptional(String key) { 096 return data.getOptional(key); 097 } 098 099 /** 100 * Return boolean configuration value with the given default value. 101 * <p> 102 * IllegalStateException is thrown if the value is not defined in configuration. 103 * </p> 104 * 105 * <pre>{@code 106 * 107 * if (Config.enabled("feature.cleanup")) { 108 * ... 109 * } 110 * 111 * }</pre> 112 * 113 * @param key The configuration key 114 * @return True when configuration value is true 115 */ 116 public static boolean enabled(String key) { 117 return getBool(key); 118 } 119 120 /** 121 * Return boolean configuration value with the given default value. 122 * 123 * <pre>{@code 124 * 125 * if (Config.enabled("feature.cleanup", true)) { 126 * ... 127 * } 128 * 129 * }</pre> 130 * 131 * @param key The configuration key 132 * @return True when configuration value is true 133 */ 134 public static boolean enabled(String key, boolean enabledDefault) { 135 return getBool(key, enabledDefault); 136 } 137 138 /** 139 * Return a required boolean configuration value. 140 * <p> 141 * IllegalStateException is thrown if the value is not defined in configuration. 142 * </p> 143 * 144 * @param key The configuration key 145 * @return The configured value 146 */ 147 public static boolean getBool(String key) { 148 return data.getBool(key); 149 } 150 151 /** 152 * Return a configuration value as boolean given a default value. 153 * 154 * @param key The configuration key 155 * @param defaultValue The default value used 156 * @return The configured or default value 157 */ 158 public static boolean getBool(String key, boolean defaultValue) { 159 return data.getBool(key, defaultValue); 160 } 161 162 /** 163 * Return a required int configuration value. 164 * <p> 165 * IllegalStateException is thrown if the value is not defined in configuration. 166 * </p> 167 * 168 * @param key The configuration key 169 * @return The configured value 170 */ 171 public static int getInt(String key) { 172 return data.getInt(key); 173 } 174 175 /** 176 * Return a configuration value as int given a default value. 177 * 178 * @param key The configuration key 179 * @param defaultValue The default value used 180 * @return The configured or default value 181 */ 182 public static int getInt(String key, int defaultValue) { 183 return data.getInt(key, defaultValue); 184 } 185 186 /** 187 * Return a required long configuration value. 188 * <p> 189 * IllegalStateException is thrown if the value is not defined in configuration. 190 * </p> 191 * 192 * @param key The configuration key 193 * @return The configured value 194 */ 195 public static long getLong(String key) { 196 return data.getLong(key); 197 } 198 199 /** 200 * Return a configuration value as long given a default value. 201 * 202 * @param key The configuration key 203 * @param defaultValue The default value used 204 * @return The configured or default value 205 */ 206 public static long getLong(String key, long defaultValue) { 207 return data.getLong(key, defaultValue); 208 } 209 210 /** 211 * Return a decimal configuration value. 212 * 213 * @param key The configuration key 214 * @return The configured value 215 */ 216 public static BigDecimal getDecimal(String key) { 217 return data.getDecimal(key); 218 } 219 220 /** 221 * Return a decimal configuration value with a default value. 222 * <p> 223 * IllegalStateException is thrown if the value is not defined in configuration. 224 * </p> 225 * 226 * @param key The configuration key 227 * @param defaultValue The default value 228 * @return The configured value 229 */ 230 public static BigDecimal getDecimal(String key, String defaultValue) { 231 return data.getDecimal(key, defaultValue); 232 } 233 234 /** 235 * Return a URL configuration value. 236 * 237 * @param key The configuration key 238 * @return The configured value 239 */ 240 public static URL getURL(String key) { 241 return data.getURL(key); 242 } 243 244 /** 245 * Return a URL configuration value with a default value. 246 * <p> 247 * IllegalStateException is thrown if the value is not defined in configuration. 248 * </p> 249 * 250 * @param key The configuration key 251 * @param defaultValue The default value 252 * @return The configured value 253 */ 254 public static URL getURL(String key, String defaultValue) { 255 return data.getURL(key, defaultValue); 256 } 257 258 /** 259 * Return the enum configuration value. 260 * <p> 261 * IllegalStateException is thrown if the value is not defined in configuration. 262 * </p> 263 * 264 * @param type The enum type 265 * @param key The configuration key 266 * @return The configured value 267 */ 268 public static <T extends Enum<T>> T getEnum(Class<T> type, String key) { 269 return data.getEnum(type, key); 270 } 271 272 /** 273 * Return the enum configuration value with a default value. 274 * 275 * @param type The enum type 276 * @param key The configuration key 277 * @param defaultValue The default value 278 * @return The configured value 279 */ 280 public static <T extends Enum<T>> T getEnum(Class<T> type, String key, T defaultValue) { 281 return data.getEnum(type, key, defaultValue); 282 } 283 284 /** 285 * Return a List of values configured. 286 * 287 * <pre>{@code 288 * 289 * List<Integer> codes = Config.getList().ofInt("my.codes", 97, 45); 290 * 291 * }</pre> 292 */ 293 public static Configuration.ListValue getList() { 294 return data.getList(); 295 } 296 297 /** 298 * Return a Set of values configured. 299 * 300 * <pre>{@code 301 * 302 * Set<String> operations = Config.getSet().of("my.operations", "put","delete"); 303 * 304 * }</pre> 305 */ 306 public static Configuration.SetValue getSet() { 307 return data.getSet(); 308 } 309 310 /** 311 * Set a configuration value. 312 * <p> 313 * This will fire an configuration callback listeners that are registered 314 * for this key. 315 * </p> 316 */ 317 public static void setProperty(String key, String value) { 318 data.setProperty(key, value); 319 } 320 321 /** 322 * Register a callback for a change to the given configuration key. 323 * 324 * @param key The configuration key we want to detect changes to 325 * @param callback The callback handling to fire when the configuration changes. 326 */ 327 public static void onChange(String key, Consumer<String> callback) { 328 data.onChange(key, callback); 329 } 330 331 /** 332 * Register a callback for a change to the given configuration key as an Int value. 333 * 334 * @param key The configuration key we want to detect changes to 335 * @param callback The callback handling to fire when the configuration changes. 336 */ 337 public static void onChangeInt(String key, Consumer<Integer> callback) { 338 data.onChangeInt(key, callback); 339 } 340 341 /** 342 * Register a callback for a change to the given configuration key as an Long value. 343 * 344 * @param key The configuration key we want to detect changes to 345 * @param callback The callback handling to fire when the configuration changes. 346 */ 347 public static void onChangeLong(String key, Consumer<Long> callback) { 348 data.onChangeLong(key, callback); 349 } 350 351 /** 352 * Register a callback for a change to the given configuration key as an Boolean value. 353 * 354 * @param key The configuration key we want to detect changes to 355 * @param callback The callback handling to fire when the configuration changes. 356 */ 357 public static void onChangeBool(String key, Consumer<Boolean> callback) { 358 data.onChangeBool(key, callback); 359 } 360}