brooklyn.policy.basic.PolicyConfigMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of brooklyn-core Show documentation
Show all versions of brooklyn-core Show documentation
Entity implementation classes, events, and other core elements
package brooklyn.policy.basic;
import static brooklyn.util.GroovyJavaMethods.elvis;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.config.ConfigKey;
import brooklyn.config.ConfigKey.HasConfigKey;
import brooklyn.entity.basic.ConfigMapViewWithStringKeys;
import brooklyn.entity.basic.Entities;
import brooklyn.entity.basic.EntityInternal;
import brooklyn.entity.basic.EntityLocal;
import brooklyn.event.basic.StructuredConfigKey;
import brooklyn.management.ExecutionContext;
import brooklyn.util.flags.TypeCoercions;
import brooklyn.util.internal.ConfigKeySelfExtracting;
import brooklyn.util.task.DeferredSupplier;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;
@SuppressWarnings("deprecation")
public class PolicyConfigMap implements brooklyn.config.ConfigMap {
private static final Logger LOG = LoggerFactory.getLogger(PolicyConfigMap.class);
/** policy against which config resolution / task execution will occur */
private final AbstractPolicy policy;
private final ConfigMapViewWithStringKeys mapViewWithStringKeys = new ConfigMapViewWithStringKeys(this);
/*
* TODO An alternative implementation approach would be to have:
* setParent(Entity o, Map inheritedConfig=[:])
* The idea is that the parent could in theory decide explicitly what in its config
* would be shared.
* I (Aled) am undecided as to whether that would be better...
*
* (Alex) i lean toward the config key getting to make the decision
*/
/**
* Map of configuration information that is defined at start-up time for the entity. These
* configuration parameters are shared and made accessible to the "children" of this
* entity.
*/
private final Map,Object> ownConfig = Collections.synchronizedMap(new LinkedHashMap, Object>());
public PolicyConfigMap(AbstractPolicy policy) {
this.policy = Preconditions.checkNotNull(policy, "policy must be specified");
}
public T getConfig(ConfigKey key) {
return getConfig(key, null);
}
public T getConfig(HasConfigKey key) {
return getConfig(key.getConfigKey(), null);
}
public T getConfig(HasConfigKey key, T defaultValue) {
return getConfig(key.getConfigKey(), defaultValue);
}
@SuppressWarnings("unchecked")
public T getConfig(ConfigKey key, T defaultValue) {
// FIXME What about inherited task in config?!
// alex says: think that should work, no?
// FIXME What if someone calls getConfig on a task, before setting parent app?
// alex says: not supported (throw exception, or return the task)
// In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key
// TODO If ask for a config value that's not in our configKeys, should we really continue with rest of method and return key.getDefaultValue?
// e.g. SshBasedJavaAppSetup calls setAttribute(JMX_USER), which calls getConfig(JMX_USER)
// but that example doesn't have a default...
ConfigKey ownKey = policy!=null ? (ConfigKey)elvis(policy.getPolicyType().getConfigKey(key.getName()), key) : key;
// Don't use groovy truth: if the set value is e.g. 0, then would ignore set value and return default!
if (ownKey instanceof ConfigKeySelfExtracting) {
if (((ConfigKeySelfExtracting)ownKey).isSet(ownConfig)) {
// FIXME Should we support config from futures? How to get execution context before setEntity?
EntityLocal entity = policy.entity;
ExecutionContext exec = (entity != null) ? ((EntityInternal)entity).getExecutionContext() : null;
return ((ConfigKeySelfExtracting)ownKey).extractValue(ownConfig, exec);
}
} else {
LOG.warn("Config key {} of {} is not a ConfigKeySelfExtracting; cannot retrieve value; returning default", ownKey, this);
}
return TypeCoercions.coerce((defaultValue != null) ? defaultValue : ownKey.getDefaultValue(), key.getTypeToken());
}
@Override
public Object getRawConfig(ConfigKey> key) {
if (ownConfig.containsKey(key)) return ownConfig.get(key);
return null;
}
/** returns the config of this policy */
public Map,Object> getAllConfig() {
// Don't use ImmutableMap because valide for values to be null
return Collections.unmodifiableMap(Maps.newLinkedHashMap(ownConfig));
}
public Object setConfig(ConfigKey> key, Object v) {
Object val;
if ((v instanceof Future) || (v instanceof DeferredSupplier)) {
// no coercion for these (coerce on exit)
val = v;
} else if (key instanceof StructuredConfigKey) {
// no coercion for these structures (they decide what to do)
val = v;
} else {
try {
val = TypeCoercions.coerce(v, key.getType());
} catch (Exception e) {
throw new IllegalArgumentException("Cannot coerce or set "+v+" to "+key, e);
}
}
Object oldVal;
if (key instanceof StructuredConfigKey) {
oldVal = ((StructuredConfigKey)key).applyValueToMap(val, ownConfig);
} else {
oldVal = ownConfig.put(key, val);
}
return oldVal;
}
@Override
public PolicyConfigMap submap(Predicate> filter) {
PolicyConfigMap m = new PolicyConfigMap(policy);
for (Map.Entry,Object> entry: ownConfig.entrySet())
if (filter.apply(entry.getKey()))
m.ownConfig.put(entry.getKey(), entry.getValue());
return m;
}
@Override
public String toString() {
return super.toString()+"[own="+Entities.sanitize(ownConfig)+"]";
}
public Map asMapWithStringKeys() {
return mapViewWithStringKeys;
}
@Override
public int size() {
return ownConfig.size();
}
@Override
public boolean isEmpty() {
return ownConfig.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy