You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2016/02/16 18:40:58 UTC
[08/11] brooklyn-server git commit: Add StopAfterDurationPolicy
Add StopAfterDurationPolicy
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/e162d209
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/e162d209
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/e162d209
Branch: refs/heads/master
Commit: e162d2091c7ad744af33e59a0b5a3441a784a92b
Parents: d2cdb41
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Feb 11 12:28:37 2016 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Tue Feb 16 16:55:46 2016 +0000
----------------------------------------------------------------------
.../core/sensor/DurationSinceSensor.java | 18 ++-
.../policy/action/StopAfterDurationPolicy.java | 135 +++++++++++++++++++
.../action/StopAfterDurationPolicyTest.java | 46 +++++++
.../org/apache/brooklyn/util/time/Duration.java | 6 +-
4 files changed, 200 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e162d209/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
index 9dc89a5..4be57d8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
@@ -41,13 +41,15 @@ public class DurationSinceSensor extends AddSensor<Duration> {
public static final ConfigKey<Supplier<Long>> EPOCH_SUPPLIER = ConfigKeys.builder(new TypeToken<Supplier<Long>>() {})
.name("duration.since.epochsupplier")
- .description("The source of time from which durations are measured. Defaults to System.currentTimeMillis.")
+ .description("The source of time from which durations are measured. Defaults to System.currentTimeMillis when " +
+ "if no supplier is given or the configured supplier returns null.")
.defaultValue(CURRENT_TIME_SUPPLIER)
.build();
public static final ConfigKey<Supplier<Long>> TIME_SUPPLIER = ConfigKeys.builder(new TypeToken<Supplier<Long>>() {})
.name("duration.since.timesupplier")
- .description("The source of the current time. Defaults to System.currentTimeMillis.")
+ .description("The source of the current time. Defaults to System.currentTimeMillis if unconfigured or the " +
+ "supplier returns null.")
.defaultValue(CURRENT_TIME_SUPPLIER)
.build();
@@ -67,7 +69,11 @@ public class DurationSinceSensor extends AddSensor<Duration> {
super.apply(entity);
if (entity.sensors().get(epochSensor) == null) {
- entity.sensors().set(epochSensor, epochSupplier.get());
+ Long epoch = epochSupplier.get();
+ if (epoch == null) {
+ epoch = CURRENT_TIME_SUPPLIER.get();
+ }
+ entity.sensors().set(epochSensor, epoch);
}
FunctionFeed feed = FunctionFeed.builder()
@@ -98,7 +104,11 @@ public class DurationSinceSensor extends AddSensor<Duration> {
Long referencePoint = entity.sensors().get(epochSensor);
// Defensive check. Someone has done something silly if this is false.
if (referencePoint != null) {
- return Duration.millis(timeSupplier.get() - referencePoint);
+ Long time = timeSupplier.get();
+ if (time == null) {
+ time = CURRENT_TIME_SUPPLIER.get();
+ }
+ return Duration.millis(time - referencePoint);
} else {
throw new IllegalStateException("Cannot calculate duration since sensor: " +
entity + " missing required value for " + epochSensor);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e162d209/policy/src/main/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicy.java b/policy/src/main/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicy.java
new file mode 100644
index 0000000..3b5eefa
--- /dev/null
+++ b/policy/src/main/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicy.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.policy.action;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.DurationSinceSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class StopAfterDurationPolicy extends AbstractPolicy {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StopAfterDurationPolicy.class);
+
+ public static final ConfigKey<Duration> LIFETIME = ConfigKeys.builder(Duration.class)
+ .name("lifetime")
+ .description("The duration the entity is allowed to remain running")
+ .constraint(Predicates.notNull())
+ .build();
+
+ public static final ConfigKey<Lifecycle> STATE = ConfigKeys.builder(Lifecycle.class)
+ .name("state")
+ .description("The state the entity must enter before the stop-timer is started")
+ .defaultValue(Lifecycle.RUNNING)
+ .constraint(Predicates.notNull())
+ .build();
+
+ public static final ConfigKey<Duration> POLL_PERIOD = ConfigKeys.builder(Duration.class)
+ .name("pollPeriod")
+ .description("Period in which duration-since sensor should be updated")
+ .defaultValue(Duration.THIRTY_SECONDS)
+ .constraint(Predicates.notNull())
+ .build();
+
+ public static final ConfigKey<Boolean> HAS_STARTED_TIMER = ConfigKeys.builder(Boolean.class)
+ .name("timer-started")
+ .description("For internal use only")
+ .defaultValue(false)
+ .build();
+
+ public static final ConfigKey<Boolean> FIRED_STOP = ConfigKeys.builder(Boolean.class)
+ .name("fired-stop")
+ .description("For internal use only")
+ .defaultValue(false)
+ .build();
+
+ private final Object eventLock = new Object[0];
+
+ public void setEntity(final EntityLocal entity) {
+ super.setEntity(entity);
+ entity.subscriptions().subscribe(entity, Attributes.SERVICE_STATE_ACTUAL, new LifecycleListener());
+ entity.subscriptions().subscribe(entity, Sensors.newSensor(Duration.class, getSensorName()), new TimeIsUpListener());
+ }
+
+ @Override
+ protected <T> void doReconfigureConfig(ConfigKey<T> key, T val) {
+ Set<ConfigKey<?>> accepted = ImmutableSet.<ConfigKey<?>>of(
+ HAS_STARTED_TIMER,
+ FIRED_STOP,
+ LIFETIME);
+ if (!accepted.contains(key)) {
+ super.doReconfigureConfig(key, val);
+ }
+ }
+
+ private String getSensorName() {
+ return "duration.since.first-" + config().get(STATE).name().toLowerCase();
+ }
+
+ private class LifecycleListener implements SensorEventListener<Lifecycle> {
+ @Override
+ public void onEvent(SensorEvent<Lifecycle> event) {
+ synchronized (eventLock) {
+ if (!config().get(HAS_STARTED_TIMER) && config().get(STATE).equals(event.getValue())) {
+ DurationSinceSensor sensor = new DurationSinceSensor(ConfigBag.newInstance(ImmutableMap.of(
+ DurationSinceSensor.SENSOR_NAME, getSensorName(),
+ DurationSinceSensor.SENSOR_PERIOD, config().get(POLL_PERIOD),
+ DurationSinceSensor.SENSOR_TYPE, Duration.class.getName())));
+ sensor.apply(entity);
+ config().set(HAS_STARTED_TIMER, true);
+ }
+ }
+ }
+ }
+
+ private class TimeIsUpListener implements SensorEventListener<Duration> {
+ @Override
+ public void onEvent(SensorEvent<Duration> event) {
+ synchronized (eventLock) {
+ if (!config().get(FIRED_STOP)) {
+ if (config().get(LIFETIME).subtract(event.getValue()).isNegative()) {
+ LOG.debug("Stopping {}: lifetime ({}) has expired", entity, config().get(LIFETIME));
+ entity.invoke(Startable.STOP, ImmutableMap.<String, Object>of());
+ config().set(FIRED_STOP, true);
+ }
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e162d209/policy/src/test/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicyTest.java b/policy/src/test/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicyTest.java
new file mode 100644
index 0000000..927d5aa
--- /dev/null
+++ b/policy/src/test/java/org/apache/brooklyn/policy/action/StopAfterDurationPolicyTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.policy.action;
+
+import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEqualsEventually;
+
+import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class StopAfterDurationPolicyTest extends BrooklynAppUnitTestSupport {
+
+ @Test
+ public void testAppStoppedWhenDurationExpires() {
+ PolicySpec<StopAfterDurationPolicy> policy = PolicySpec.create(StopAfterDurationPolicy.class)
+ .configure(StopAfterDurationPolicy.LIFETIME, Duration.ONE_MILLISECOND)
+ .configure(StopAfterDurationPolicy.POLL_PERIOD, Duration.ONE_MILLISECOND);
+ app.policies().add(policy);
+ app.start(ImmutableList.of(app.newSimulatedLocation()));
+ assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+ assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e162d209/utils/common/src/main/java/org/apache/brooklyn/util/time/Duration.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/time/Duration.java b/utils/common/src/main/java/org/apache/brooklyn/util/time/Duration.java
index e8dee7d..a5042cf 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/time/Duration.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/time/Duration.java
@@ -275,7 +275,11 @@ public class Duration implements Comparable<Duration>, Serializable {
}
public boolean isPositive() {
- return nanos()>0;
+ return nanos() > 0;
+ }
+
+ public boolean isNegative() {
+ return nanos() < 0;
}
public boolean isLongerThan(Duration x) {