Skip to content
Permalink
Browse files
allow spec parameters to imply sensors as well as config keys;
mainly intended for AttributeSensorAndConfigKey -- especially ports.

this means param of type `port` given a range causes a sensor to be published with the actual value.
  • Loading branch information
ahgittin committed Jan 21, 2016
1 parent 5e9012b commit 9141c99f4c0f295a3a39b75bf06b42f85650d3f4
Showing 13 changed files with 117 additions and 55 deletions.
@@ -20,13 +20,23 @@

import java.io.Serializable;

import javax.annotation.Nullable;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;

/** A wrapper around a {@link ConfigKey} which will be added to an {@link Entity},
* providing additional information for rendering in a UI */
public interface SpecParameter<T> extends Serializable {
/** Short name, to be used in UI */
String getLabel();
/** Visible by default in UI, not all inputs may be visible at once */
/** Whether visible by default in UI, not all inputs may be visible at once */
boolean isPinned();
/** Type information for the input */
ConfigKey<T> getType();
/** All config key info for this spec parameter;
* this is the config key which is added to the defined type */
ConfigKey<T> getConfigKey();
/** An optional sensor which may also be added to the defined type */
@Nullable AttributeSensor<?> getSensor();

}
@@ -62,20 +62,20 @@ public void testYamlInputsParsed() {
SpecParameter<?> firstInput = inputs.get(0);
assertEquals(firstInput.getLabel(), "simple");
assertEquals(firstInput.isPinned(), true);
assertEquals(firstInput.getType().getName(), "simple");
assertEquals(firstInput.getType().getTypeToken(), TypeToken.of(String.class));
assertEquals(firstInput.getConfigKey().getName(), "simple");
assertEquals(firstInput.getConfigKey().getTypeToken(), TypeToken.of(String.class));

SpecParameter<?> secondInput = inputs.get(1);
assertEquals(secondInput.getLabel(), "explicit_name");
assertEquals(secondInput.isPinned(), true);
assertEquals(secondInput.getType().getName(), "explicit_name");
assertEquals(secondInput.getType().getTypeToken(), TypeToken.of(String.class));
assertEquals(secondInput.getConfigKey().getName(), "explicit_name");
assertEquals(secondInput.getConfigKey().getTypeToken(), TypeToken.of(String.class));

SpecParameter<?> thirdInput = inputs.get(2);
assertEquals(thirdInput.getLabel(), "third_input");
assertEquals(thirdInput.isPinned(), true);
assertEquals(thirdInput.getType().getName(), "third_input");
assertEquals(thirdInput.getType().getTypeToken(), TypeToken.of(Integer.class));
assertEquals(thirdInput.getConfigKey().getName(), "third_input");
assertEquals(thirdInput.getConfigKey().getTypeToken(), TypeToken.of(Integer.class));
}

@Test
@@ -99,8 +99,8 @@ public void testOsgiType() {
SpecParameter<?> firstInput = inputs.get(0);
assertEquals(firstInput.getLabel(), "simple");
assertTrue(firstInput.isPinned());
assertEquals(firstInput.getType().getName(), "simple");
assertEquals(firstInput.getType().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY);
assertEquals(firstInput.getConfigKey().getName(), "simple");
assertEquals(firstInput.getConfigKey().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY);
}

@Test
@@ -126,7 +126,7 @@ public void testOsgiClassScanned() {
SpecParameter<?> input = inputs.get(0);
assertEquals(input.getLabel(), "more_config");
assertFalse(input.isPinned());
assertEquals(input.getType().getName(), "more_config");
assertEquals(input.getConfigKey().getName(), "more_config");
}

private String add(String... def) {
@@ -49,7 +49,6 @@

public class BasicConfigKey<T> implements ConfigKeySelfExtracting<T>, Serializable {

@SuppressWarnings("unused")
private static final Logger log = LoggerFactory.getLogger(BasicConfigKey.class);
private static final long serialVersionUID = -1762014059150215376L;

@@ -119,6 +118,13 @@ public Builder<T> constraint(Predicate<? super T> constraint) {
public BasicConfigKey<T> build() {
return new BasicConfigKey<T>(this);
}

public String getName() {
return name;
}
public String getDescription() {
return description;
}
}

private String name;
@@ -165,7 +171,7 @@ public BasicConfigKey(TypeToken<T> type, String name, String description, T defa
this.constraint = Predicates.alwaysTrue();
}

protected BasicConfigKey(Builder<T> builder) {
public BasicConfigKey(Builder<T> builder) {
this.name = checkNotNull(builder.name, "name");
this.type = TypeTokens.getRawTypeIfRaw(checkNotNull(builder.type, "type"));
this.typeToken = TypeTokens.getTypeTokenIfNotRaw(builder.type);
@@ -28,10 +28,9 @@
import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.objs.EntityAdjunct;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
import org.apache.brooklyn.core.objs.BrooklynObjectPredicate;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.objs.BrooklynObjectPredicate;
import org.apache.brooklyn.util.guava.Maybe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,12 +36,18 @@
import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.objs.BrooklynType;
import org.apache.brooklyn.api.objs.SpecParameter;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey.Builder;
import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.text.StringPredicates;
import org.apache.brooklyn.util.time.Duration;

import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
@@ -54,14 +60,26 @@
public class BasicSpecParameter<T> implements SpecParameter<T>{
private static final long serialVersionUID = -4728186276307619778L;

private String label;
private boolean pinned;
private ConfigKey<T> type;
private final String label;

/** pinning may become a priority or other more expansive indicator */
@Beta
private final boolean pinned;

private final ConfigKey<T> configKey;
private final AttributeSensor<?> sensor;

public BasicSpecParameter(String label, boolean pinned, ConfigKey<T> type) {
@Beta // TBD whether "pinned" stays
public BasicSpecParameter(String label, boolean pinned, ConfigKey<T> config) {
this(label, pinned, config, null);
}

@Beta // TBD whether "pinned" and "sensor" stay
public <SensorType> BasicSpecParameter(String label, boolean pinned, ConfigKey<T> config, AttributeSensor<SensorType> sensor) {
this.label = label;
this.pinned = pinned;
this.type = type;
this.configKey = config;
this.sensor = sensor;
}

@Override
@@ -73,15 +91,20 @@ public String getLabel() {
public boolean isPinned() {
return pinned;
}

@Override
public ConfigKey<T> getConfigKey() {
return configKey;
}

@Override
public ConfigKey<T> getType() {
return type;
public AttributeSensor<?> getSensor() {
return sensor;
}

@Override
public int hashCode() {
return Objects.hashCode(label, pinned, type);
return Objects.hashCode(label, pinned, configKey);
}

@Override
@@ -95,15 +118,15 @@ public boolean equals(Object obj) {
BasicSpecParameter<?> other = (BasicSpecParameter<?>) obj;
return Objects.equal(label, other.label) &&
pinned == other.pinned &&
Objects.equal(type, other.type);
Objects.equal(configKey, other.configKey);
}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("label", label)
.add("pinned", pinned)
.add("type", type)
.add("type", configKey)
.toString();
}

@@ -154,6 +177,7 @@ private static final class ParseYamlInputs {
.put("long", Long.class)
.put("float", Float.class)
.put("double", Double.class)
.put("duration", Duration.class)
.put("timestamp", Date.class)
.put("port", PortRange.class)
.build();
@@ -191,13 +215,23 @@ private static SpecParameter<?> parseParameter(Object obj, BrooklynClassLoadingC
throw new IllegalArgumentException("'name' value missing from input definition " + obj + " but is required. Check for typos.");
}

ConfigKey inputType = BasicConfigKey.builder(inferType(type, loader))
.name(name)
.description(description)
.defaultValue(defaultValue)
.constraint(constraints)
.build();
return new BasicSpecParameter(Objects.firstNonNull(label, name), true, inputType);
ConfigKey configType;
AttributeSensor sensorType = null;

TypeToken typeToken = inferType(type, loader);
Builder builder = BasicConfigKey.builder(typeToken)
.name(name)
.description(description)
.defaultValue(defaultValue)
.constraint(constraints);

if (PortRange.class.equals(typeToken.getRawType())) {
sensorType = new PortAttributeSensorAndConfigKey(builder);
configType = ((HasConfigKey)sensorType).getConfigKey();
} else {
configType = builder.build();
}
return new BasicSpecParameter(Objects.firstNonNull(label, name), true, configType, sensorType);
}

@SuppressWarnings({ "rawtypes" })
@@ -44,6 +44,7 @@
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
@@ -248,13 +249,13 @@ protected <T extends Entity> T loadUnitializedEntity(final T entity, final Entit
}

entity.tags().addTags(spec.getTags());
((AbstractEntity)entity).configure(getConfigKeysFromSpecParameters(spec));
((AbstractEntity)entity).configure(MutableMap.copyOf(spec.getFlags()));
addSpecParameters(spec, ((AbstractEntity)entity).getMutableEntityType());

((AbstractEntity)entity).configure(MutableMap.copyOf(spec.getFlags()));
for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) {
entity.config().set((ConfigKey)entry.getKey(), entry.getValue());
}

Entity parent = spec.getParent();
if (parent != null) {
parent = (parent instanceof AbstractEntity) ? ((AbstractEntity)parent).getProxyIfAvailable() : parent;
@@ -268,12 +269,11 @@ protected <T extends Entity> T loadUnitializedEntity(final T entity, final Entit
}
}

private <T extends Entity> List<ConfigKey<?>> getConfigKeysFromSpecParameters(EntitySpec<T> spec) {
List<ConfigKey<?>> configKeys = MutableList.of();
private void addSpecParameters(EntitySpec<?> spec, EntityDynamicType edType) {
for (SpecParameter<?> param : spec.getParameters()) {
configKeys.add(param.getType());
edType.addConfigKey(param.getConfigKey());
if (param.getSensor()!=null) edType.addSensor(param.getSensor());
}
return configKeys;
}

/**
@@ -19,11 +19,11 @@
package org.apache.brooklyn.core.sensor;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey.Builder;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
@@ -45,6 +45,7 @@
*/
public abstract class AttributeSensorAndConfigKey<ConfigType,SensorType> extends BasicAttributeSensor<SensorType>
implements ConfigKey.HasConfigKey<ConfigType> {

private static final long serialVersionUID = -3103809215973264600L;
private static final Logger log = LoggerFactory.getLogger(AttributeSensorAndConfigKey.class);

@@ -87,6 +88,10 @@ public AttributeSensorAndConfigKey(AttributeSensorAndConfigKey<ConfigType,Sensor
configKey = ConfigKeys.newConfigKeyWithDefault(orig.configKey,
TypeCoercions.coerce(defaultValue, orig.configKey.getTypeToken()));
}
public AttributeSensorAndConfigKey(Builder<ConfigType> configKeyBuilder, TypeToken<SensorType> sensorType) {
super(sensorType, configKeyBuilder.getName(), configKeyBuilder.getDescription());
configKey = new BasicConfigKey<ConfigType>(configKeyBuilder);
}

public ConfigKey<ConfigType> getConfigKey() { return configKey; }

@@ -106,7 +111,7 @@ public SensorType getAsSensorValue(Entity e) {
SensorType sensorValue = e.getAttribute(this);
if (sensorValue!=null) return sensorValue;

ConfigType v = ((EntityLocal)e).getConfig(this);
ConfigType v = e.config().get(this);
try {
return convertConfigToSensor(v, e);
} catch (Throwable t) {
@@ -29,6 +29,7 @@
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.internal.BrooklynInitialization;
import org.apache.brooklyn.core.location.Locations;
@@ -40,6 +41,7 @@
import com.google.common.base.Optional;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.reflect.TypeToken;

/**
* A {@link Sensor} describing a port on a system,
@@ -68,6 +70,10 @@ public PortAttributeSensorAndConfigKey(String name, String description, Object d
public PortAttributeSensorAndConfigKey(PortAttributeSensorAndConfigKey orig, Object defaultValue) {
super(orig, TypeCoercions.coerce(defaultValue, PortRange.class));
}
public PortAttributeSensorAndConfigKey(BasicConfigKey.Builder<PortRange> builder) {
super(builder, TypeToken.of(Integer.class));
}

@Override
protected Integer convertConfigToSensor(PortRange value, Entity entity) {
if (value==null) return null;
@@ -234,7 +234,7 @@ public static <T> List<FlagConfigKeyAndValueRecord> findAllFlagsAndConfigKeys(T
public static List<FlagConfigKeyAndValueRecord> findAllParameterConfigKeys(List<SpecParameter<?>> parameters, ConfigBag input) {
List<FlagConfigKeyAndValueRecord> output = new ArrayList<FlagUtils.FlagConfigKeyAndValueRecord>();
for (SpecParameter<?> param : parameters) {
FlagConfigKeyAndValueRecord record = getFlagConfigKeyRecord(null, param.getType(), input);
FlagConfigKeyAndValueRecord record = getFlagConfigKeyRecord(null, param.getConfigKey(), input);
if (record.isValuePresent())
output.add(record);
}
@@ -103,7 +103,7 @@ public void testConfigInImplVisible() {
private void assertInput(SpecParameter<?> input, String label, boolean pinned, ConfigKey<?> type) {
assertEquals(input.getLabel(), label);
assertEquals(input.isPinned(), pinned);
assertEquals(input.getType(), type);
assertEquals(input.getConfigKey(), type);
}

}

0 comments on commit 9141c99

Please sign in to comment.