Skip to content

Commit 07460fb

Browse files
author
eirslett
committed
Use Archaius for Hystrix plugin setup
Currently, Hystrix lets you define custom strategies in two ways: 1) with System properties 2) with bootstrapping via HystrixPlugins.getInstance().registerXXX If neither is specified, the default strategy is used. This change replaces hardwired System.getProperty calls with lookup via Archaius. So one can override the plugin strategies used with any configuration provider Archaius is configured with. Most importantly, it has the effect of checking any file called "config.properties" on the classpath as well as using system properties. This lets you configure plugin strategies without having to write Java code for it, or having to run the application with additional system properties. Fixes Netflix#92
1 parent 05ea381 commit 07460fb

File tree

1 file changed

+31
-34
lines changed

1 file changed

+31
-34
lines changed

hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java

+31-34
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.concurrent.atomic.AtomicReference;
1919

20+
import com.netflix.config.DynamicPropertyFactory;
2021
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
2122
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
2223
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
@@ -33,7 +34,7 @@
3334
* Registry for plugin implementations that allows global override and handles the retrieval of correct implementation based on order of precedence:
3435
* <ol>
3536
* <li>plugin registered globally via <code>register</code> methods in this class</li>
36-
* <li>plugin registered and retrieved using {@link java.lang.System#getProperty(String)} (see get methods for property names)</li>
37+
* <li>plugin registered and retrieved using Archaius (see get methods for property names)</li>
3738
* <li>default implementation</li>
3839
* </ol>
3940
* See the Hystrix GitHub Wiki for more information: <a href="https://github.com/Netflix/Hystrix/wiki/Plugins">https://github.com/Netflix/Hystrix/wiki/Plugins</a>.
@@ -71,21 +72,21 @@ public static void reset() {
7172
/**
7273
* Retrieve instance of {@link HystrixEventNotifier} to use based on order of precedence as defined in {@link HystrixPlugins} class header.
7374
* <p>
74-
* Override default by using {@link #registerEventNotifier(HystrixEventNotifier)} or setting property: <code>hystrix.plugin.HystrixEventNotifier.implementation</code> with the full classname to
75+
* Override default by using {@link #registerEventNotifier(HystrixEventNotifier)} or setting property (via Archaius): <code>hystrix.plugin.HystrixEventNotifier.implementation</code> with the full classname to
7576
* load.
7677
*
7778
* @return {@link HystrixEventNotifier} implementation to use
7879
*/
7980
public HystrixEventNotifier getEventNotifier() {
8081
if (notifier.get() == null) {
81-
// check for an implementation from System.getProperty first
82-
Object impl = getPluginImplementationViaProperty(HystrixEventNotifier.class);
82+
// check for an implementation from Archaius first
83+
Object impl = getPluginImplementationViaArchaius(HystrixEventNotifier.class);
8384
if (impl == null) {
84-
// nothing set via properties so initialize with default
85+
// nothing set via Archaius so initialize with default
8586
notifier.compareAndSet(null, HystrixEventNotifierDefault.getInstance());
8687
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
8788
} else {
88-
// we received an implementation from the system property so use it
89+
// we received an implementation from Archaius so use it
8990
notifier.compareAndSet(null, (HystrixEventNotifier) impl);
9091
}
9192
}
@@ -109,21 +110,21 @@ public void registerEventNotifier(HystrixEventNotifier impl) {
109110
/**
110111
* Retrieve instance of {@link HystrixConcurrencyStrategy} to use based on order of precedence as defined in {@link HystrixPlugins} class header.
111112
* <p>
112-
* Override default by using {@link #registerConcurrencyStrategy(HystrixConcurrencyStrategy)} or setting property: <code>hystrix.plugin.HystrixConcurrencyStrategy.implementation</code> with the
113+
* Override default by using {@link #registerConcurrencyStrategy(HystrixConcurrencyStrategy)} or setting property (via Archaius): <code>hystrix.plugin.HystrixConcurrencyStrategy.implementation</code> with the
113114
* full classname to load.
114115
*
115116
* @return {@link HystrixConcurrencyStrategy} implementation to use
116117
*/
117118
public HystrixConcurrencyStrategy getConcurrencyStrategy() {
118119
if (concurrencyStrategy.get() == null) {
119-
// check for an implementation from System.getProperty first
120-
Object impl = getPluginImplementationViaProperty(HystrixConcurrencyStrategy.class);
120+
// check for an implementation from Archaius first
121+
Object impl = getPluginImplementationViaArchaius(HystrixConcurrencyStrategy.class);
121122
if (impl == null) {
122-
// nothing set via properties so initialize with default
123+
// nothing set via Archaius so initialize with default
123124
concurrencyStrategy.compareAndSet(null, HystrixConcurrencyStrategyDefault.getInstance());
124125
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
125126
} else {
126-
// we received an implementation from the system property so use it
127+
// we received an implementation from Archaius so use it
127128
concurrencyStrategy.compareAndSet(null, (HystrixConcurrencyStrategy) impl);
128129
}
129130
}
@@ -147,21 +148,21 @@ public void registerConcurrencyStrategy(HystrixConcurrencyStrategy impl) {
147148
/**
148149
* Retrieve instance of {@link HystrixMetricsPublisher} to use based on order of precedence as defined in {@link HystrixPlugins} class header.
149150
* <p>
150-
* Override default by using {@link #registerMetricsPublisher(HystrixMetricsPublisher)} or setting property: <code>hystrix.plugin.HystrixMetricsPublisher.implementation</code> with the full
151+
* Override default by using {@link #registerMetricsPublisher(HystrixMetricsPublisher)} or setting property (via Archaius): <code>hystrix.plugin.HystrixMetricsPublisher.implementation</code> with the full
151152
* classname to load.
152153
*
153154
* @return {@link HystrixMetricsPublisher} implementation to use
154155
*/
155156
public HystrixMetricsPublisher getMetricsPublisher() {
156157
if (metricsPublisher.get() == null) {
157-
// check for an implementation from System.getProperty first
158-
Object impl = getPluginImplementationViaProperty(HystrixMetricsPublisher.class);
158+
// check for an implementation from Archaius first
159+
Object impl = getPluginImplementationViaArchaius(HystrixMetricsPublisher.class);
159160
if (impl == null) {
160-
// nothing set via properties so initialize with default
161+
// nothing set via Archaius so initialize with default
161162
metricsPublisher.compareAndSet(null, HystrixMetricsPublisherDefault.getInstance());
162163
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
163164
} else {
164-
// we received an implementation from the system property so use it
165+
// we received an implementation from Archaius so use it
165166
metricsPublisher.compareAndSet(null, (HystrixMetricsPublisher) impl);
166167
}
167168
}
@@ -185,21 +186,21 @@ public void registerMetricsPublisher(HystrixMetricsPublisher impl) {
185186
/**
186187
* Retrieve instance of {@link HystrixPropertiesStrategy} to use based on order of precedence as defined in {@link HystrixPlugins} class header.
187188
* <p>
188-
* Override default by using {@link #registerPropertiesStrategy(HystrixPropertiesStrategy)} or setting property: <code>hystrix.plugin.HystrixPropertiesStrategy.implementation</code> with the full
189+
* Override default by using {@link #registerPropertiesStrategy(HystrixPropertiesStrategy)} or setting property (via Archaius): <code>hystrix.plugin.HystrixPropertiesStrategy.implementation</code> with the full
189190
* classname to load.
190191
*
191192
* @return {@link HystrixPropertiesStrategy} implementation to use
192193
*/
193194
public HystrixPropertiesStrategy getPropertiesStrategy() {
194195
if (propertiesFactory.get() == null) {
195-
// check for an implementation from System.getProperty first
196-
Object impl = getPluginImplementationViaProperty(HystrixPropertiesStrategy.class);
196+
// check for an implementation from Archaius first
197+
Object impl = getPluginImplementationViaArchaius(HystrixPropertiesStrategy.class);
197198
if (impl == null) {
198-
// nothing set via properties so initialize with default
199+
// nothing set via Archaius so initialize with default
199200
propertiesFactory.compareAndSet(null, HystrixPropertiesStrategyDefault.getInstance());
200201
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
201202
} else {
202-
// we received an implementation from the system property so use it
203+
// we received an implementation from Archaius so use it
203204
propertiesFactory.compareAndSet(null, (HystrixPropertiesStrategy) impl);
204205
}
205206
}
@@ -223,7 +224,7 @@ public void registerPropertiesStrategy(HystrixPropertiesStrategy impl) {
223224
/**
224225
* Retrieve instance of {@link HystrixCommandExecutionHook} to use based on order of precedence as defined in {@link HystrixPlugins} class header.
225226
* <p>
226-
* Override default by using {@link #registerCommandExecutionHook(HystrixCommandExecutionHook)} or setting property: <code>hystrix.plugin.HystrixCommandExecutionHook.implementation</code> with the
227+
* Override default by using {@link #registerCommandExecutionHook(HystrixCommandExecutionHook)} or setting property (via Archaius): <code>hystrix.plugin.HystrixCommandExecutionHook.implementation</code> with the
227228
* full classname to
228229
* load.
229230
*
@@ -233,14 +234,14 @@ public void registerPropertiesStrategy(HystrixPropertiesStrategy impl) {
233234
*/
234235
public HystrixCommandExecutionHook getCommandExecutionHook() {
235236
if (commandExecutionHook.get() == null) {
236-
// check for an implementation from System.getProperty first
237-
Object impl = getPluginImplementationViaProperty(HystrixCommandExecutionHook.class);
237+
// check for an implementation from Archaius first
238+
Object impl = getPluginImplementationViaArchaius(HystrixCommandExecutionHook.class);
238239
if (impl == null) {
239-
// nothing set via properties so initialize with default
240+
// nothing set via Archaius so initialize with default
240241
commandExecutionHook.compareAndSet(null, HystrixCommandExecutionHookDefault.getInstance());
241242
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
242243
} else {
243-
// we received an implementation from the system property so use it
244+
// we received an implementation from Archaius so use it
244245
commandExecutionHook.compareAndSet(null, (HystrixCommandExecutionHook) impl);
245246
}
246247
}
@@ -263,15 +264,11 @@ public void registerCommandExecutionHook(HystrixCommandExecutionHook impl) {
263264
}
264265
}
265266

266-
private static Object getPluginImplementationViaProperty(Class<?> pluginClass) {
267+
private static Object getPluginImplementationViaArchaius(Class<?> pluginClass) {
267268
String classSimpleName = pluginClass.getSimpleName();
268-
/*
269-
* Check system properties for plugin class.
270-
* <p>
271-
* This will only happen during system startup thus it's okay to use the synchronized System.getProperties
272-
* as it will never get called in normal operations.
273-
*/
274-
String implementingClass = System.getProperty("hystrix.plugin." + classSimpleName + ".implementation");
269+
// Check Archaius for plugin class.
270+
String propertyName = "hystrix.plugin." + classSimpleName + ".implementation";
271+
String implementingClass = DynamicPropertyFactory.getInstance().getStringProperty(propertyName, null).get();
275272
if (implementingClass != null) {
276273
try {
277274
Class<?> cls = Class.forName(implementingClass);

0 commit comments

Comments
 (0)