com.netflix.config.DynamicContextualProperty Maven / Gradle / Ivy
/**
* 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.
*/
package com.netflix.config;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
/**
* A property that has multiple possible values associated with it and determines
* the value according to the runtime context, which can include deployment context,
* values of other properties or attributes of user input.
*
* The value is defined as a JSON blob that
* consists of multiple conditions and value associated with each condition. The following
* is an example:
*
*
{@code
* [
{
"if":
{"@environment":["prod"],
"@region":["us-east-1"]
},
"value":5
},
{
"if":
{"@environment":["test", "dev"]},
"value":10
},
{
"value":2
}
]
* }
*
* This blob means that
If "@enviornment" is "prod" and "@region" is "us-east-1", value of the property is integer 5; (Note: if you use ConfigurationManager, "@enviornment" and "@region" are automatically exported as properties from DeploymentContext)
Else if "@environment" is either "test" or "dev", the value is 10;
Otherwise, the default value of the property is 2
*
* In order to make this work, a Predicate is needed to determine if the current runtime context matches any of the conditions
* described in the JSON blob. The predicate can be passed in as a parameter of the constructor, otherwise the default one
* will interpret each key in the "dimensions" as a key of a DynamicProperty, and the list of values are the acceptable
* values of the DynamicProperty.
*
* For example:
*
*
{@code
*
* String json = ... // string as the above JSON blob
* ConfigurationManager.getConfigInstance().setProperty("@environment", "test"); // no need to do this in real application as property is automatically set
ConfigurationManager.getConfigInstance().setProperty("contextualProp", json);
DynamicContextualProperty prop = new DynamicContextualProperty("contextualProp", 0);
prop.get(); // returns 10 as "@environment" == "test" matches the second condition
* }
*
* @author awang
*
* @param Data type of the property, e.g., Integer, Boolean
*/
public class DynamicContextualProperty extends PropertyWrapper {
public static class Value {
private Map> dimensions;
private T value;
private String comment;
private boolean runtimeEval = false;
public Value() {
}
public Value(T value) {
this.value = value;
}
@JsonProperty("if")
public final Map> getDimensions() {
return dimensions;
}
@JsonProperty("if")
public final void setDimensions(Map> dimensions) {
this.dimensions = dimensions;
}
public final T getValue() {
return value;
}
public final void setValue(T value) {
this.value = value;
}
public final String getComment() {
return comment;
}
public final void setComment(String comment) {
this.comment = comment;
}
public final boolean isRuntimeEval() {
return runtimeEval;
}
public final void setRuntimeEval(boolean runtimeEval) {
this.runtimeEval = runtimeEval;
}
}
private static Predicate