Skip to content
Permalink
Browse files
JCLOUDS-418 Add schedule Scaling Policy type
  • Loading branch information
zack-shoylev committed Jan 7, 2014
1 parent 3c8fa33 commit 2e4f67c7fb788e52c17a560131ae51f47c0c06c5
Showing 13 changed files with 380 additions and 28 deletions.
@@ -21,14 +21,17 @@

import java.beans.ConstructorProperties;
import java.util.EnumSet;
import java.util.Map;


import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

/**
* Autoscale ScalingPolicy. This class is used for requests.
* Auto Scale ScalingPolicy. This class is used for requests.
*
* @see GroupApi#create(GroupConfiguration, LaunchConfiguration, java.util.List)
* @see Group#getScalingPolicies()
@@ -41,18 +44,19 @@ public class ScalingPolicy implements Comparable<ScalingPolicy>{
private final int cooldown;
private final String target;
private final ScalingPolicyTargetType targetType;
private final Map<String, String> args;

@ConstructorProperties({
"name", "type", "cooldown", "target", "targetType"
"name", "type", "cooldown", "target", "targetType", "args"
})
protected ScalingPolicy(String name, ScalingPolicyType type, int cooldown, String target, ScalingPolicyTargetType targetType) {

protected ScalingPolicy(String name, ScalingPolicyType type, int cooldown, String target, ScalingPolicyTargetType targetType, Map<String, String> args) {
this.name = checkNotNull(name, "name required");
this.type = type;
checkArgument(cooldown >= 0, "cooldown should be non-negative");
this.cooldown = cooldown;
this.target = target;
this.targetType = targetType;
this.args = args;
}

/**
@@ -98,9 +102,46 @@ public ScalingPolicyTargetType getTargetType() {
return this.targetType;
}

/**
* @return The scheduling string, if any.
* @see ScalingPolicy.Builder#atSchedule(String)
* @see ScalingPolicy.Builder#cronSchedule(String)
*/
protected Map<String, String> getSchedulingArgs() {
return this.args;
}

/**
* @return The scheduling string, if any.
* @see ScalingPolicy.Builder#atSchedule(String)
* @see ScalingPolicy.Builder#cronSchedule(String)
*/
public String getSchedulingString() {
if (this.args != null) {
for (Map.Entry<String, String> entry : this.args.entrySet()) {
return entry.getValue();
}
}
return null;
}

/**
* @return The type of the schedule this policy uses.
*/
public ScalingPolicyScheduleType getSchedulingType() {
if(this.args != null) {
for (ScalingPolicyScheduleType type : ScalingPolicyScheduleType.values()) {
if (this.args.get(type.toString()) != null) {
return type;
}
}
}
return null;
}

@Override
public int hashCode() {
return Objects.hashCode(name, type, cooldown, target, targetType);
return Objects.hashCode(name, type, cooldown, target, targetType, args);
}

@Override
@@ -112,7 +153,8 @@ public boolean equals(Object obj) {
Objects.equal(this.type, that.type) &&
Objects.equal(this.cooldown, that.cooldown) &&
Objects.equal(this.target, that.target) &&
Objects.equal(this.targetType, that.targetType);
Objects.equal(this.targetType, that.targetType) &&
Objects.equal(this.args, that.args);
}

protected ToStringHelper string() {
@@ -121,7 +163,8 @@ protected ToStringHelper string() {
.add("type", type)
.add("cooldown", cooldown)
.add("target", target)
.add("targetType", "targetType");
.add("targetType", targetType)
.add("args", args);
}

@Override
@@ -143,6 +186,7 @@ public static class Builder {
protected int cooldown;
protected String target;
protected ScalingPolicyTargetType targetType;
protected Map<String, String> args;

/**
* @param name The name of this ScalingPolicy.
@@ -155,7 +199,7 @@ public Builder name(String name) {
}

/**
* @param name The type for this ScalingPolicy.
* @param type The type for this ScalingPolicy.
* @return The builder object.
* @see ScalingPolicyType
* @see ScalingPolicy#getType()
@@ -186,7 +230,7 @@ public Builder target(String target) {
}

/**
* @param target type The target type of this ScalingPolicy.
* @param targetType The target type of this ScalingPolicy.
* @return The builder object.
* @see ScalingPolicyTargetType
* @see ScalingPolicy#getTargetType()
@@ -196,20 +240,62 @@ public Builder targetType(ScalingPolicyTargetType targetType) {
return this;
}

/**
* @param cron This parameter specifies the recurring time when the policy will be executed as a cron entry.
* For example, if this is parameter is set to "1 0 * * *",
* the policy will be executed at one minute past midnight (00:01)
* every day of the month, and every day of the week.
* You can either provide "cron" or "at" for a given policy, but not both.
* @return The builder object.
* @see ScalingPolicyTargetType
* @see ScalingPolicy#getTargetType()
* @see <a href="http://en.wikipedia.org/wiki/Cron">Cron</a>
*/
public Builder cronSchedule(String cron) {
this.type = ScalingPolicyType.SCHEDULE;
this.args = ImmutableMap.of("cron", cron);
return this;
}

/**
* @param at This parameter specifies the time at which this policy will be executed.
* This property is mutually exclusive with the "cron" parameter.
* You can either provide "cron" or "at" for a given policy, but not both.
* Example date string: "2013-12-05T03:12:00Z"
* @return The builder object.
* @see ScalingPolicyTargetType
* @see ScalingPolicy#getTargetType()
*/
public Builder atSchedule(String at) {
this.type = ScalingPolicyType.SCHEDULE;
this.args = ImmutableMap.of("at", at);
return this;
}

private Builder scheduleArgs(Map<String, String> args) {
this.args = args;
return this;
}

/**
* @return A new ScalingPolicy object.
*/
public ScalingPolicy build() {
return new ScalingPolicy(name, type, cooldown, target, targetType);
return new ScalingPolicy(name, type, cooldown, target, targetType, args);
}

/**
* @param in The target scaling policy
* @return The scaling policy builder
*/
public Builder fromScalingPolicy(ScalingPolicy in) {
return this
.name(in.getName())
.type(in.getType())
.cooldown(in.getCooldown())
.target(in.getTarget())
.targetType(in.getTargetType());
.targetType(in.getTargetType())
.scheduleArgs(in.getSchedulingArgs());
}
}

@@ -222,7 +308,8 @@ public int compareTo(ScalingPolicy that) {
* Enumerates different types of scaling policies
*/
public static enum ScalingPolicyType {
WEBHOOK("webhook");
WEBHOOK("webhook"),
SCHEDULE("schedule");

private final String name;

@@ -271,4 +358,39 @@ public static Optional<ScalingPolicyTargetType> getByValue(String value){
return Optional.absent();
}
}

/**
* Enumerates different types of targets a policy might have
*/
public static enum ScalingPolicyScheduleType {
/**
* Example: "1 0 * * *"
* @see ScalingPolicy.Builder#cronSchedule(String)
*/
AT("at"),
/**
* Example date string: "2013-12-05T03:12:00Z"
* @see ScalingPolicy.Builder#atSchedule(String)
*/
CRON("cron");

private final String name;

private ScalingPolicyScheduleType(String name) {
this.name = name;
}

public String toString() {
return name;
}

public static Optional<ScalingPolicyTargetType> getByValue(String value){
for (final ScalingPolicyTargetType element : EnumSet.allOf(ScalingPolicyTargetType.class)) {
if (element.toString().equals(value)) {
return Optional.of(element);
}
}
return Optional.absent();
}
}
}
@@ -20,6 +20,7 @@

import java.beans.ConstructorProperties;
import java.util.List;
import java.util.Map;

import org.jclouds.openstack.v2_0.domain.Link;

@@ -38,10 +39,10 @@ public class ScalingPolicyResponse extends ScalingPolicy{
private final String id;

@ConstructorProperties({
"name", "type", "cooldown", "target", "targetType", "links", "id"
"name", "type", "cooldown", "target", "targetType", "args", "links", "id"
})
public ScalingPolicyResponse(String name, ScalingPolicyType type, int cooldown, String target, ScalingPolicyTargetType targetType, List<Link> links, String id) {
super(name, type, cooldown, target, targetType);
public ScalingPolicyResponse(String name, ScalingPolicyType type, int cooldown, String target, ScalingPolicyTargetType targetType, Map<String, String> args, List<Link> links, String id) {
super(name, type, cooldown, target, targetType, args);
this.id = checkNotNull(id, "id required");
this.links = ImmutableList.copyOf(checkNotNull(links, "links required"));
}
@@ -132,6 +132,7 @@ public Group apply(HttpResponse from) {
((Double)scalingPolicyMap.get("cooldown")).intValue(),
DoubleMath.isMathematicalInteger(d) ? Integer.toString(d.intValue()) : Double.toString(d),
targetType,
(Map<String, String>) scalingPolicyMap.get("args"),
ImmutableList.copyOf(links.build()),
(String) scalingPolicyMap.get("id")
);
@@ -84,6 +84,7 @@ public FluentIterable<ScalingPolicyResponse> apply(HttpResponse from) {
((Double)scalingPolicyMap.get("cooldown")).intValue(),
DoubleMath.isMathematicalInteger(d) ? Integer.toString(d.intValue()) : Double.toString(d),
targetType,
(Map<String, String>) scalingPolicyMap.get("args"),
ImmutableList.copyOf(links.build()),
(String) scalingPolicyMap.get("id")
);
@@ -81,6 +81,7 @@ public ScalingPolicyResponse apply(HttpResponse from) {
((Double)scalingPolicyMap.get("cooldown")).intValue(),
DoubleMath.isMathematicalInteger(d) ? Integer.toString(d.intValue()) : Double.toString(d),
targetType,
(Map<String, String>) scalingPolicyMap.get("args"),
ImmutableList.copyOf(links.build()),
(String) scalingPolicyMap.get("id")
);
@@ -28,6 +28,8 @@
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;

import static org.jclouds.rackspace.autoscale.v1.domain.ScalingPolicy.ScalingPolicyType;

/**
* @author Zack Shoylev
*
@@ -75,7 +77,7 @@ public static ImmutableList<Map<String, Object>> buildScalingPoliciesRequestList
}
return scalingPoliciesListBuilder.build();
}

public static ImmutableMap<String, Object> buildScalingPolicyMap(ScalingPolicy scalingPolicy) {
ImmutableMap.Builder<String, Object> scalingPolicyMapBuilder = ImmutableMap.builder();
scalingPolicyMapBuilder.put("cooldown", scalingPolicy.getCooldown());
@@ -97,6 +99,12 @@ public static ImmutableMap<String, Object> buildScalingPolicyMap(ScalingPolicy s
scalingPolicyMapBuilder.put(scalingPolicy.getTargetType().toString(), targetString);
}

if (scalingPolicy.getSchedulingType() != null
&& scalingPolicy.getType().equals(ScalingPolicyType.SCHEDULE)) {
// Have to use getters to rebuild map
scalingPolicyMapBuilder.put("args", ImmutableMap.of(scalingPolicy.getSchedulingType().toString(),scalingPolicy.getSchedulingString()));
}

return scalingPolicyMapBuilder.build();
}
}
@@ -32,6 +32,7 @@
import org.jclouds.rackspace.autoscale.v1.domain.LoadBalancer;
import org.jclouds.rackspace.autoscale.v1.domain.Personality;
import org.jclouds.rackspace.autoscale.v1.domain.ScalingPolicy;
import org.jclouds.rackspace.autoscale.v1.domain.ScalingPolicy.ScalingPolicyScheduleType;
import org.jclouds.rackspace.autoscale.v1.domain.ScalingPolicy.ScalingPolicyTargetType;
import org.jclouds.rackspace.autoscale.v1.domain.ScalingPolicy.ScalingPolicyType;
import org.jclouds.rackspace.autoscale.v1.domain.ScalingPolicyResponse;
@@ -169,6 +170,60 @@ public void testCreatePolicy() {
}
}

@Test
public void testCreateScheduleCronPolicy() {
for (String zone : api.getConfiguredZones()) {

PolicyApi policyApi = api.getPolicyApiForZoneAndGroup(zone, created.get(zone).get(0).getId());

List<ScalingPolicy> scalingPolicies = Lists.newArrayList();

ScalingPolicy scalingPolicy = ScalingPolicy.builder()
.cooldown(3)
.type(ScalingPolicyType.SCHEDULE)
.name("scale up by one server")
.targetType(ScalingPolicyTargetType.INCREMENTAL)
.target("1")
.cronSchedule("23 * * * *")
.build();
scalingPolicies.add(scalingPolicy);

FluentIterable<ScalingPolicyResponse> scalingPolicyResponse = policyApi.create(scalingPolicies);
assertNotNull(scalingPolicyResponse.iterator().next().getId());
assertEquals(scalingPolicyResponse.iterator().next().getCooldown(), 3);
assertEquals(scalingPolicyResponse.iterator().next().getTarget(), "1");
assertEquals(scalingPolicyResponse.iterator().next().getSchedulingType(), ScalingPolicyScheduleType.CRON);
assertEquals(scalingPolicyResponse.iterator().next().getSchedulingString(), "23 * * * *");
}
}

@Test
public void testCreateScheduleAtPolicy() {
for (String zone : api.getConfiguredZones()) {

PolicyApi policyApi = api.getPolicyApiForZoneAndGroup(zone, created.get(zone).get(0).getId());

List<ScalingPolicy> scalingPolicies = Lists.newArrayList();

ScalingPolicy scalingPolicy = ScalingPolicy.builder()
.cooldown(3)
.type(ScalingPolicyType.SCHEDULE)
.name("scale up by one server")
.targetType(ScalingPolicyTargetType.INCREMENTAL)
.target("1")
.atSchedule("2020-12-05T03:12:00Z")
.build();
scalingPolicies.add(scalingPolicy);

FluentIterable<ScalingPolicyResponse> scalingPolicyResponse = policyApi.create(scalingPolicies);
assertNotNull(scalingPolicyResponse.iterator().next().getId());
assertEquals(scalingPolicyResponse.iterator().next().getCooldown(), 3);
assertEquals(scalingPolicyResponse.iterator().next().getTarget(), "1");
assertEquals(scalingPolicyResponse.iterator().next().getSchedulingType(), ScalingPolicyScheduleType.AT);
assertEquals(scalingPolicyResponse.iterator().next().getSchedulingString(), "2020-12-05T03:12:00Z");
}
}

@Test
public void testListPolicy() {
for (String zone : api.getConfiguredZones()) {

0 comments on commit 2e4f67c

Please sign in to comment.