Allow alarm definition and alarm lists to be sorted
Change offsets to integers instead of ids Change-Id: I58712dfe2ae8e6c40f52eb4753fc39e6cbfdd3b9
This commit is contained in:
parent
b0ff5227b0
commit
0195c9162d
|
@ -1786,8 +1786,10 @@ None.
|
|||
#### Query Parameters
|
||||
* name (string(255), optional) - Name of alarm to filter by.
|
||||
* dimensions (string, optional) - Dimensions of metrics to filter by specified as a comma separated array of (key, value) pairs as `key1:value1,key1:value1, ...`
|
||||
* offset (string, optional)
|
||||
* offset (integer, optional)
|
||||
* limit (integer, optional)
|
||||
* sort_by (string, optional) - Comma separated list of fields to sort by, defaults to 'id', 'created_at'. Fields may be followed by 'asc' or 'desc' to set the direction, ex 'severity desc'
|
||||
Allowed fields for sort_by are: 'id', 'name', 'severity', 'updated_at', 'created_at'
|
||||
|
||||
#### Request Body
|
||||
None.
|
||||
|
@ -2254,8 +2256,10 @@ None.
|
|||
* lifecycle_state (string(50), optional) - Lifecycle state to filter by.
|
||||
* link (string(512), optional) - Link to filter by.
|
||||
* state_updated_start_time (string, optional) - The start time in ISO 8601 combined date and time format in UTC.
|
||||
* offset (string, optional)
|
||||
* offset (integer, optional)
|
||||
* limit (integer, optional)
|
||||
* sort_by (string, optional) - Comma separated list of fields to sort by, defaults to 'alarm_id'. Fields may be followed by 'asc' or 'desc' to set the direction, ex 'severity desc'
|
||||
Allowed fields for sort_by are: 'alarm_id', 'alarm_definition_id', 'state', 'severity', 'lifecycle_state', 'link', 'state_updated_timestamp', 'updated_timestamp', 'created_timestamp'
|
||||
|
||||
#### Request Body
|
||||
None.
|
||||
|
|
|
@ -152,7 +152,7 @@ public class AlarmDefinitionService {
|
|||
|
||||
// Have to get information about the Alarms before they are deleted. They will be deleted
|
||||
// by the database as a cascade delete from the Alarm Definition delete
|
||||
final List<Alarm> alarms = alarmRepo.find(tenantId, alarmDefId, null, null, null, null, null, null, null, 1, false);
|
||||
final List<Alarm> alarms = alarmRepo.find(tenantId, alarmDefId, null, null, null, null, null, null, null, null, 1, false);
|
||||
final Map<String, Map<String, AlarmSubExpression>> alarmSubExpressions =
|
||||
alarmRepo.findAlarmSubExpressionsForAlarmDefinition(alarmDefId);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -13,9 +13,11 @@
|
|||
*/
|
||||
package monasca.api.app.validation;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
|
||||
|
@ -220,4 +222,26 @@ public final class Validation {
|
|||
public static boolean isCrossProjectRequest(String crossTenantId, String tenantId) {
|
||||
return !Strings.isNullOrEmpty(crossTenantId) && !crossTenantId.equals(tenantId);
|
||||
}
|
||||
|
||||
public static List<String> parseAndValidateSortBy(String sortBy, final List<String> allowed_sort_by) {
|
||||
List<String> sortByList = new ArrayList<>();
|
||||
if (sortBy != null && !sortBy.isEmpty()) {
|
||||
List<String> fieldList = Lists
|
||||
.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(sortBy));
|
||||
for (String sortByField: fieldList) {
|
||||
List<String> field = Lists.newArrayList(Splitter.on(' ').omitEmptyStrings().trimResults().split(sortByField));
|
||||
if (field.size() > 2) {
|
||||
throw Exceptions.unprocessableEntity(String.format("Invalid sort_by format %s", sortByField));
|
||||
}
|
||||
if (!allowed_sort_by.contains(field.get(0))) {
|
||||
throw Exceptions.unprocessableEntity(String.format("Sort_by field %s must be one of %s", field.get(0), allowed_sort_by));
|
||||
}
|
||||
if (field.size() > 1 && !field.get(1).equals("desc") && !field.get(1).equals("asc")) {
|
||||
throw Exceptions.unprocessableEntity(String.format("Sort_by value %s must be 'asc' or 'desc'", field.get(1)));
|
||||
}
|
||||
sortByList.add(Joiner.on(' ').join(field));
|
||||
}
|
||||
}
|
||||
return sortByList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ public interface AlarmRepo {
|
|||
* Returns alarms for the given criteria.
|
||||
*/
|
||||
List<Alarm> find(String tenantId, String alarmDefId, String metricName, Map<String,
|
||||
String> metricDimensions, AlarmState state, String lifecycleState, String link, DateTime stateUpdatedStart, String offset, int limit, boolean enforceLimit);
|
||||
String> metricDimensions, AlarmState state, String lifecycleState, String link, DateTime stateUpdatedStart,
|
||||
List<String> sort_by, String offset, int limit, boolean enforceLimit);
|
||||
|
||||
/**
|
||||
* @throws EntityNotFoundException if an alarm cannot be found for the {@code id}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -48,7 +48,7 @@ public interface AlarmDefinitionRepo {
|
|||
* Returns alarms for the given criteria.
|
||||
*/
|
||||
List<AlarmDefinition> find(String tenantId, String name, Map<String, String> dimensions,
|
||||
String offset, int limit);
|
||||
List<String> sortBy, String offset, int limit);
|
||||
|
||||
/**
|
||||
* @throws EntityNotFoundException if an alarm cannot be found for the {@code alarmDefId}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2015 FUJITSU LIMITED
|
||||
* Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -50,6 +51,7 @@ import monasca.api.domain.exception.EntityNotFoundException;
|
|||
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
|
||||
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
|
||||
import monasca.api.infrastructure.persistence.SubAlarmDefinitionQueries;
|
||||
import monasca.api.resource.exception.Exceptions;
|
||||
import monasca.common.hibernate.db.AlarmActionDb;
|
||||
import monasca.common.hibernate.db.AlarmDb;
|
||||
import monasca.common.hibernate.db.AlarmDefinitionDb;
|
||||
|
@ -225,8 +227,11 @@ public class AlarmDefinitionSqlRepoImpl
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<AlarmDefinition> find(String tenantId, String name, Map<String, String> dimensions, String offset, int limit) {
|
||||
public List<AlarmDefinition> find(String tenantId, String name, Map<String, String> dimensions, List<String> sortBy, String offset, int limit) {
|
||||
logger.trace(ORM_LOG_MARKER, "find(...) entering...");
|
||||
if (sortBy != null && !sortBy.isEmpty()) {
|
||||
throw Exceptions.unprocessableEntity("Sort_by is not implemented for the hibernate database type");
|
||||
}
|
||||
|
||||
Session session = null;
|
||||
List<AlarmDefinition> resultSet = Lists.newArrayList();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2015 FUJITSU LIMITED
|
||||
* Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -150,8 +151,12 @@ public class AlarmSqlRepoImpl
|
|||
public List<Alarm> find(String tenantId, String alarmDefId, String metricName,
|
||||
Map<String, String> metricDimensions, AlarmState state,
|
||||
String lifecycleState, String link, DateTime stateUpdatedStart,
|
||||
List<String> sortBy,
|
||||
String offset, int limit, boolean enforceLimit) {
|
||||
logger.trace(ORM_LOG_MARKER, "find(...) entering");
|
||||
if (sortBy != null && !sortBy.isEmpty()) {
|
||||
throw Exceptions.unprocessableEntity("Sort_by is not implemented for the hibernate database type");
|
||||
}
|
||||
|
||||
List<Alarm> alarms = this.findInternal(tenantId, alarmDefId, metricName, metricDimensions, state,
|
||||
lifecycleState, link, stateUpdatedStart, offset, (3 * limit / 2), enforceLimit);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -139,7 +139,7 @@ public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<AlarmDefinition> find(String tenantId, String name,
|
||||
Map<String, String> dimensions, String offset, int limit) {
|
||||
Map<String, String> dimensions, List<String> sortBy, String offset, int limit) {
|
||||
|
||||
|
||||
try (Handle h = db.open()) {
|
||||
|
@ -155,10 +155,9 @@ public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
|
|||
+ " FROM alarm_definition AS ad "
|
||||
+ " LEFT OUTER JOIN sub_alarm_definition AS sad ON ad.id = sad.alarm_definition_id "
|
||||
+ " LEFT OUTER JOIN sub_alarm_definition_dimension AS dim ON sad.id = dim.sub_alarm_definition_id %1$s "
|
||||
+ " WHERE ad.tenant_id = :tenantId AND ad.deleted_at IS NULL %2$s %3$s) AS t "
|
||||
+ " WHERE ad.tenant_id = :tenantId AND ad.deleted_at IS NULL %2$s) AS t "
|
||||
+ "LEFT OUTER JOIN alarm_action AS aa ON t.id = aa.alarm_definition_id "
|
||||
+ "GROUP BY t.id ORDER BY t.id, t.created_at";
|
||||
|
||||
+ "GROUP BY t.id %3$s %4$s %5$s";
|
||||
|
||||
StringBuilder sbWhere = new StringBuilder();
|
||||
|
||||
|
@ -166,8 +165,14 @@ public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
|
|||
sbWhere.append(" and ad.name = :name");
|
||||
}
|
||||
|
||||
if (offset != null) {
|
||||
sbWhere.append(" and ad.id > :offset");
|
||||
String orderByPart = "";
|
||||
if (sortBy != null && !sortBy.isEmpty()) {
|
||||
orderByPart = " order by " + COMMA_JOINER.join(sortBy);
|
||||
if (!orderByPart.contains("id")) {
|
||||
orderByPart = orderByPart + ",id";
|
||||
}
|
||||
} else {
|
||||
orderByPart = " order by id ";
|
||||
}
|
||||
|
||||
String limitPart = "";
|
||||
|
@ -175,8 +180,14 @@ public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
|
|||
limitPart = " limit :limit";
|
||||
}
|
||||
|
||||
String offsetPart = "";
|
||||
if (offset != null) {
|
||||
offsetPart = " offset " + offset + ' ';
|
||||
}
|
||||
|
||||
String sql = String.format(query,
|
||||
SubAlarmDefinitionQueries.buildJoinClauseFor(dimensions), sbWhere, limitPart);
|
||||
SubAlarmDefinitionQueries.buildJoinClauseFor(dimensions), sbWhere, orderByPart,
|
||||
limitPart, offsetPart);
|
||||
|
||||
Query<?> q = h.createQuery(sql);
|
||||
|
||||
|
@ -186,10 +197,6 @@ public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
|
|||
q.bind("name", name);
|
||||
}
|
||||
|
||||
if (offset != null) {
|
||||
q.bind("offset", offset);
|
||||
}
|
||||
|
||||
if (limit > 0) {
|
||||
q.bind("limit", limit + 1);
|
||||
}
|
||||
|
|
|
@ -50,16 +50,15 @@ import javax.inject.Named;
|
|||
*/
|
||||
public class AlarmMySqlRepoImpl implements AlarmRepo {
|
||||
|
||||
private static final Joiner COMMA_JOINER = Joiner.on(',');
|
||||
private static final Logger logger = LoggerFactory.getLogger(AlarmMySqlRepoImpl.class);
|
||||
|
||||
private final DBI db;
|
||||
private final PersistUtils persistUtils;
|
||||
|
||||
private static final Joiner COMMA_JOINER = Joiner.on(',');
|
||||
|
||||
private static final String FIND_ALARM_BY_ID_SQL =
|
||||
"select ad.id as alarm_definition_id, ad.severity, ad.name as alarm_definition_name, "
|
||||
+ "a.id, a.state, a.lifecycle_state, a.link, a.state_updated_at as state_updated_timestamp, "
|
||||
+ "a.id as alarm_id, a.state, a.lifecycle_state, a.link, a.state_updated_at as state_updated_timestamp, "
|
||||
+ "a.updated_at as updated_timestamp, a.created_at as created_timestamp, "
|
||||
+ "md.name as metric_name, mdg.dimensions as metric_dimensions from alarm as a "
|
||||
+ "inner join alarm_definition ad on ad.id = a.alarm_definition_id "
|
||||
|
@ -72,18 +71,18 @@ public class AlarmMySqlRepoImpl implements AlarmRepo {
|
|||
|
||||
private static final String FIND_ALARMS_SQL =
|
||||
"select ad.id as alarm_definition_id, ad.severity, ad.name as alarm_definition_name, "
|
||||
+ "a.id, a.state, a.lifecycle_state, a.link, a.state_updated_at as state_updated_timestamp, "
|
||||
+ "a.id as alarm_id, a.state, a.lifecycle_state, a.link, a.state_updated_at as state_updated_timestamp, "
|
||||
+ "a.updated_at as updated_timestamp, a.created_at as created_timestamp, "
|
||||
+ "md.name as metric_name, group_concat(mdim.name, '=', mdim.value order by mdim.name) as metric_dimensions "
|
||||
+ "from alarm as a "
|
||||
+ "inner join %s as alarm_id_list on alarm_id_list.id = a.id "
|
||||
+ "inner join %1$s as alarm_id_list on alarm_id_list.id = a.id "
|
||||
+ "inner join alarm_definition ad on ad.id = a.alarm_definition_id "
|
||||
+ "inner join alarm_metric as am on am.alarm_id = a.id "
|
||||
+ "inner join metric_definition_dimensions as mdd on mdd.id = am.metric_definition_dimensions_id "
|
||||
+ "inner join metric_definition as md on md.id = mdd.metric_definition_id "
|
||||
+ "left outer join metric_dimension as mdim on mdim.dimension_set_id = mdd.metric_dimension_set_id "
|
||||
+ "group by a.id, md.name, mdim.dimension_set_id "
|
||||
+ "order by a.id ASC";
|
||||
+ "%2$s";
|
||||
|
||||
@Inject
|
||||
public AlarmMySqlRepoImpl(@Named("mysql") DBI db, PersistUtils persistUtils) {
|
||||
|
@ -122,8 +121,8 @@ public class AlarmMySqlRepoImpl implements AlarmRepo {
|
|||
@Override
|
||||
public List<Alarm> find(String tenantId, String alarmDefId, String metricName,
|
||||
Map<String, String> metricDimensions, AlarmState state,
|
||||
String lifecycleState, String link, DateTime stateUpdatedStart, String offset,
|
||||
int limit, boolean enforceLimit) {
|
||||
String lifecycleState, String link, DateTime stateUpdatedStart,
|
||||
List<String> sortBy, String offset, int limit, boolean enforceLimit) {
|
||||
|
||||
StringBuilder
|
||||
sbWhere =
|
||||
|
@ -180,19 +179,32 @@ public class AlarmMySqlRepoImpl implements AlarmRepo {
|
|||
sbWhere.append(" and a.state_updated_at >= :stateUpdatedStart");
|
||||
}
|
||||
|
||||
if (offset != null) {
|
||||
sbWhere.append(" and a.id > :offset");
|
||||
StringBuilder sortByClause = new StringBuilder();
|
||||
if (sortBy != null && !sortBy.isEmpty()) {
|
||||
sortByClause.append(" order by ");
|
||||
sortByClause.append(COMMA_JOINER.join(sortBy));
|
||||
// if alarm_id is not in the list, add it
|
||||
if (sortByClause.indexOf("alarm_id") == -1) {
|
||||
sortByClause.append(",alarm_id ASC");
|
||||
}
|
||||
sortByClause.append(' ');
|
||||
} else {
|
||||
sortByClause.append(" order by alarm_id ASC ");
|
||||
}
|
||||
|
||||
sbWhere.append(" order by a.id ASC ");
|
||||
|
||||
if (enforceLimit && limit > 0) {
|
||||
sbWhere.append(" limit :limit");
|
||||
}
|
||||
|
||||
if (offset != null) {
|
||||
sbWhere.append(" offset ");
|
||||
sbWhere.append(offset);
|
||||
sbWhere.append(' ');
|
||||
}
|
||||
|
||||
sbWhere.append(")");
|
||||
|
||||
String sql = String.format(FIND_ALARMS_SQL, sbWhere);
|
||||
String sql = String.format(FIND_ALARMS_SQL, sbWhere, sortByClause);
|
||||
|
||||
try (Handle h = db.open()) {
|
||||
|
||||
|
@ -222,10 +234,6 @@ public class AlarmMySqlRepoImpl implements AlarmRepo {
|
|||
q.bind("stateUpdatedStart", stateUpdatedStart.toString());
|
||||
}
|
||||
|
||||
if (offset != null) {
|
||||
q.bind("offset", offset);
|
||||
}
|
||||
|
||||
if (enforceLimit && limit > 0) {
|
||||
q.bind("limit", limit + 1);
|
||||
}
|
||||
|
@ -267,7 +275,7 @@ public class AlarmMySqlRepoImpl implements AlarmRepo {
|
|||
final List<Alarm> alarms = new LinkedList<>();
|
||||
List<MetricDefinition> alarmedMetrics = null;
|
||||
for (final Map<String, Object> row : rows) {
|
||||
final String alarmId = (String) row.get("id");
|
||||
final String alarmId = (String) row.get("alarm_id");
|
||||
if (!alarmId.equals(previousAlarmId)) {
|
||||
alarmedMetrics = new ArrayList<>();
|
||||
alarm =
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonMappingException;
|
|||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -62,6 +63,8 @@ public class AlarmDefinitionResource {
|
|||
private final PersistUtils persistUtils;
|
||||
public final static String ALARM_DEFINITIONS = "alarm-definitions";
|
||||
public final static String ALARM_DEFINITIONS_PATH = "/v2.0/" + ALARM_DEFINITIONS;
|
||||
private final static List<String> ALLOWED_SORT_BY = Arrays.asList("id", "name", "severity",
|
||||
"updated_at", "created_at");
|
||||
|
||||
@Inject
|
||||
public AlarmDefinitionResource(AlarmDefinitionService service,
|
||||
|
@ -93,20 +96,27 @@ public class AlarmDefinitionResource {
|
|||
public Object list(@Context UriInfo uriInfo,
|
||||
@HeaderParam("X-Tenant-Id") String tenantId, @QueryParam("name") String name,
|
||||
@QueryParam("dimensions") String dimensionsStr,
|
||||
@QueryParam("sort_by") String sortByStr,
|
||||
@QueryParam("offset") String offset,
|
||||
@QueryParam("limit") String limit) throws UnsupportedEncodingException {
|
||||
Map<String, String> dimensions =
|
||||
Strings.isNullOrEmpty(dimensionsStr) ? null : Validation
|
||||
.parseAndValidateDimensions(dimensionsStr);
|
||||
|
||||
List<String> sortByList = Validation.parseAndValidateSortBy(sortByStr, ALLOWED_SORT_BY);
|
||||
if (!Strings.isNullOrEmpty(offset)) {
|
||||
Validation.parseAndValidateNumber(offset, "offset");
|
||||
}
|
||||
|
||||
final int paging_limit = this.persistUtils.getLimit(limit);
|
||||
final List<AlarmDefinition> resources = repo.find(tenantId,
|
||||
name,
|
||||
dimensions,
|
||||
offset,
|
||||
paging_limit
|
||||
name,
|
||||
dimensions,
|
||||
sortByList,
|
||||
offset,
|
||||
paging_limit
|
||||
);
|
||||
return Links.paginate(paging_limit, Links.hydrate(resources, uriInfo), uriInfo);
|
||||
return Links.paginateAlarming(paging_limit, Links.hydrate(resources, uriInfo), uriInfo);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
|
|
@ -71,6 +71,10 @@ public class AlarmResource {
|
|||
"lifecycle_state",
|
||||
"metric_name", "dimension_name",
|
||||
"dimension_value");
|
||||
private final static List<String> ALLOWED_SORT_BY = Arrays.asList("alarm_id", "alarm_definition_id", "state",
|
||||
"severity", "lifecycle_state", "link",
|
||||
"state_updated_timestamp", "updated_timestamp",
|
||||
"created_timestamp");
|
||||
|
||||
@Inject
|
||||
public AlarmResource(AlarmService service, AlarmRepo repo,
|
||||
|
@ -153,11 +157,11 @@ public class AlarmResource {
|
|||
|
||||
final int paging_limit = this.persistUtils.getLimit(limit);
|
||||
final List<AlarmStateHistory> resources = stateHistoryRepo.find(tenantId,
|
||||
dimensions,
|
||||
startTime,
|
||||
endTime,
|
||||
offset,
|
||||
paging_limit
|
||||
dimensions,
|
||||
startTime,
|
||||
endTime,
|
||||
offset,
|
||||
paging_limit
|
||||
);
|
||||
return Links.paginate(paging_limit, resources, uriInfo);
|
||||
}
|
||||
|
@ -173,6 +177,7 @@ public class AlarmResource {
|
|||
@QueryParam("lifecycle_state") String lifecycleState,
|
||||
@QueryParam("link") String link,
|
||||
@QueryParam("state_updated_start_time") String stateUpdatedStartStr,
|
||||
@QueryParam("sort_by") String sortBy,
|
||||
@QueryParam("offset") String offset,
|
||||
@QueryParam("limit") String limit)
|
||||
throws Exception {
|
||||
|
@ -185,9 +190,14 @@ public class AlarmResource {
|
|||
Validation.parseAndValidateDate(stateUpdatedStartStr,
|
||||
"state_updated_start_time", false);
|
||||
|
||||
List<String> sortByList = Validation.parseAndValidateSortBy(sortBy, ALLOWED_SORT_BY);
|
||||
if (!Strings.isNullOrEmpty(offset)) {
|
||||
Validation.parseAndValidateNumber(offset, "offset");
|
||||
}
|
||||
|
||||
final int paging_limit = this.persistUtils.getLimit(limit);
|
||||
final List<Alarm> alarms = repo.find(tenantId, alarmDefId, metricName, metricDimensions, state,
|
||||
lifecycleState, link, stateUpdatedStart,
|
||||
lifecycleState, link, stateUpdatedStart, sortByList,
|
||||
offset, paging_limit, true);
|
||||
for (final Alarm alarm : alarms) {
|
||||
Links.hydrate(
|
||||
|
@ -196,9 +206,11 @@ public class AlarmResource {
|
|||
AlarmDefinitionResource.ALARM_DEFINITIONS_PATH
|
||||
);
|
||||
}
|
||||
return Links.paginate(paging_limit, Links.hydrate(alarms, uriInfo), uriInfo);
|
||||
return Links.paginateAlarming(paging_limit, Links.hydrate(alarms, uriInfo), uriInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@PATCH
|
||||
@Timed
|
||||
@Path("/{alarm_id}")
|
||||
|
|
|
@ -197,6 +197,44 @@ public final class Links {
|
|||
|
||||
}
|
||||
|
||||
public static Object paginateAlarming(int limit, List<? extends AbstractEntity> elements, UriInfo uriInfo)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
// Check for paging turned off. Happens if maxQueryLimit is not set or is set to zero.
|
||||
if (limit == 0) {
|
||||
Paged paged = new Paged();
|
||||
paged.elements = elements != null ? elements : new ArrayList<>();
|
||||
return paged;
|
||||
}
|
||||
|
||||
Paged paged = new Paged();
|
||||
|
||||
paged.links.add(getSelfLink(uriInfo));
|
||||
|
||||
if (elements != null) {
|
||||
|
||||
if (elements.size() > limit) {
|
||||
|
||||
String offset = String.valueOf(limit);
|
||||
|
||||
paged.links.add(getNextLink(offset, uriInfo));
|
||||
|
||||
// Truncate the list. Normally this will just truncate one extra element.
|
||||
elements = elements.subList(0, limit);
|
||||
}
|
||||
|
||||
paged.elements = elements;
|
||||
|
||||
} else {
|
||||
|
||||
paged.elements = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
return paged;
|
||||
|
||||
}
|
||||
|
||||
public static Object paginateMeasurements(int limit, List<Measurements> elements, UriInfo uriInfo)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2015 FUJITSU LIMITED
|
||||
* Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -49,6 +50,8 @@ import org.testng.annotations.AfterMethod;
|
|||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
@Test(groups = "orm")
|
||||
public class AlarmDefinitionSqlRepositoryImplTest {
|
||||
|
||||
|
@ -340,33 +343,38 @@ public class AlarmDefinitionSqlRepositoryImplTest {
|
|||
fail();
|
||||
} catch (EntityNotFoundException expected) {
|
||||
}
|
||||
assertEquals(Arrays.asList(alarmDef_234), repo.find("bob", null, null, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_234), repo.find("bob", null, null, null, null, 1));
|
||||
}
|
||||
|
||||
public void shouldFindByDimension() {
|
||||
final Map<String, String> dimensions = new HashMap<>();
|
||||
dimensions.put("image_id", "888");
|
||||
|
||||
List<AlarmDefinition> result = repo.find("bob", null, dimensions, null, 1);
|
||||
List<AlarmDefinition> result = repo.find("bob", null, dimensions, null, null, 1);
|
||||
|
||||
assertEquals(Arrays.asList(alarmDef_123, alarmDef_234), result);
|
||||
|
||||
dimensions.clear();
|
||||
dimensions.put("device", "1");
|
||||
assertEquals(Arrays.asList(alarmDef_123), repo.find("bob", null, dimensions, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_123), repo.find("bob", null, dimensions, null, null, 1));
|
||||
|
||||
dimensions.clear();
|
||||
dimensions.put("Not real", "AA");
|
||||
assertEquals(0, repo.find("bob", null, dimensions, null, 1).size());
|
||||
assertEquals(0, repo.find("bob", null, dimensions, null, null, 1).size());
|
||||
}
|
||||
|
||||
public void shouldFindByName() {
|
||||
final Map<String, String> dimensions = new HashMap<>();
|
||||
dimensions.put("image_id", "888");
|
||||
|
||||
List<AlarmDefinition> result = repo.find("bob", "90% CPU", dimensions, null, 1);
|
||||
List<AlarmDefinition> result = repo.find("bob", "90% CPU", dimensions, null, null, 1);
|
||||
|
||||
assertEquals(Arrays.asList(alarmDef_123), result);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "orm", expectedExceptions = WebApplicationException.class)
|
||||
public void shouldFindThrowException() {
|
||||
repo.find("bob", null, null, Arrays.asList("severity", "state"), null, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2015 FUJITSU LIMITED
|
||||
* Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -24,6 +25,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -346,55 +348,60 @@ public class AlarmSqlRepositoryImplTest {
|
|||
@Test(groups = "orm")
|
||||
public void shouldFind() {
|
||||
|
||||
checkList(repo.find("Not a tenant id", null, null, null, null, null, null, null, null, 1, false));
|
||||
checkList(repo.find("Not a tenant id", null, null, null, null, null, null, null, null, null, 1, false));
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null, null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", null, null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", ImmutableMap.<String, String>builder().put("flavor_id", "222").build(), null, null, null,
|
||||
null, null, 1, false), alarm1, alarm3);
|
||||
null, null, null, 1, false), alarm1, alarm3);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, null, "cpu.idle_perc", ImmutableMap.<String, String>builder().put("service", "monitoring").put("hostname", "roland")
|
||||
.build(), null, null, null, null, null, 1, false), compoundAlarm);
|
||||
.build(), null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, AlarmState.UNDETERMINED, null, null, null, null, 1, false), alarm2, compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, null, null, AlarmState.UNDETERMINED, null, null, null, null, null, 1, false), alarm2, compoundAlarm);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", ImmutableMap.<String, String>builder()
|
||||
.put("service", "monitoring").build(), null, null, null, null, null, 1, false), alarm1, alarm2);
|
||||
.put("service", "monitoring").build(), null, null, null, null, null, null, 1, false), alarm1, alarm2);
|
||||
|
||||
checkList(repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", null, null, null, null, null, null, 1, false), alarm1,
|
||||
checkList(repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", null, null, null, null, null, null, null, 1, false), alarm1,
|
||||
alarm2, alarm3);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null, AlarmState.UNDETERMINED, null, null, null, null, 1, false),
|
||||
repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null, AlarmState.UNDETERMINED, null, null, null, null, null, 1, false),
|
||||
compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, AlarmState.UNDETERMINED, null, null, null, null, 1, false), compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, AlarmState.UNDETERMINED, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", ImmutableMap.<String, String>builder().put("service", "monitoring").build(),
|
||||
AlarmState.UNDETERMINED, null, null, null, null, 1, false), alarm2, compoundAlarm);
|
||||
AlarmState.UNDETERMINED, null, null, null, null, null, 1, false), alarm2, compoundAlarm);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", ImmutableMap.<String, String>builder()
|
||||
.put("service", "monitoring").build(), AlarmState.UNDETERMINED, null, null, null, null, 1, false), alarm2);
|
||||
.put("service", "monitoring").build(), AlarmState.UNDETERMINED, null, null, null, null, null, 1, false), alarm2);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, DateTime.now(UTC_TIMEZONE), null, 0, false));
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, DateTime.now(UTC_TIMEZONE), null, null, 0, false));
|
||||
|
||||
//checkList(repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-15T00:00:00Z"), null, 0, false),
|
||||
// compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-14T00:00:00Z"), null, 1, false),
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-14T00:00:00Z"), null, null, 1, false),
|
||||
alarm1, alarm2, alarm3, compoundAlarm);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "orm", expectedExceptions = WebApplicationException.class)
|
||||
public void shouldFindThrowException() {
|
||||
repo.find(TENANT_ID, null, null, null, null, null, null, null, Arrays.asList("severity", "state"), null, 1, true);
|
||||
}
|
||||
|
||||
@Test(groups = "orm")
|
||||
public void shouldFindById() {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -245,36 +245,42 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
|
|||
}
|
||||
|
||||
public void shouldFind() {
|
||||
assertEquals(Arrays.asList(alarmDef_123, alarmDef_234), repo.find("bob", null, null, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_123, alarmDef_234), repo.find("bob", null, null, null, null, 1));
|
||||
|
||||
// Make sure it still finds AlarmDefinitions with no notifications
|
||||
handle.execute("delete from alarm_action");
|
||||
alarmDef_123.setAlarmActions(new ArrayList<String>(0));
|
||||
alarmDef_234.setAlarmActions(new ArrayList<String>(0));
|
||||
assertEquals(Arrays.asList(alarmDef_123, alarmDef_234), repo.find("bob", null, null, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_123, alarmDef_234), repo.find("bob", null, null, null, null, 1));
|
||||
|
||||
assertEquals(0, repo.find("bill", null, null, null, 1).size());
|
||||
assertEquals(0, repo.find("bill", null, null, null, null, 1).size());
|
||||
|
||||
assertEquals(Arrays.asList(alarmDef_234, alarmDef_123),
|
||||
repo.find("bob", null, null, Arrays.asList("name"), null, 1));
|
||||
|
||||
assertEquals(Arrays.asList(alarmDef_234, alarmDef_123),
|
||||
repo.find("bob", null, null, Arrays.asList("id desc"), null, 1));
|
||||
}
|
||||
|
||||
public void shouldFindByDimension() {
|
||||
final Map<String, String> dimensions = new HashMap<>();
|
||||
dimensions.put("image_id", "888");
|
||||
assertEquals(Arrays.asList(alarmDef_123, alarmDef_234),
|
||||
repo.find("bob", null, dimensions, null, 1));
|
||||
repo.find("bob", null, dimensions, null, null, 1));
|
||||
|
||||
dimensions.clear();
|
||||
dimensions.put("device", "1");
|
||||
assertEquals(Arrays.asList(alarmDef_123), repo.find("bob", null, dimensions, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_123), repo.find("bob", null, dimensions, null, null, 1));
|
||||
|
||||
dimensions.clear();
|
||||
dimensions.put("Not real", "AA");
|
||||
assertEquals(0, repo.find("bob", null, dimensions, null, 1).size());
|
||||
assertEquals(0, repo.find("bob", null, dimensions, null, null, 1).size());
|
||||
}
|
||||
|
||||
public void shouldFindByName() {
|
||||
assertEquals(Arrays.asList(alarmDef_123), repo.find("bob", "90% CPU", null, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_123), repo.find("bob", "90% CPU", null, null, null, 1));
|
||||
|
||||
assertEquals(0, repo.find("bob", "Does not exist", null, null, 1).size());
|
||||
assertEquals(0, repo.find("bob", "Does not exist", null, null, null, 1).size());
|
||||
}
|
||||
|
||||
public void shouldDeleteById() {
|
||||
|
@ -285,6 +291,6 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
|
|||
fail();
|
||||
} catch (EntityNotFoundException expected) {
|
||||
}
|
||||
assertEquals(Arrays.asList(alarmDef_234), repo.find("bob", null, null, null, 1));
|
||||
assertEquals(Arrays.asList(alarmDef_234), repo.find("bob", null, null, null, null, 1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -166,7 +166,7 @@ public class AlarmMySqlRepositoryImplTest {
|
|||
handle
|
||||
.execute(
|
||||
"insert into alarm_definition (id, tenant_id, name, severity, expression, match_by, actions_enabled, created_at, updated_at, deleted_at) "
|
||||
+ "values ('234', 'bob', '50% CPU', 'LOW', 'avg(cpu.sys_mem{service=monitoring}) > 20 and avg(cpu.idle_perc{service=monitoring}) < 10', 'hostname,region', 1, NOW(), NOW(), NULL)");
|
||||
+ "values ('234', 'bob', '50% CPU', 'HIGH', 'avg(cpu.sys_mem{service=monitoring}) > 20 and avg(cpu.idle_perc{service=monitoring}) < 10', 'hostname,region', 1, NOW(), NOW(), NULL)");
|
||||
handle
|
||||
.execute("insert into alarm (id, alarm_definition_id, state, created_at, updated_at, state_updated_at) values ('234111', '234', 'UNDETERMINED', '"+timestamp4.toString().replace('Z', ' ')+"', '"+timestamp4.toString().replace('Z', ' ')+"', '"+timestamp4.toString().replace('Z', ' ')+"')");
|
||||
handle
|
||||
|
@ -202,7 +202,7 @@ public class AlarmMySqlRepositoryImplTest {
|
|||
.execute("insert into metric_dimension (dimension_set_id, name, value) values (22, 'extra', 'vivi')");
|
||||
|
||||
compoundAlarm =
|
||||
new Alarm("234111", "234", "50% CPU", "LOW", buildAlarmMetrics(
|
||||
new Alarm("234111", "234", "50% CPU", "HIGH", buildAlarmMetrics(
|
||||
buildMetricDefinition("cpu.sys_mem", "service", "monitoring", "hostname", "roland",
|
||||
"region", "colorado"),
|
||||
buildMetricDefinition("cpu.idle_perc", "service", "monitoring", "hostname", "roland",
|
||||
|
@ -271,58 +271,64 @@ public class AlarmMySqlRepositoryImplTest {
|
|||
|
||||
@Test(groups = "database")
|
||||
public void shouldFind() {
|
||||
checkList(repo.find("Not a tenant id", null, null, null, null, null, null, null, null, 1, false));
|
||||
checkList(repo.find("Not a tenant id", null, null, null, null, null, null, null, null, null, 1, false));
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null, null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", null, null, null, null, null, null, null, 1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, null, "cpu.idle_perc",
|
||||
ImmutableMap.<String, String>builder().put("flavor_id", "222").build(), null, null, null, null, null, 1, false), alarm1,
|
||||
ImmutableMap.<String, String>builder().put("flavor_id", "222").build(), null, null, null, null, null, null, 1, false), alarm1,
|
||||
alarm3);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, null, "cpu.idle_perc",
|
||||
ImmutableMap.<String, String>builder().put("service", "monitoring")
|
||||
.put("hostname", "roland").build(), null, null, null, null, null, 1, false), compoundAlarm);
|
||||
.put("hostname", "roland").build(), null, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, AlarmState.UNDETERMINED, null, null, null, null, 1, false),
|
||||
checkList(repo.find(TENANT_ID, null, null, null, AlarmState.UNDETERMINED, null, null, null, null, null, 1, false),
|
||||
alarm2,
|
||||
compoundAlarm);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", ImmutableMap
|
||||
.<String, String>builder().put("service", "monitoring").build(), null, null, null, null, null, 1, false), alarm1, alarm2);
|
||||
.<String, String>builder().put("service", "monitoring").build(), null, null, null, null, null, null, 1, false), alarm1, alarm2);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", null, null, null, null, null, null, 1, false),
|
||||
repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc", null, null, null, null, null, null, null, 1, false),
|
||||
alarm1, alarm2, alarm3);
|
||||
|
||||
checkList(repo.find(TENANT_ID, compoundAlarm.getAlarmDefinition().getId(), null, null,
|
||||
AlarmState.UNDETERMINED, null, null, null, null, 1, false), compoundAlarm);
|
||||
AlarmState.UNDETERMINED, null, null, null, null, null, 1, false), compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, AlarmState.UNDETERMINED, null, null, null, null, 1, false),
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.sys_mem", null, AlarmState.UNDETERMINED, null, null, null, null, null, 1, false),
|
||||
compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, "cpu.idle_perc", ImmutableMap.<String, String>builder()
|
||||
.put("service", "monitoring").build(), AlarmState.UNDETERMINED, null, null, null, null, 1,false), alarm2, compoundAlarm);
|
||||
.put("service", "monitoring").build(), AlarmState.UNDETERMINED, null, null, null, null, null, 1,false), alarm2, compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, alarm1.getAlarmDefinition().getId(), "cpu.idle_perc",
|
||||
ImmutableMap.<String, String>builder().put("service", "monitoring").build(),
|
||||
AlarmState.UNDETERMINED, null, null, null, null, 1, false), alarm2);
|
||||
AlarmState.UNDETERMINED, null, null, null, null, null, 1, false), alarm2);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, DateTime.now(DateTimeZone.forID("UTC")), null, 0, false));
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, DateTime.now(DateTimeZone.forID("UTC")), null, null, 0, false));
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-15T00:00:00Z"), null, 0, false), compoundAlarm);
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-15T00:00:00Z"), null, null, 0, false), compoundAlarm);
|
||||
|
||||
checkList(
|
||||
repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-14T00:00:00Z"), null,
|
||||
repo.find(TENANT_ID, null, null, null, null, null, null, ISO_8601_FORMATTER.parseDateTime("2015-03-14T00:00:00Z"), null, null,
|
||||
1, false), alarm1, alarm2, alarm3, compoundAlarm);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, null, Arrays.asList("state","severity"), null, 1, false),
|
||||
alarm1, alarm2, compoundAlarm, alarm3);
|
||||
|
||||
checkList(repo.find(TENANT_ID, null, null, null, null, null, null, null, Arrays.asList("state desc","severity"), null, 1, false),
|
||||
compoundAlarm, alarm3, alarm2, alarm1);
|
||||
}
|
||||
|
||||
private DateTime getAlarmStateUpdatedDate(final String alarmId) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
* Copyright (c) 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
*
|
||||
* Licensed 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
|
||||
|
@ -16,6 +16,7 @@ package monasca.api.resource;
|
|||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyList;
|
||||
import static org.mockito.Matchers.anyMap;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
|
@ -85,7 +86,8 @@ public class AlarmDefinitionResourceTest extends AbstractMonApiResourceTest {
|
|||
|
||||
repo = mock(AlarmDefinitionRepo.class);
|
||||
when(repo.findById(eq("abc"), eq("123"))).thenReturn(alarm);
|
||||
when(repo.find(anyString(), anyString(), (Map<String, String>) anyMap(), anyString(), anyInt())).thenReturn(
|
||||
when(repo.find(anyString(), anyString(), (Map<String, String>) anyMap(), (List<String>) anyList(),
|
||||
anyString(), anyInt())).thenReturn(
|
||||
Arrays.asList(alarmItem));
|
||||
|
||||
addResources(new AlarmDefinitionResource(service, repo, new PersistUtils()));
|
||||
|
@ -275,7 +277,8 @@ public class AlarmDefinitionResourceTest extends AbstractMonApiResourceTest {
|
|||
|
||||
assertEquals(alarms, Arrays.asList(alarmItem));
|
||||
|
||||
verify(repo).find(eq("abc"), anyString(), (Map<String, String>) anyMap(), anyString(), anyInt());
|
||||
verify(repo).find(eq("abc"), anyString(), (Map<String, String>) anyMap(), (List<String>) anyList(),
|
||||
anyString(), anyInt());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -306,8 +309,8 @@ public class AlarmDefinitionResourceTest extends AbstractMonApiResourceTest {
|
|||
List<AlarmDefinition> alarms = Arrays.asList(ad);
|
||||
|
||||
assertEquals(alarms, Arrays.asList(alarmItem));
|
||||
verify(repo).find(eq("abc"), eq("foo bar baz"), (Map<String, String>) anyMap(), anyString(),
|
||||
anyInt());
|
||||
verify(repo).find(eq("abc"), eq("foo bar baz"), (Map<String, String>) anyMap(), (List<String>) anyList(),
|
||||
anyString(), anyInt());
|
||||
}
|
||||
|
||||
public void shouldGet() {
|
||||
|
@ -352,13 +355,13 @@ public class AlarmDefinitionResourceTest extends AbstractMonApiResourceTest {
|
|||
public void should500OnInternalException() {
|
||||
doThrow(new RuntimeException("")).when(repo).find(anyString(), anyString(),
|
||||
|
||||
(Map<String, String>) anyObject(), anyString(), anyInt());
|
||||
(Map<String, String>) anyObject(), (List<String>) anyList(), anyString(), anyInt());
|
||||
|
||||
try {
|
||||
client().resource("/v2.0/alarm-definitions").header("X-Tenant-Id", "abc").get(List.class);
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
assertTrue(e.getMessage().contains("500"));
|
||||
assertTrue(e.getMessage().contains("500"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2014 Hewlett-Packard
|
||||
# Copyright 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -50,8 +50,8 @@ class AlarmDefinitionsRepository(object):
|
|||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_alarm_definitions(self, tenant_id, name, dimensions, offset,
|
||||
limit):
|
||||
def get_alarm_definitions(self, tenant_id, name, dimensions, sort_by,
|
||||
offset, limit):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2014 Hewlett-Packard
|
||||
# Copyright 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -76,8 +76,8 @@ class AlarmDefinitionsRepository(mysql_repository.MySQLRepository,
|
|||
raise exceptions.DoesNotExistException
|
||||
|
||||
@mysql_repository.mysql_try_catch_block
|
||||
def get_alarm_definitions(self, tenant_id, name, dimensions, offset,
|
||||
limit):
|
||||
def get_alarm_definitions(self, tenant_id, name, dimensions,
|
||||
sort_by, offset, limit):
|
||||
|
||||
parms = [tenant_id]
|
||||
|
||||
|
@ -89,14 +89,20 @@ class AlarmDefinitionsRepository(mysql_repository.MySQLRepository,
|
|||
where_clause += " and ad.name = %s "
|
||||
parms.append(name.encode('utf8'))
|
||||
|
||||
order_by_clause = " order by ad.id, ad.created_at "
|
||||
if sort_by is not None:
|
||||
order_by_clause = " order by " + ','.join(sort_by)
|
||||
if 'id' not in sort_by:
|
||||
order_by_clause += ",ad.id "
|
||||
else:
|
||||
order_by_clause += " "
|
||||
else:
|
||||
order_by_clause = " order by ad.id "
|
||||
|
||||
limit_offset_clause = " limit %s "
|
||||
parms.append(limit + 1)
|
||||
|
||||
if offset:
|
||||
where_clause += " and ad.id > %s "
|
||||
parms.append(offset.encode('utf8'))
|
||||
|
||||
limit_clause = " limit %s "
|
||||
parms.append(limit + 1)
|
||||
limit_offset_clause += ' offset {}'.format(offset)
|
||||
|
||||
if dimensions:
|
||||
inner_join = """ inner join sub_alarm_definition as sad
|
||||
|
@ -119,7 +125,7 @@ class AlarmDefinitionsRepository(mysql_repository.MySQLRepository,
|
|||
select_clause += inner_join
|
||||
parms = inner_join_parms + parms
|
||||
|
||||
query = select_clause + where_clause + order_by_clause + limit_clause
|
||||
query = select_clause + where_clause + order_by_clause + limit_offset_clause
|
||||
|
||||
return self._execute_query(query, parms)
|
||||
|
||||
|
|
|
@ -214,14 +214,8 @@ class AlarmsRepository(mysql_repository.MySQLRepository,
|
|||
|
||||
select_clause = AlarmsRepository.base_query
|
||||
|
||||
order_by_clause = " order by a.id "
|
||||
|
||||
where_clause = " where ad.tenant_id = %s "
|
||||
|
||||
if offset:
|
||||
where_clause += " and a.id > %s"
|
||||
parms.append(offset.encode('utf8'))
|
||||
|
||||
if 'alarm_definition_id' in query_parms:
|
||||
parms.append(query_parms['alarm_definition_id'])
|
||||
where_clause += " and ad.id = %s "
|
||||
|
@ -287,13 +281,29 @@ class AlarmsRepository(mysql_repository.MySQLRepository,
|
|||
parms += sub_select_parms
|
||||
where_clause += sub_select_clause
|
||||
|
||||
if 'sort_by' in query_parms:
|
||||
order_by_clause = " order by " + ','.join(query_parms['sort_by'])
|
||||
if 'alarm_id' not in query_parms['sort_by']:
|
||||
order_by_clause += ",alarm_id "
|
||||
else:
|
||||
order_by_clause += " "
|
||||
else:
|
||||
order_by_clause = " order by a.id "
|
||||
|
||||
if offset:
|
||||
offset_clause = " offset {}".format(offset)
|
||||
else:
|
||||
offset_clause = ""
|
||||
|
||||
if limit:
|
||||
limit_clause = " limit %s "
|
||||
parms.append(limit + 1)
|
||||
else:
|
||||
limit_clause = ""
|
||||
|
||||
query = select_clause + where_clause + order_by_clause + limit_clause
|
||||
query = select_clause + where_clause + order_by_clause + limit_clause + offset_clause
|
||||
|
||||
LOG.debug("Query: {}".format(query))
|
||||
|
||||
return self._execute_query(query, parms)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||
# (C) Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015 Hewlett-Packard
|
||||
# Copyright 2015,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -12,9 +12,11 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from monasca_api.v2.common.exceptions import HTTPUnprocessableEntityError
|
||||
|
||||
import re
|
||||
|
||||
invalid_chars = "<>={}(),\"\\\\;&"
|
||||
invalid_chars = "<>={}(),'\"\\\\;&"
|
||||
restricted_chars = re.compile('[' + invalid_chars + ']')
|
||||
|
||||
|
||||
|
@ -34,3 +36,20 @@ def dimension_value(value):
|
|||
assert isinstance(value, (str, unicode)), "Dimension value must be a string"
|
||||
assert len(value) <= 255, "Dimension value must be 255 characters or less"
|
||||
assert not restricted_chars.search(value), "Invalid characters in dimension value " + value
|
||||
|
||||
|
||||
def validate_sort_by(sort_by_list, allowed_sort_by):
|
||||
for sort_by_field in sort_by_list:
|
||||
sort_by_values = sort_by_field.split()
|
||||
if len(sort_by_values) > 2:
|
||||
raise HTTPUnprocessableEntityError("Unprocessable Entity",
|
||||
"Invalid sort_by {}".format(sort_by_field))
|
||||
if sort_by_values[0] not in allowed_sort_by:
|
||||
raise HTTPUnprocessableEntityError("Unprocessable Entity",
|
||||
"sort_by field {} must be one of [{}]".format(
|
||||
sort_by_values[0],
|
||||
','.join(list(allowed_sort_by))))
|
||||
if len(sort_by_values) > 1 and sort_by_values[1] not in ['asc', 'desc']:
|
||||
raise HTTPUnprocessableEntityError("Unprocessable Entity",
|
||||
"sort_by value {} must be 'asc' or 'desc'".format(
|
||||
sort_by_values[1]))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2014 Hewlett-Packard
|
||||
# Copyright 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -85,11 +85,27 @@ class AlarmDefinitions(alarm_definitions_api_v2.AlarmDefinitionsV2API,
|
|||
tenant_id = helpers.get_tenant_id(req)
|
||||
name = helpers.get_query_name(req)
|
||||
dimensions = helpers.get_query_dimensions(req)
|
||||
sort_by = helpers.get_query_param(req, 'sort_by', default_val=None)
|
||||
if sort_by is not None:
|
||||
if isinstance(sort_by, basestring):
|
||||
sort_by = [sort_by]
|
||||
|
||||
allowed_sort_by = {'id', 'name', 'severity',
|
||||
'updated_at', 'created_at'}
|
||||
|
||||
validation.validate_sort_by(sort_by, allowed_sort_by)
|
||||
|
||||
offset = helpers.get_query_param(req, 'offset')
|
||||
if offset is not None and not isinstance(offset, int):
|
||||
try:
|
||||
offset = int(offset)
|
||||
except Exception:
|
||||
raise HTTPUnprocessableEntityError('Unprocessable Entity',
|
||||
'Offset value {} must be an integer'.format(offset))
|
||||
limit = helpers.get_limit(req)
|
||||
|
||||
result = self._alarm_definition_list(tenant_id, name, dimensions,
|
||||
req.uri, offset, limit)
|
||||
req.uri, sort_by, offset, limit)
|
||||
|
||||
res.body = helpers.dumpit_utf8(result)
|
||||
res.status = falcon.HTTP_200
|
||||
|
@ -203,6 +219,7 @@ class AlarmDefinitions(alarm_definitions_api_v2.AlarmDefinitionsV2API,
|
|||
definitions = self._alarm_definitions_repo.get_alarm_definitions(tenant_id=tenant_id,
|
||||
name=name,
|
||||
dimensions=None,
|
||||
sort_by=None,
|
||||
offset=None,
|
||||
limit=0)
|
||||
if definitions:
|
||||
|
@ -280,12 +297,12 @@ class AlarmDefinitions(alarm_definitions_api_v2.AlarmDefinitionsV2API,
|
|||
alarm_metric_rows, sub_alarm_rows)
|
||||
|
||||
@resource.resource_try_catch_block
|
||||
def _alarm_definition_list(self, tenant_id, name, dimensions, req_uri,
|
||||
def _alarm_definition_list(self, tenant_id, name, dimensions, req_uri, sort_by,
|
||||
offset, limit):
|
||||
|
||||
alarm_definition_rows = (
|
||||
self._alarm_definitions_repo.get_alarm_definitions(tenant_id, name,
|
||||
dimensions,
|
||||
dimensions, sort_by,
|
||||
offset, limit))
|
||||
|
||||
result = []
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2014 Hewlett-Packard
|
||||
# Copyright 2014,2016 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
|
|
@ -23,6 +23,7 @@ from monasca_api.api import alarms_api_v2
|
|||
from monasca_api.common.repositories import exceptions
|
||||
from monasca_api.v2.common.exceptions import HTTPUnprocessableEntityError
|
||||
from monasca_api.v2.common.schemas import alarm_update_schema as schema_alarm
|
||||
from monasca_api.v2.common import validation
|
||||
from monasca_api.v2.reference import alarming
|
||||
from monasca_api.v2.reference import helpers
|
||||
from monasca_api.v2.reference import resource
|
||||
|
@ -116,12 +117,26 @@ class Alarms(alarms_api_v2.AlarmsV2API,
|
|||
|
||||
if alarm_id is None:
|
||||
query_parms = falcon.uri.parse_query_string(req.query_string)
|
||||
if 'sort_by' in query_parms:
|
||||
if isinstance(query_parms['sort_by'], basestring):
|
||||
query_parms['sort_by'] = [query_parms['sort_by']]
|
||||
|
||||
allowed_sort_by = {'alarm_id', 'alarm_definition_id', 'state', 'severity', 'lifecycle_state', 'link',
|
||||
'state_updated_timestamp', 'updated_timestamp', 'created_timestamp'}
|
||||
validation.validate_sort_by(query_parms['sort_by'], allowed_sort_by)
|
||||
|
||||
# ensure metric_dimensions is a list
|
||||
if 'metric_dimensions' in query_parms and isinstance(query_parms['metric_dimensions'], str):
|
||||
query_parms['metric_dimensions'] = query_parms['metric_dimensions'].split(',')
|
||||
|
||||
offset = helpers.get_query_param(req, 'offset')
|
||||
if offset is not None and not isinstance(offset, int):
|
||||
try:
|
||||
offset = int(offset)
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
raise HTTPUnprocessableEntityError("Unprocessable Entity",
|
||||
"Offset value {} must be an integer".format(offset))
|
||||
|
||||
limit = helpers.get_limit(req)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||
# (C) Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -326,6 +326,48 @@ class TestAlarmDefinitions(base.BaseMonascaTest):
|
|||
links = response_body['links']
|
||||
self._verify_list_alarm_definitions_links(links)
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_alarm_definitions_sort_by(self):
|
||||
alarm_definitions = []
|
||||
alarm_definitions.append(helpers.create_alarm_definition(
|
||||
name='alarm def sort by 01',
|
||||
expression='test_metric_01 > 1',
|
||||
severity='HIGH'
|
||||
))
|
||||
alarm_definitions.append(helpers.create_alarm_definition(
|
||||
name='alarm def sort by 04',
|
||||
expression='test_metric_04 > 1',
|
||||
severity='LOW'
|
||||
))
|
||||
alarm_definitions.append(helpers.create_alarm_definition(
|
||||
name='alarm def sort by 02',
|
||||
expression='test_metric_02 > 1',
|
||||
severity='CRITICAL'
|
||||
))
|
||||
alarm_definitions.append(helpers.create_alarm_definition(
|
||||
name='alarm def sort by 03',
|
||||
expression='test_metric_03 > 1',
|
||||
severity='MEDIUM'
|
||||
))
|
||||
for definition in alarm_definitions:
|
||||
self.monasca_client.create_alarm_definitions(definition)
|
||||
|
||||
resp, response_body = self.monasca_client.list_alarm_definitions('?sort_by=severity')
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
prev_severity = 'CRITICAL'
|
||||
for alarm_definition in response_body['elements']:
|
||||
assert prev_severity <= alarm_definition['severity'],\
|
||||
"Severity {} came after {}".format(alarm_definition['severity'], prev_severity)
|
||||
prev_severity = alarm_definition['severity']
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_alarm_definitions_invalid_sort_by(self):
|
||||
query_parms = '?sort_by=random'
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_alarm_definitions, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarm_definitions_with_offset_limit(self):
|
||||
helpers.delete_alarm_definitions(self.monasca_client)
|
||||
|
@ -347,31 +389,15 @@ class TestAlarmDefinitions(base.BaseMonascaTest):
|
|||
self.assertEqual(first_element, elements[0])
|
||||
self.assertEqual(last_element, elements[1])
|
||||
|
||||
timeout = time.time() + 60 * 1 # 1 minute timeout
|
||||
for limit in xrange(1, 3):
|
||||
next_element = elements[limit - 1]
|
||||
while True:
|
||||
if time.time() < timeout:
|
||||
query_parms = '?offset=' + str(next_element['id']) + \
|
||||
'&limit=' + str(limit)
|
||||
resp, response_body = self.monasca_client.\
|
||||
list_alarm_definitions(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
new_elements = response_body['elements']
|
||||
if len(new_elements) > limit - 1:
|
||||
self.assertEqual(limit, len(new_elements))
|
||||
next_element = new_elements[limit - 1]
|
||||
elif 0 < len(new_elements) <= limit - 1:
|
||||
self.assertEqual(last_element, new_elements[0])
|
||||
break
|
||||
else:
|
||||
self.assertEqual(last_element, next_element)
|
||||
break
|
||||
else:
|
||||
msg = "Failed " \
|
||||
"test_list_alarm_definitions_with_offset_limit: " \
|
||||
"one minute timeout"
|
||||
raise exceptions.TimeoutException(msg)
|
||||
for offset in xrange(0, 2):
|
||||
for limit in xrange(1, 3 - offset):
|
||||
query_parms = '?offset=' + str(offset) + '&limit=' + str(limit)
|
||||
resp, response_body = self.monasca_client.list_alarm_definitions(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
new_elements = response_body['elements']
|
||||
self.assertEqual(limit, len(new_elements))
|
||||
self.assertEqual(elements[offset], new_elements[0])
|
||||
self.assertEqual(elements[offset+limit-1], new_elements[-1])
|
||||
|
||||
# Get
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||
# (C) Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -176,21 +176,18 @@ class TestAlarms(base.BaseMonascaTest):
|
|||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_offset_limit(self):
|
||||
helpers.delete_alarm_definitions(self.monasca_client)
|
||||
self._create_alarms_for_test_alarms(num=2)
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
definition_ids, expected_metric = self._create_alarms_for_test_alarms(num=2)
|
||||
resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'])
|
||||
self._verify_list_alarms_elements(resp, response_body,
|
||||
expect_num_elements=2)
|
||||
elements = response_body['elements']
|
||||
first_element = elements[0]
|
||||
next_element = elements[1]
|
||||
id_first_element = first_element['id']
|
||||
query_parms = '?offset=' + str(id_first_element) + '&limit=1'
|
||||
second_element = elements[1]
|
||||
query_parms = '?metric_name=' + expected_metric['name'] + '&offset=1&limit=1'
|
||||
resp, response_body1 = self.monasca_client.list_alarms(query_parms)
|
||||
elements = response_body1['elements']
|
||||
self.assertEqual(1, len(elements))
|
||||
self.assertEqual(elements[0]['id'], next_element['id'])
|
||||
self.assertEqual(elements[0], next_element)
|
||||
self.assertEqual(elements[0]['id'], second_element['id'])
|
||||
self.assertEqual(elements[0], second_element)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_get_alarm(self):
|
||||
|
@ -207,6 +204,66 @@ class TestAlarms(base.BaseMonascaTest):
|
|||
metric = element['metrics'][0]
|
||||
self._verify_metric_in_alarm(metric, expected_metric)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_sort_by(self):
|
||||
alarm_definition_ids, expected_metric = self._create_alarms_for_test_alarms(num=3)
|
||||
resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'])
|
||||
self._verify_list_alarms_elements(resp, response_body,
|
||||
expect_num_elements=3)
|
||||
|
||||
resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'] +
|
||||
'&sort_by=created_timestamp')
|
||||
self._verify_list_alarms_elements(resp, response_body,
|
||||
expect_num_elements=3)
|
||||
|
||||
elements = response_body['elements']
|
||||
last_timestamp = elements[0]['created_timestamp']
|
||||
for element in elements:
|
||||
assert element['state'] >= last_timestamp,\
|
||||
"Created_timestamps are not in sorted order {} came before {}".format(last_timestamp,
|
||||
element['created_timestamp'])
|
||||
last_timestamp = element['created_timestamp']
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_alarms_sort_by_asc_desc(self):
|
||||
alarm_definition_ids, expected_metric = self._create_alarms_for_test_alarms(num=3)
|
||||
resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'])
|
||||
self._verify_list_alarms_elements(resp, response_body,
|
||||
expect_num_elements=3)
|
||||
|
||||
resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'] +
|
||||
'&sort_by=created_timestamp')
|
||||
self._verify_list_alarms_elements(resp, response_body,
|
||||
expect_num_elements=3)
|
||||
|
||||
elements = response_body['elements']
|
||||
last_timestamp = elements[0]['created_timestamp']
|
||||
for element in elements:
|
||||
assert element['state'] >= last_timestamp,\
|
||||
"Created_timestamps are not in ascending order {} came before {}".format(last_timestamp,
|
||||
element['created_timestamp'])
|
||||
last_timestamp = element['created_timestamp']
|
||||
|
||||
resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'] +
|
||||
'&sort_by=created_timestamp')
|
||||
self._verify_list_alarms_elements(resp, response_body,
|
||||
expect_num_elements=3)
|
||||
|
||||
elements = response_body['elements']
|
||||
last_timestamp = elements[0]['created_timestamp']
|
||||
for element in elements:
|
||||
assert element['state'] >= last_timestamp,\
|
||||
"Created_timestamps are not in descending order {} came before {}".format(last_timestamp,
|
||||
element['created_timestamp'])
|
||||
last_timestamp = element['created_timestamp']
|
||||
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_invalid_sort_by(self):
|
||||
query_parms = '?sort_by=not_valid_field'
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_alarms, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_get_alarm_with_invalid_id(self):
|
||||
|
|
Loading…
Reference in New Issue