This commit is contained in:
Todd Walk 2013-10-01 15:31:54 -06:00
parent edd5a2dd0d
commit 21f842bf10
11 changed files with 60 additions and 54 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
*.swp
*.iml
.DS_Store
.cache
.classpath
.idea

View File

@ -16,7 +16,7 @@
<versionNumber>1.0.0</versionNumber>
<computedVersion>${versionNumber}-SNAPSHOT</computedVersion>
<ps.common.version>1.0.0.280</ps.common.version>
<maas.commons.version>1.0.0.108</maas.commons.version>
<maas.commons.version>1.0.0.134</maas.commons.version>
<dropwizard.version>0.6.1</dropwizard.version>
<skipITs>true</skipITs>

View File

@ -13,7 +13,6 @@ import com.hpcloud.maas.common.model.alarm.AggregateFunction;
import com.hpcloud.maas.common.model.alarm.AlarmOperator;
import com.hpcloud.maas.common.model.alarm.AlarmState;
import com.hpcloud.maas.common.model.alarm.AlarmSubExpression;
import com.hpcloud.maas.common.model.metric.CollectdMetrics;
import com.hpcloud.maas.common.model.metric.MetricDefinition;
import com.hpcloud.maas.domain.model.Alarm;
import com.hpcloud.maas.domain.model.SubAlarm;
@ -50,10 +49,9 @@ public class AlarmDAOImpl implements AlarmDAO {
String subAlarmId = (String) row.get("id");
Map<String, String> dimensions = findDimensionsById(handle, subAlarmId);
AggregateFunction function = AggregateFunction.valueOf((String) row.get("function"));
MetricDefinition metricDef = new MetricDefinition((String) row.get("namespace"),
(String) row.get("metric_type"), (String) row.get("metric_subject"), dimensions);
MetricDefinition metricDef = new MetricDefinition((String) row.get("namespace"), dimensions);
// TODO remove later when collectd supports all dimensions
CollectdMetrics.removeUnsupportedDimensions(metricDef);
// CollectdMetrics.removeUnsupportedDimensions(metricDef);
AlarmOperator operator = AlarmOperator.valueOf((String) row.get("operator"));
AlarmSubExpression subExpression = new AlarmSubExpression(function, metricDef, operator,
(Double) row.get("threshold"), (Integer) row.get("period"), (Integer) row.get("periods"));

View File

@ -20,7 +20,7 @@ import com.hpcloud.maas.domain.service.MetricDefinitionDAO;
* @author Jonathan Halterman
*/
public class MetricDefinitionDAOImpl implements MetricDefinitionDAO {
private static final String METRIC_DEF_SQL = "select sa.namespace, sa.metric_type, sa.metric_subject, sad.dimensions from sub_alarm as sa "
private static final String METRIC_DEF_SQL = "select sa.namespace, sad.dimensions from sub_alarm as sa "
+ "left join (select sub_alarm_id, group_concat(dimension_name, '=', value) as dimensions from sub_alarm_dimension group by sub_alarm_id) as sad on sa.id = sad.sub_alarm_id";
private final DBI db;
@ -40,8 +40,6 @@ public class MetricDefinitionDAOImpl implements MetricDefinitionDAO {
List<MetricDefinition> metricDefs = new ArrayList<MetricDefinition>(rows.size());
for (Map<String, Object> row : rows) {
String namespace = (String) row.get("namespace");
String type = (String) row.get("metric_type");
String subject = (String) row.get("metric_subject");
String dimensionSet = (String) row.get("dimensions");
Map<String, String> dimensions = null;
@ -57,7 +55,7 @@ public class MetricDefinitionDAOImpl implements MetricDefinitionDAO {
}
}
metricDefs.add(new MetricDefinition(namespace, type, subject, dimensions));
metricDefs.add(new MetricDefinition(namespace, dimensions));
}
return metricDefs;

View File

@ -31,10 +31,10 @@ public class SubAlarmDAOImpl implements SubAlarmDAO {
*/
private static final String FIND_BY_METRIC_DEF_SQL = "select sa.* from sub_alarm sa, sub_alarm_dimension d "
+ "join (%s) v on d.dimension_name = v.dimension_name and d.value = v.value "
+ "where sa.id = d.sub_alarm_id and sa.namespace = :namespace and sa.metric_type = :metricType and sa.metric_subject %s "
+ "where sa.id = d.sub_alarm_id and sa.namespace = :namespace "
+ "group by d.sub_alarm_id having count(d.sub_alarm_id) = %s";
private static final String FIND_BY_METRIC_DEF_NO_DIMS_SQL = "select * from sub_alarm sa where sa.namespace = :namespace "
+ "and sa.metric_type = :metricType and sa.metric_subject %s and (select count(*) from sub_alarm_dimension where sub_alarm_id = sa.id) = 0";
+ "and (select count(*) from sub_alarm_dimension where sub_alarm_id = sa.id) = 0";
private final DBI db;
@ -49,21 +49,17 @@ public class SubAlarmDAOImpl implements SubAlarmDAO {
try {
String sql = null;
String subjectSql = metricDefinition.subject == null ? "is null" : "= :metricSubject";
if (metricDefinition.dimensions == null || metricDefinition.dimensions.isEmpty())
sql = String.format(FIND_BY_METRIC_DEF_NO_DIMS_SQL, subjectSql);
sql = FIND_BY_METRIC_DEF_NO_DIMS_SQL;
else {
String unionAllStatement = SqlStatements.unionAllStatementFor(metricDefinition.dimensions,
"dimension_name", "value");
sql = String.format(FIND_BY_METRIC_DEF_SQL, unionAllStatement, subjectSql,
sql = String.format(FIND_BY_METRIC_DEF_SQL, unionAllStatement,
metricDefinition.dimensions.size());
}
Query<Map<String, Object>> query = h.createQuery(sql)
.bind("namespace", metricDefinition.namespace)
.bind("metricType", metricDefinition.type);
if (metricDefinition.subject != null)
query.bind("metricSubject", metricDefinition.subject);
Query<Map<String, Object>> query = h.createQuery(sql).bind("namespace",
metricDefinition.namespace);
List<Map<String, Object>> rows = query.list();
List<SubAlarm> subAlarms = new ArrayList<SubAlarm>(rows.size());
@ -75,7 +71,7 @@ public class SubAlarmDAOImpl implements SubAlarmDAO {
operator, (Double) row.get("threshold"), (Integer) row.get("period"),
(Integer) row.get("periods"));
SubAlarm subAlarm = new SubAlarm(subAlarmId, (String) row.get("alarm_id"), subExpression);
subAlarms.add(subAlarm);
}

View File

@ -33,7 +33,7 @@ public class CollectdMetricDeserializer implements TupleDeserializer, Serializab
List<List<?>> results = new ArrayList<List<?>>(metrics.size());
for (Metric metric : metrics) {
// TODO remove in the future
CollectdMetrics.removeUnsupportedDimensions(metric.definition);
// CollectdMetrics.removeUnsupportedDimensions(metric.definition);
results.add(Arrays.asList(metric.definition, metric));
}
return results;

View File

@ -19,7 +19,7 @@ import com.hpcloud.maas.common.model.alarm.AlarmState;
public class AlarmTest {
public void shouldBeUndeterminedIfAnySubAlarmIsUndetermined() {
AlarmExpression expr = new AlarmExpression(
"avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 AND avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3");
"avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 AND avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3");
SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0),
AlarmState.UNDETERMINED);
SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1), AlarmState.ALARM);
@ -32,7 +32,7 @@ public class AlarmTest {
public void shouldEvaluateExpressionWithBooleanAnd() {
AlarmExpression expr = new AlarmExpression(
"avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 AND avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3");
"avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 AND avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3");
SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0));
SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1));
@ -66,7 +66,7 @@ public class AlarmTest {
public void shouldEvaluateExpressionWithBooleanOr() {
AlarmExpression expr = new AlarmExpression(
"avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 OR avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3");
"avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 OR avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3");
SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0));
SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1));
@ -103,7 +103,7 @@ public class AlarmTest {
public void shouldBuiltStateChangeReason() {
AlarmExpression expr = new AlarmExpression(
"avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 OR avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3");
"avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 OR avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3");
SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0));
SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1));
List<String> expressions = Arrays.asList(subAlarm1.getExpression().toString(),
@ -111,10 +111,10 @@ public class AlarmTest {
assertEquals(
Alarm.buildStateChangeReason(AlarmState.UNDETERMINED, expressions),
"No data was present for the sub-alarms: [avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4.0 times 3]");
"No data was present for the sub-alarms: [avg(hpcs.compute:{device=1, metric_name=cpu, instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:{flavor_id=3, metric_name=mem}, 2) < 4.0 times 3]");
assertEquals(
Alarm.buildStateChangeReason(AlarmState.ALARM, expressions),
"Thresholds were exceeded for the sub-alarms: [avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4.0 times 3]");
"Thresholds were exceeded for the sub-alarms: [avg(hpcs.compute:{device=1, metric_name=cpu, instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:{flavor_id=3, metric_name=mem}, 2) < 4.0 times 3]");
}
}

View File

@ -50,17 +50,18 @@ public class AlarmDAOImplTest {
handle.execute("truncate table alarm_action");
handle.execute("insert into alarm (id, tenant_id, name, expression, state, created_at, updated_at) "
+ "values ('123', 'bob', '90% CPU', 'avg(hpcs.compute:cpu:{flavor_id=777, image_id=888}) > 10', 'UNDETERMINED', NOW(), NOW())");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('111', '123', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())");
+ "values ('123', 'bob', '90% CPU', 'avg(hpcs.compute{flavor_id=777, image_id=888, metric_name=cpu}) > 10', 'UNDETERMINED', NOW(), NOW())");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('111', '123', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm_dimension values ('111', 'flavor_id', '777')");
handle.execute("insert into sub_alarm_dimension values ('111', 'image_id', '888')");
handle.execute("insert into sub_alarm_dimension values ('111', 'metric_name', 'cpu')");
handle.execute("insert into alarm_action values ('123', '29387234')");
handle.execute("insert into alarm_action values ('123', '77778687')");
}
public void shouldFindById() {
String expr = "avg(hpcs.compute:cpu) > 10";
String expr = "avg(hpcs.compute{flavor_id=777, image_id=888, metric_name=cpu}) > 10";
Alarm expected = new Alarm("123", "bob", "90% CPU", AlarmExpression.of(expr),
Arrays.asList(new SubAlarm("111", "123", AlarmSubExpression.of(expr))),
AlarmState.UNDETERMINED);

View File

@ -1,6 +1,7 @@
package com.hpcloud.maas.infrastructure.persistence;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import java.nio.charset.Charset;
import java.util.Arrays;
@ -47,54 +48,61 @@ public class SubAlarmDAOImplTest {
handle.execute("truncate table sub_alarm");
handle.execute("truncate table sub_alarm_dimension");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('111', '123', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('111', '123', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm_dimension values ('111', 'instance_id', '555')");
handle.execute("insert into sub_alarm_dimension values ('111', 'az', '1')");
handle.execute("insert into sub_alarm_dimension values ('111', 'instance_uuid', '555')");
handle.execute("insert into sub_alarm_dimension values ('111', 'metric_name', 'cpu')");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('222', '234', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('222', '234', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm_dimension values ('222', 'instance_id', '666')");
handle.execute("insert into sub_alarm_dimension values ('222', 'az', '1')");
handle.execute("insert into sub_alarm_dimension values ('222', 'instance_uuid', '666')");
handle.execute("insert into sub_alarm_dimension values ('222', 'metric_name', 'cpu')");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('333', '345', 'AVG', 'hpcs.compute', 'disk', 'vda', 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('333', '345', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm_dimension values ('333', 'instance_id', '777')");
handle.execute("insert into sub_alarm_dimension values ('333', 'az', '1')");
handle.execute("insert into sub_alarm_dimension values ('333', 'instance_uuid', '777')");
handle.execute("insert into sub_alarm_dimension values ('333', 'metric_name', 'disk')");
handle.execute("insert into sub_alarm_dimension values ('333', 'device', 'vda')");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('444', '456', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) "
+ "values ('444', '456', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())");
handle.execute("insert into sub_alarm_dimension values ('444', 'metric_name', 'cpu')");
}
public void shouldFind() {
List<SubAlarm> expected = Arrays.asList(new SubAlarm("111", "123",
AlarmSubExpression.of("avg(hpcs.compute:cpu:{instance_id=555,az=1}) > 10"),
AlarmSubExpression.of("avg(hpcs.compute{instance_id=555,az=1,metric_name=cpu}) > 10"),
AlarmState.UNDETERMINED));
List<SubAlarm> subAlarms = dao.find(expected.get(0).getExpression().getMetricDefinition());
assertEquals(subAlarms, expected);
expected = Arrays.asList(new SubAlarm("222", "234",
AlarmSubExpression.of("avg(hpcs.compute:cpu:{instance_id=666,az=1}) > 10"),
AlarmSubExpression.of("avg(hpcs.compute{instance_id=666,az=1,metric_name=cpu}) > 10"),
AlarmState.UNDETERMINED));
subAlarms = dao.find(expected.get(0).getExpression().getMetricDefinition());
assertEquals(subAlarms, expected);
}
public void shouldFindWithSubject() {
List<SubAlarm> expected = Arrays.asList(new SubAlarm("333", "345",
AlarmSubExpression.of("avg(hpcs.compute:disk:vda:{instance_id=777,az=1}) > 10"),
List<SubAlarm> expected = Arrays.asList(new SubAlarm(
"333",
"345",
AlarmSubExpression.of("avg(hpcs.compute{instance_id=777,az=1,metric_name=disk,device=vda}) > 10"),
AlarmState.UNDETERMINED));
List<SubAlarm> subAlarms = dao.find(expected.get(0).getExpression().getMetricDefinition());
assertEquals(subAlarms, expected);
}
public void shouldFindForNullDimensions() {
public void shouldFailFindForNullDimensions() {
List<SubAlarm> expected = Arrays.asList(new SubAlarm("444", "456",
AlarmSubExpression.of("avg(hpcs.compute:cpu) > 10"), AlarmState.UNDETERMINED));
AlarmSubExpression.of("avg(hpcs.compute{metric_name=cpu}) > 10"), AlarmState.UNDETERMINED));
List<SubAlarm> subAlarms = dao.find(new MetricDefinition("hpcs.compute", "cpu", null, null));
assertEquals(subAlarms, expected);
assertNotEquals(subAlarms, expected);
}
}

View File

@ -24,12 +24,18 @@ public class CollectdMetricDeserializerTest {
String metric = "{\"putval\":{\"values\":[36184,51182963],\"dstypes\":[\"derive\",\"derive\"],\"dsnames\":[\"read\",\"write\"],\"time\":1365802618.809,\"interval\":60.000,\"host\":\"instance-000d65f3\",\"plugin\":\"libvirt\",\"plugin_instance\":\"\",\"type\":\"disk_ops\",\"type_instance\":\"vda\"}}";
List<List<?>> metrics = deserializer.deserialize(metric.getBytes());
Metric expected1 = new Metric(new MetricDefinition("hpcs.compute", "disk_read_ops_count", "vda",
ImmutableMap.<String, String>builder().put("instance_id", "878067").build()), 1365802618,
36184);
Metric expected2 = new Metric(new MetricDefinition("hpcs.compute", "disk_write_ops_count", "vda",
ImmutableMap.<String, String>builder().put("instance_id", "878067").build()), 1365802618,
51182963);
Metric expected1 = new Metric(new MetricDefinition("hpcs.compute",
ImmutableMap.<String, String>builder()
.put("device", "vda")
.put("metric_name", "disk_read_ops_count")
.put("instance_id", "878067")
.build()), 1365802618, 36184);
Metric expected2 = new Metric(new MetricDefinition("hpcs.compute",
ImmutableMap.<String, String>builder()
.put("device", "vda")
.put("metric_name", "disk_write_ops_count")
.put("instance_id", "878067")
.build()), 1365802618, 51182963);
assertEquals(
metrics,
Arrays.asList(Arrays.asList(expected1.definition, expected1),

View File

@ -14,8 +14,6 @@ CREATE TABLE `sub_alarm` (
`alarm_id` varchar(36) NOT NULL,
`function` varchar(10) NOT NULL,
`namespace` varchar(100) NOT NULL,
`metric_type` varchar(100) NOT NULL,
`metric_subject` varchar(50) DEFAULT NULL,
`operator` varchar(5) NOT NULL,
`threshold` double NOT NULL,
`period` int(11) NOT NULL,