Java tutorial
package netflix.archaius; /** * Copyright 2014 Netflix, Inc. * * 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. */ import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.configuration.AbstractConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.netflix.config.ConcurrentMapConfiguration; import com.netflix.config.ConfigurationManager; import com.netflix.config.DynamicIntProperty; import com.netflix.config.DynamicLongProperty; import com.netflix.config.DynamicPropertyFactory; import com.netflix.config.DynamicStringProperty; import com.netflix.config.FixedDelayPollingScheduler; import com.netflix.config.jmx.ConfigJMXManager; import com.netflix.config.jmx.ConfigMBean; /** * A Sample Application built to showcase the usage of Configuration and DynamicProperties * <p> * To run this sample application, add the following jars to your classpath: * <ul> * <li>archaius-core-xxx.jar (latest release/snapshot of archaius-core) * <li>commons-configuration-1.8.jar * <li>commons-lang-2.6.jar * <li>commons-logging-1.1.1.jar * </ul> * * @author stonse * */ public class SampleApplication extends Thread { static ConfigMBean configMBean = null; public SampleApplication() { // This application is set up as a non-daemon app // as we want it to just hang around allowing us to launch jconsole // to perform properties based operations setDaemon(false); start(); } public void run() { while (true) { try { sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } } /** * SampleApplication entrypoint * @param args * @throws InterruptedException * @throws IOException */ public static void main(String[] args) throws InterruptedException, IOException { //@SuppressWarnings(value = {"unused" }) new SampleApplication(); // Step 1. // Create a Source of Configuration // Here we use a simple ConcurrentMapConfiguration // You can use your own, or use of the pre built ones including JDBCConfigurationSource // which lets you load properties from any RDBMS AbstractConfiguration myConfiguration = new ConcurrentMapConfiguration(); myConfiguration.setProperty("com.netflix.config.samples.sampleapp.prop1", "value1"); myConfiguration.setProperty("com.netflix.config.samples.SampleApp.SampleBean.name", "A Coffee Bean from Gautemala1"); // STEP 2: Optional. Dynamic Runtime property change option // We would like to utilize the benefits of obtaining dynamic property // changes // initialize the DynamicPropertyFactory with our configuration source DynamicPropertyFactory.initWithConfigurationSource(myConfiguration); // STEP 3: Optional. Option to inspect and modify properties using JConsole // We would like to inspect properties via JMX JConsole and potentially // update // these properties too // Register the MBean // // This can be also achieved automatically by setting "true" to // system property "archaius.dynamicPropertyFactory.registerConfigWithJMX" configMBean = ConfigJMXManager.registerConfigMbean(myConfiguration); // once this application is launched, launch JConsole and navigate to // the // Config MBean (under the MBeans tab) System.out.println("Started SampleApplication. Launch JConsole to inspect and update properties"); System.out.println( "To see how callback work, update property com.netflix.config.samples.SampleApp.SampleBean.sensitiveBeanData from BaseConfigBean in JConsole"); SampleBean sampleBean = new SampleBean(); System.out.println("SampleBean:" + sampleBean); System.out.println(sampleBean.getName()); System.setProperty("archaius.fixedDelayPollingScheduler.initialDelayMills", "100"); System.setProperty("archaius.fixedDelayPollingScheduler.delayMills", "100"); // System.setProperty("archaius.configurationSource.defaultFileName", "log4j.properties"); // ConfigurationManager.loadCascadedPropertiesFromResources("log4j"); FixedDelayPollingScheduler f = new FixedDelayPollingScheduler(100, 100, true); // create a property whose value is type long and use 1000 as the default // if the property is not defined System.setProperty("archaius.fixedDelayPollingScheduler.initialDelayMills", "100"); System.setProperty("archaius.fixedDelayPollingScheduler.delayMills", "100"); System.setProperty("archaius.configurationSource.defaultFileName", "log4j.properties"); ConfigurationManager.loadCascadedPropertiesFromResources("log4j"); // create a property whose value is type long and use 1000 as the default // if the property is not defined DynamicLongProperty timeToWait = DynamicPropertyFactory.getInstance().getLongProperty("lock.waitTime", 1000); ReentrantLock lock = new ReentrantLock(); // ... while (true) { lock.tryLock(timeToWait.get(), TimeUnit.MILLISECONDS); // timeToWait.get() returns up-to-date value of the property System.out.println("??" + timeToWait.get()); Thread.sleep(1000); // AbstractConfiguration myConfiguration = new ConcurrentMapConfiguration(); // myConfiguration.setProperty("lock.waitTime", 11); // DynamicPropertyFactory.initWithConfigurationSource(myConfiguration); // System.out.println( "??"+timeToWait.get()); } } } /** * Simple Class that has its field values influenced (assigned with values) from * Properties Some fields can get initialized at startup only and NOT change * when actual property value is changed. Others can use * <code>DynamicProperty</code> and contain values that are in sync with the * runtime changes to the property source. * * @author stonse * */ class SampleBean { /** * Default CTOR */ public SampleBean() { // value of field obtained during init only this.name = DynamicPropertyFactory.getInstance() .getStringProperty("com.netflix.config.samples.SampleApp.SampleBean.name", "Sample Bean").get(); } /** * Name of this bean :-) The value for this can be obtained from Properties */ public String name; /** * Number of seeds in this bean. The value for this is automatically * populated by the Configuration. Additionally, if the property value is * modified, the new value will be reflected as well We can assign a default * value as well in case a value was not configured or the configuration was * not successfully loaded * */ public DynamicIntProperty numSeeds = DynamicPropertyFactory.getInstance() .getIntProperty("com.netflix.config.samples.SampleApp.SampleBean.numSeeds", 2); /** * This field utilizes the feature of Callbacks. * When a property value is changed at runtime, it will receive a callback * which can be used to trigger other operations or used for bookkeeping */ DynamicStringProperty sensitiveBeanData = DynamicPropertyFactory.getInstance().getStringProperty( "com.netflix.config.samples.SampleApp.SampleBean.sensitiveBeanData", "magic", new Runnable() { public void run() { // let my auditing system know about this change System.out.println("SampleBean.sensitiveData changed to:" + sensitiveBeanData.get()); } }); /** * returns the name of this bean * @return */ public String getName() { return name; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("SampleBean ->name:"); sb.append(name); sb.append("\t numSeeds:"); sb.append(numSeeds); sb.append("\tsensitiveBeanData:"); sb.append(sensitiveBeanData); return sb.toString(); }; }