/*
* 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.jclouds.cloudwatch.features;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.jclouds.util.Predicates2.retry;
import java.util.Date;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.jclouds.cloudwatch.domain.Alarm;
import org.jclouds.cloudwatch.domain.AlarmHistoryItem;
import org.jclouds.cloudwatch.domain.ComparisonOperator;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.MetricDatum;
import org.jclouds.cloudwatch.domain.StatisticValues;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchApiLiveTest;
import org.jclouds.cloudwatch.options.ListAlarmHistoryOptions;
import org.jclouds.cloudwatch.options.ListAlarmsForMetric;
import org.jclouds.cloudwatch.options.ListAlarmsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.cloudwatch.options.SaveAlarmOptions;
import org.jclouds.collect.IterableWithMarker;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@Test(groups = "live", testName = "AlarmApiLiveTest")
public class AlarmApiLiveTest extends BaseCloudWatchApiLiveTest {
private String alarmName = "TestAlarmName" + System.currentTimeMillis();
private String metricName = "TestMetricForAlarms";
private String namespace = "JCLOUDS/Test";
@BeforeClass
protected void beforeClass() throws Exception {
IterableWithMarker<Metric> metrics = metricApi().list(new ListMetricsOptions().metricName(metricName));
if (Iterables.isEmpty(metrics)) {
metricApi().putMetricsInNamespace(ImmutableSet.of(
MetricDatum.builder()
.metricName(metricName)
.statisticValues(StatisticValues.builder()
.maximum(4.0)
.minimum(1.0)
.sampleCount(4.0)
.sum(10.0)
.build())
.dimension(new Dimension("BaseMetricName", metricName))
.dimension(new Dimension("TestDimension2", "TEST2"))
.unit(Unit.COUNT)
.timestamp(new Date())
.build()
), namespace);
ListMetricsOptions lmo = ListMetricsOptions.Builder.namespace(namespace)
.metricName(metricName);
boolean success = retry(new Predicate<ListMetricsOptions>() {
public boolean apply(ListMetricsOptions options) {
return Iterables.size(metricApi().list(options)) == 1;
}
}, 5, 1, MINUTES).apply(lmo);
if (!success) {
Assert.fail("Unable to create the test CloudWatch metric within the time (5m) allotted.");
}
}
}
@AfterClass
protected void afterClass() throws Exception {
IterableWithMarker<Alarm> alarms = api().list(new ListAlarmsOptions().alarmName(alarmName)).get(0);
if (!Iterables.isEmpty(alarms)) {
api().delete(ImmutableSet.of(alarmName));
}
}
@Test
protected void testAlarmCRUD() throws Exception {
// Create new alarm
api().save(new SaveAlarmOptions()
.actionsEnabled(true)
.alarmDescription("This is a test alarm for jclouds.")
.alarmName(alarmName)
.comparisonOperator(ComparisonOperator.GREATER_THAN_THRESHOLD)
.evaluationPeriods(5)
.metricName(metricName)
.namespace(namespace)
.period(60)
.statistic(Statistics.SAMPLE_COUNT)
.threshold(1.0));
// Poll alarms until alarm is found
ListAlarmsOptions dmo = new ListAlarmsOptions().alarmName(alarmName);
boolean success = retry(new Predicate<ListAlarmsOptions>() {
public boolean apply(ListAlarmsOptions options) {
return Iterables.size(api().list(options).get(0)) == 1;
}
}, 5, 1, MINUTES).apply(dmo);
if (!success) {
Assert.fail("Unable to create the test CloudWatch alarm within the time (5m) allotted.");
}
// Poll all alarms until alarm is found
success = retry(new Predicate<Void>() {
public boolean apply(Void arg) {
for (IterableWithMarker<Alarm> page : api().list()) {
for (Alarm alarm : page) {
if (alarm.getAlarmName().equals(alarmName)) {
return true;
}
}
}
return false;
}
}, 5, 1, MINUTES).apply(null);
if (!success) {
Assert.fail("Unable to create the test CloudWatch alarm within the time (5m) allotted.");
}
// Poll for alarms for metric until alarm is found
ListAlarmsForMetric dafmo = new ListAlarmsForMetric()
.metricName(metricName)
.namespace(namespace);
success = retry(new Predicate<ListAlarmsForMetric>() {
public boolean apply(ListAlarmsForMetric options) {
for (Alarm alarm : api().listForMetric(options)) {
if (alarm.getAlarmName().equals(alarmName)) {
return true;
}
}
return false;
}
}, 5, 1, MINUTES).apply(dafmo);
if (!success) {
Assert.fail("Unable to create the test CloudWatch alarm history item within the time (5m) allotted.");
}
// Create history item by changing its state
api().setState(alarmName, "Updating the state.", null, Alarm.State.OK);
// Poll for alarm history
ListAlarmHistoryOptions daho = new ListAlarmHistoryOptions().alarmName(alarmName);
success = retry(new Predicate<ListAlarmHistoryOptions>() {
public boolean apply(ListAlarmHistoryOptions options) {
for (IterableWithMarker<AlarmHistoryItem> page : api().listHistory(options)) {
for (AlarmHistoryItem alarmHistoryItem : page) {
if (alarmHistoryItem.getAlarmName().equals(alarmName)) {
JsonObject historyData = new JsonParser().parse(alarmHistoryItem.getHistoryData())
.getAsJsonObject();
if (historyData.has("newState") && historyData.getAsJsonObject("newState").has("stateReason") &&
historyData.getAsJsonObject("newState").get("stateReason").getAsString()
.equals("Updating the state.")) {
return true;
}
}
}
}
return false;
}
}, 5, 1, MINUTES).apply(daho);
if (!success) {
Assert.fail("Unable to create the test CloudWatch alarm history item within the time (5m) allotted.");
}
success = retry(new Predicate<Void>() {
public boolean apply(Void arg) {
for (IterableWithMarker<AlarmHistoryItem> page : api().listHistory()) {
for (AlarmHistoryItem alarmHistoryItem : page) {
if (alarmHistoryItem.getAlarmName().equals(alarmName)) {
JsonObject historyData = new JsonParser().parse(alarmHistoryItem.getHistoryData())
.getAsJsonObject();
if (historyData.has("newState") && historyData.getAsJsonObject("newState").has("stateReason") &&
historyData.getAsJsonObject("newState").get("stateReason").getAsString()
.equals("Updating the state.")) {
return true;
}
}
}
}
return false;
}
}, 5, 1, MINUTES).apply(null);
if (!success) {
Assert.fail("Unable to create the test CloudWatch alarm history item within the time (5m) allotted.");
}
// Disable alarm actions
api().disable(ImmutableSet.of(alarmName));
// Validate
success = retry(new Predicate<ListAlarmsOptions>() {
public boolean apply(ListAlarmsOptions options) {
Iterable<Alarm> alarms = api().list(options).get(0);
return Iterables.size(alarms) == 1 && !alarms.iterator().next().areActionsEnabled();
}
}, 5, 1, MINUTES).apply(dmo);
if (!success) {
Assert.fail("Unable to validate the test CloudWatch alarm disablement within the time (5m) allotted.");
}
// Enable alarm actions
api().enable(ImmutableSet.of(alarmName));
// Validate
success = retry(new Predicate<ListAlarmsOptions>() {
public boolean apply(ListAlarmsOptions options) {
IterableWithMarker<Alarm> alarms = api().list(options).get(0);
return Iterables.size(alarms) == 1 && alarms.iterator().next().areActionsEnabled();
}
}, 5, 1, MINUTES).apply(dmo);
if (!success) {
Assert.fail("Unable to validate the test CloudWatch alarm enablement within the time (5m) allotted.");
}
// Delete the alarm
api().delete(ImmutableSet.of(alarmName));
success = retry(new Predicate<ListAlarmsOptions>() {
public boolean apply(ListAlarmsOptions options) {
return Iterables.isEmpty(api().list(options).get(0));
}
}, 5, 1, MINUTES).apply(dmo);
if (!success) {
Assert.fail("Unable to delete the test CloudWatch alarm within the time (5m) allotted.");
}
}
protected AlarmApi api() {
return api.getAlarmApiForRegion(null);
}
protected MetricApi metricApi() {
return api.getMetricApiForRegion(null);
}
}