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