(Non)deterministic support for alarms
Alarms can be created with deterministic keyword. 'deterministic' can be passed as part of alarm expression using: * keyword deterministic If 'deterministic' is not found in expression it is assumed to be 'false'. Implements: blueprint alarmsonlogs Change-Id: Ia42f9a1be37c31416bdac341b092fe527f860c16
This commit is contained in:
parent
91469d6ebf
commit
b338b78907
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 FUJITSU LIMITED
|
* Copyright 2015-2016 FUJITSU LIMITED
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
* 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
|
* in compliance with the License. You may obtain a copy of the License at
|
||||||
@ -29,6 +29,7 @@ import org.hibernate.annotations.OnDeleteAction;
|
|||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import monasca.common.model.alarm.AlarmOperator;
|
import monasca.common.model.alarm.AlarmOperator;
|
||||||
|
import monasca.common.model.alarm.AlarmSubExpression;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "sub_alarm_definition")
|
@Table(name = "sub_alarm_definition")
|
||||||
@ -81,6 +82,9 @@ public class SubAlarmDefinitionDb
|
|||||||
@Column(name = "periods", length = 11, nullable = false)
|
@Column(name = "periods", length = 11, nullable = false)
|
||||||
private Integer periods;
|
private Integer periods;
|
||||||
|
|
||||||
|
@Column(name = "is_deterministic", length = 1, nullable = false)
|
||||||
|
private boolean deterministic = AlarmSubExpression.DEFAULT_DETERMINISTIC;
|
||||||
|
|
||||||
public SubAlarmDefinitionDb() {
|
public SubAlarmDefinitionDb() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -95,6 +99,21 @@ public class SubAlarmDefinitionDb
|
|||||||
Integer periods,
|
Integer periods,
|
||||||
DateTime created_at,
|
DateTime created_at,
|
||||||
DateTime updated_at) {
|
DateTime updated_at) {
|
||||||
|
this(id, alarmDefinition, function, metricName, operator, threshold, period, periods, created_at,
|
||||||
|
updated_at, AlarmSubExpression.DEFAULT_DETERMINISTIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubAlarmDefinitionDb(String id,
|
||||||
|
AlarmDefinitionDb alarmDefinition,
|
||||||
|
String function,
|
||||||
|
String metricName,
|
||||||
|
String operator,
|
||||||
|
Double threshold,
|
||||||
|
Integer period,
|
||||||
|
Integer periods,
|
||||||
|
DateTime created_at,
|
||||||
|
DateTime updated_at,
|
||||||
|
boolean deterministic) {
|
||||||
super(id, created_at, updated_at);
|
super(id, created_at, updated_at);
|
||||||
this.alarmDefinition = alarmDefinition;
|
this.alarmDefinition = alarmDefinition;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
@ -103,6 +122,7 @@ public class SubAlarmDefinitionDb
|
|||||||
this.threshold = threshold;
|
this.threshold = threshold;
|
||||||
this.period = period;
|
this.period = period;
|
||||||
this.periods = periods;
|
this.periods = periods;
|
||||||
|
this.deterministic = deterministic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubAlarmDefinitionDb setPeriods(final Integer periods) {
|
public SubAlarmDefinitionDb setPeriods(final Integer periods) {
|
||||||
@ -172,6 +192,15 @@ public class SubAlarmDefinitionDb
|
|||||||
return this.periods;
|
return this.periods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeterministic() {
|
||||||
|
return this.deterministic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubAlarmDefinitionDb setDeterministic(final boolean isDeterministic) {
|
||||||
|
this.deterministic = isDeterministic;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public interface Queries {
|
public interface Queries {
|
||||||
String BY_ALARMDEFINITION_ID = "SubAlarmDefinition.byAlarmDefinitionId";
|
String BY_ALARMDEFINITION_ID = "SubAlarmDefinition.byAlarmDefinitionId";
|
||||||
String BY_ALARMDEFINITIONDIMENSION_SUBEXPRESSION_ID = "SubAlarmDefinition.byAlarmDefinitionDimension.subExpressionId";
|
String BY_ALARMDEFINITIONDIMENSION_SUBEXPRESSION_ID = "SubAlarmDefinition.byAlarmDefinitionDimension.subExpressionId";
|
||||||
|
@ -151,7 +151,7 @@ public class AlarmExpression {
|
|||||||
public List<AlarmSubExpression> getSubExpressions() {
|
public List<AlarmSubExpression> getSubExpressions() {
|
||||||
if (subExpressions != null)
|
if (subExpressions != null)
|
||||||
return subExpressions;
|
return subExpressions;
|
||||||
List<AlarmSubExpression> subExpressions = new ArrayList<AlarmSubExpression>();
|
List<AlarmSubExpression> subExpressions = new ArrayList<>(elements.size());
|
||||||
for (Object element : elements)
|
for (Object element : elements)
|
||||||
if (element instanceof AlarmSubExpression)
|
if (element instanceof AlarmSubExpression)
|
||||||
subExpressions.add((AlarmSubExpression) element);
|
subExpressions.add((AlarmSubExpression) element);
|
||||||
@ -159,6 +159,30 @@ public class AlarmExpression {
|
|||||||
return subExpressions;
|
return subExpressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if expression is deterministic or non-deterministic.
|
||||||
|
*
|
||||||
|
* All {@link AlarmSubExpression} must be deterministic in order for entire expression
|
||||||
|
* to be such. Otherwise expression is non-deterministic.
|
||||||
|
*
|
||||||
|
* @return true/false
|
||||||
|
*
|
||||||
|
* @see #getSubExpressions()
|
||||||
|
* @see AlarmSubExpression#DEFAULT_DETERMINISTIC
|
||||||
|
*/
|
||||||
|
public boolean isDeterministic() {
|
||||||
|
final List<AlarmSubExpression> subExpressions = this.getSubExpressions();
|
||||||
|
if (subExpressions == null || subExpressions.isEmpty()) {
|
||||||
|
return AlarmSubExpression.DEFAULT_DETERMINISTIC;
|
||||||
|
}
|
||||||
|
for (final AlarmSubExpression alarmSubExpression : subExpressions) {
|
||||||
|
if (!alarmSubExpression.isDeterministic()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
* Copyright 2016 FUJITSU LIMITED
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -21,17 +22,13 @@ import java.text.DecimalFormat;
|
|||||||
import java.text.DecimalFormatSymbols;
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||||
import org.antlr.v4.runtime.CommonTokenStream;
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
import org.antlr.v4.runtime.ParserRuleContext;
|
import org.antlr.v4.runtime.ParserRuleContext;
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
|
|
||||||
import monasca.common.model.alarm.AlarmExpressionLexer;
|
|
||||||
import monasca.common.model.alarm.AlarmExpressionParser;
|
|
||||||
import monasca.common.model.metric.MetricDefinition;
|
import monasca.common.model.metric.MetricDefinition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +38,7 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
private static final long serialVersionUID = -7458129503846747592L;
|
private static final long serialVersionUID = -7458129503846747592L;
|
||||||
public static final int DEFAULT_PERIOD = 60;
|
public static final int DEFAULT_PERIOD = 60;
|
||||||
public static final int DEFAULT_PERIODS = 1;
|
public static final int DEFAULT_PERIODS = 1;
|
||||||
|
public static final boolean DEFAULT_DETERMINISTIC = false;
|
||||||
|
|
||||||
private AggregateFunction function;
|
private AggregateFunction function;
|
||||||
private MetricDefinition metricDefinition;
|
private MetricDefinition metricDefinition;
|
||||||
@ -48,6 +46,8 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
private double threshold;
|
private double threshold;
|
||||||
private int period;
|
private int period;
|
||||||
private int periods;
|
private int periods;
|
||||||
|
private boolean deterministic = DEFAULT_DETERMINISTIC;
|
||||||
|
|
||||||
// Use a DecimalFormatter for threshold because the standard double format starts using scientific notation when
|
// Use a DecimalFormatter for threshold because the standard double format starts using scientific notation when
|
||||||
// threshold is very large and that scientific notation can't be parsed when recreating the SubExpression
|
// threshold is very large and that scientific notation can't be parsed when recreating the SubExpression
|
||||||
private static final DecimalFormat formatter;
|
private static final DecimalFormat formatter;
|
||||||
@ -57,14 +57,29 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
formatter.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US));
|
formatter.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlarmSubExpression(AggregateFunction function, MetricDefinition metricDefinition,
|
public AlarmSubExpression(AggregateFunction function,
|
||||||
AlarmOperator operator, double threshold, int period, int periods) {
|
MetricDefinition metricDefinition,
|
||||||
|
AlarmOperator operator,
|
||||||
|
double threshold,
|
||||||
|
int period,
|
||||||
|
int periods) {
|
||||||
|
this(function, metricDefinition, operator, threshold, period, periods, DEFAULT_DETERMINISTIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AlarmSubExpression(AggregateFunction function,
|
||||||
|
MetricDefinition metricDefinition,
|
||||||
|
AlarmOperator operator,
|
||||||
|
double threshold,
|
||||||
|
int period,
|
||||||
|
int periods,
|
||||||
|
boolean deterministic) {
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.metricDefinition = metricDefinition;
|
this.metricDefinition = metricDefinition;
|
||||||
this.operator = operator;
|
this.operator = operator;
|
||||||
this.threshold = threshold;
|
this.threshold = threshold;
|
||||||
this.period = period;
|
this.period = period;
|
||||||
this.periods = periods;
|
this.periods = periods;
|
||||||
|
this.deterministic = deterministic;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlarmSubExpression() {
|
AlarmSubExpression() {
|
||||||
@ -111,6 +126,8 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
return false;
|
return false;
|
||||||
if (periods != other.periods)
|
if (periods != other.periods)
|
||||||
return false;
|
return false;
|
||||||
|
if (deterministic != other.deterministic)
|
||||||
|
return false;
|
||||||
if (Double.doubleToLongBits(threshold) != Double.doubleToLongBits(other.threshold))
|
if (Double.doubleToLongBits(threshold) != Double.doubleToLongBits(other.threshold))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -130,8 +147,12 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
public String getExpression() {
|
public String getExpression() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(function).append('(').append(metricDefinition.toExpression());
|
sb.append(function).append('(').append(metricDefinition.toExpression());
|
||||||
if (period != 60)
|
if (this.isDeterministic()) {
|
||||||
|
sb.append(", deterministic"); // present only non-default value
|
||||||
|
}
|
||||||
|
if (period != 60) {
|
||||||
sb.append(", ").append(period);
|
sb.append(", ").append(period);
|
||||||
|
}
|
||||||
sb.append(") ").append(operator).append(' ').append(formatter.format(threshold));
|
sb.append(") ").append(operator).append(' ').append(formatter.format(threshold));
|
||||||
if (periods != 1)
|
if (periods != 1)
|
||||||
sb.append(" times ").append(periods);
|
sb.append(" times ").append(periods);
|
||||||
@ -162,6 +183,10 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
return threshold;
|
return threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeterministic() {
|
||||||
|
return this.deterministic;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
@ -171,6 +196,7 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
result = prime * result + ((operator == null) ? 0 : operator.hashCode());
|
result = prime * result + ((operator == null) ? 0 : operator.hashCode());
|
||||||
result = prime * result + period;
|
result = prime * result + period;
|
||||||
result = prime * result + periods;
|
result = prime * result + periods;
|
||||||
|
result = prime * result + Boolean.valueOf(this.deterministic).hashCode();
|
||||||
long temp;
|
long temp;
|
||||||
temp = Double.doubleToLongBits(threshold);
|
temp = Double.doubleToLongBits(threshold);
|
||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
@ -201,6 +227,10 @@ public class AlarmSubExpression implements Serializable {
|
|||||||
this.threshold = threshold;
|
this.threshold = threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDeterministic(final boolean deterministic) {
|
||||||
|
this.deterministic = deterministic;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getExpression();
|
return getExpression();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
* Copyright 2016 FUJITSU LIMITED
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -27,6 +28,7 @@ import monasca.common.model.metric.MetricDefinition;
|
|||||||
* Complex alarm parser lister for sub expression extraction.
|
* Complex alarm parser lister for sub expression extraction.
|
||||||
*/
|
*/
|
||||||
class AlarmSubExpressionListener extends AlarmExpressionBaseListener {
|
class AlarmSubExpressionListener extends AlarmExpressionBaseListener {
|
||||||
|
|
||||||
private final boolean simpleExpression;
|
private final boolean simpleExpression;
|
||||||
private AggregateFunction function;
|
private AggregateFunction function;
|
||||||
private String namespace;
|
private String namespace;
|
||||||
@ -36,23 +38,36 @@ class AlarmSubExpressionListener extends AlarmExpressionBaseListener {
|
|||||||
private int period = AlarmSubExpression.DEFAULT_PERIOD;
|
private int period = AlarmSubExpression.DEFAULT_PERIOD;
|
||||||
private int periods = AlarmSubExpression.DEFAULT_PERIODS;
|
private int periods = AlarmSubExpression.DEFAULT_PERIODS;
|
||||||
private List<Object> elements = new ArrayList<Object>();
|
private List<Object> elements = new ArrayList<Object>();
|
||||||
|
private boolean deterministic = AlarmSubExpression.DEFAULT_DETERMINISTIC;
|
||||||
|
|
||||||
AlarmSubExpressionListener(boolean simpleExpression) {
|
AlarmSubExpressionListener(boolean simpleExpression) {
|
||||||
this.simpleExpression = simpleExpression;
|
this.simpleExpression = simpleExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveSubExpression() {
|
private void saveSubExpression() {
|
||||||
AlarmSubExpression subExpression = new AlarmSubExpression(function, new MetricDefinition(
|
// not possible to establish if metric is sporadic from expression, so we go with default
|
||||||
namespace, dimensions), operator, threshold, period, periods);
|
final MetricDefinition metricDefinition = new MetricDefinition(
|
||||||
|
namespace,
|
||||||
|
dimensions
|
||||||
|
);
|
||||||
|
final AlarmSubExpression subExpression = new AlarmSubExpression(function,
|
||||||
|
metricDefinition,
|
||||||
|
operator,
|
||||||
|
threshold,
|
||||||
|
period,
|
||||||
|
periods,
|
||||||
|
deterministic
|
||||||
|
);
|
||||||
elements.add(subExpression);
|
elements.add(subExpression);
|
||||||
|
|
||||||
function = null;
|
function = null;
|
||||||
namespace = null;
|
namespace = null;
|
||||||
dimensions = new TreeMap<String, String>();
|
dimensions = new TreeMap<>();
|
||||||
operator = null;
|
operator = null;
|
||||||
threshold = 0;
|
threshold = 0;
|
||||||
period = AlarmSubExpression.DEFAULT_PERIOD;
|
period = AlarmSubExpression.DEFAULT_PERIOD;
|
||||||
periods = AlarmSubExpression.DEFAULT_PERIODS;
|
periods = AlarmSubExpression.DEFAULT_PERIODS;
|
||||||
|
deterministic = AlarmSubExpression.DEFAULT_DETERMINISTIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -155,6 +170,11 @@ class AlarmSubExpressionListener extends AlarmExpressionBaseListener {
|
|||||||
elements.add(BooleanOperator.AND);
|
elements.add(BooleanOperator.AND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterDeterministic(final AlarmExpressionParser.DeterministicContext ctx) {
|
||||||
|
this.deterministic = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the operator and operand elements of the expression in postfix order. Elements will be
|
* Returns the operator and operand elements of the expression in postfix order. Elements will be
|
||||||
* of types AlarmSubExpression and BooleanOperator.
|
* of types AlarmSubExpression and BooleanOperator.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
* Copyright 2016 FUJITSU LIMITED
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -31,7 +32,7 @@ expression
|
|||||||
|
|
||||||
|
|
||||||
function
|
function
|
||||||
: functionType '(' compoundIdentifier (',' period)? ')'
|
: functionType '(' compoundIdentifier (',' deterministic)? (',' period)? ')'
|
||||||
;
|
;
|
||||||
|
|
||||||
relational_operator
|
relational_operator
|
||||||
@ -118,6 +119,10 @@ period
|
|||||||
: INTEGER
|
: INTEGER
|
||||||
;
|
;
|
||||||
|
|
||||||
|
deterministic
|
||||||
|
: 'deterministic'
|
||||||
|
;
|
||||||
|
|
||||||
literal
|
literal
|
||||||
: DECIMAL
|
: DECIMAL
|
||||||
| INTEGER
|
| INTEGER
|
||||||
@ -133,6 +138,7 @@ txt
|
|||||||
| INTEGER
|
| INTEGER
|
||||||
| STRING
|
| STRING
|
||||||
;
|
;
|
||||||
|
|
||||||
LT
|
LT
|
||||||
: [lL][tT]
|
: [lL][tT]
|
||||||
;
|
;
|
||||||
@ -226,4 +232,4 @@ WS : [ \t\r\n]+ -> skip ;
|
|||||||
|
|
||||||
FALL_THROUGH
|
FALL_THROUGH
|
||||||
: . {if(true) {throw new IllegalArgumentException("IllegalCharacter: " + getText());}}
|
: . {if(true) {throw new IllegalArgumentException("IllegalCharacter: " + getText());}}
|
||||||
;
|
;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
* Copyright 2016 FUJITSU LIMITED
|
||||||
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
* 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
|
* in compliance with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
* 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
|
* 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
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
@ -19,11 +20,14 @@ import static org.testng.Assert.assertNotEquals;
|
|||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
import static org.testng.Assert.fail;
|
import static org.testng.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import com.beust.jcommander.internal.Maps;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import monasca.common.model.metric.MetricDefinition;
|
import monasca.common.model.metric.MetricDefinition;
|
||||||
|
|
||||||
@ -315,4 +319,60 @@ public class AlarmExpressionTest {
|
|||||||
+ "(min(ເຮືອນ{dn3=dv3,家=дом}) < 10 or sum(biz{dn5=dv5}) >9 and "
|
+ "(min(ເຮືອນ{dn3=dv3,家=дом}) < 10 or sum(biz{dn5=dv5}) >9 and "
|
||||||
+ "count(fizzle) lt 0 or count(baz) > 1)");
|
+ "count(fizzle) lt 0 or count(baz) > 1)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void shouldParseDeterministicExpression() {
|
||||||
|
final Map<String, String> dimensions = Maps.newHashMap();
|
||||||
|
final ArrayList<AlarmExpression> expressions = Lists.newArrayList(
|
||||||
|
new AlarmExpression("count(log.error{},deterministic,20) > 5")
|
||||||
|
);
|
||||||
|
final MetricDefinition metricDefinition = new MetricDefinition("log.error", dimensions);
|
||||||
|
|
||||||
|
final AlarmSubExpression logErrorExpr = new AlarmSubExpression(
|
||||||
|
AggregateFunction.COUNT,
|
||||||
|
metricDefinition,
|
||||||
|
AlarmOperator.GT,
|
||||||
|
5,
|
||||||
|
20,
|
||||||
|
1,
|
||||||
|
true // each expression is deterministic
|
||||||
|
);
|
||||||
|
|
||||||
|
for (final AlarmExpression expr : expressions) {
|
||||||
|
final List<AlarmSubExpression> subExpressions = expr.getSubExpressions();
|
||||||
|
|
||||||
|
assertTrue(expr.isDeterministic()); // each expression is deterministic
|
||||||
|
assertEquals(1, subExpressions.size());
|
||||||
|
assertEquals(subExpressions.get(0), logErrorExpr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void shouldNotParseInvalidExpressionWrongRightOperand() {
|
||||||
|
AlarmExpression.of("count(log.error{},deterministic=foo,20) > 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void shouldNotParseInvalidExpressionMalformedDeterministicKeyword() {
|
||||||
|
AlarmExpression.of("count(log.error{},determ=true,20) > 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shouldBeDeterministicIfAllSubExpressionAreDeterministic() {
|
||||||
|
final String expression1 = "count(log.error{hostname=1,component=A},deterministic,20) > 5";
|
||||||
|
final String expression2 = "count(log.error{hostname=1,component=B},deterministic,20) > 10";
|
||||||
|
final String expression3 = "count(log.error{hostname=1,component=C},deterministic,20) > 15";
|
||||||
|
|
||||||
|
final String expression = String.format("%s OR %s OR %s", expression1, expression2, expression3);
|
||||||
|
|
||||||
|
assertTrue(new AlarmExpression(expression).isDeterministic());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shouldBeNonDeterministicIfAtLeastOneExpressionIsNonDeterministic() {
|
||||||
|
final String expression1 = "count(log.error{hostname=1,component=A},deterministic,20) > 5";
|
||||||
|
final String expression2 = "count(log.error{hostname=1,component=B},deterministic,20) > 10";
|
||||||
|
final String expression3 = "count(log.error{}) > 15";
|
||||||
|
|
||||||
|
final String expression = String.format("%s OR %s OR %s", expression1, expression2, expression3);
|
||||||
|
|
||||||
|
assertFalse(new AlarmExpression(expression).isDeterministic());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||||
*
|
* Copyright 2016 FUJITSU LIMITED
|
||||||
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
* 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
|
* in compliance with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
* 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
|
* 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
|
* or implied. See the License for the specific language governing permissions and limitations under
|
||||||
@ -17,13 +18,9 @@ import static org.testng.Assert.assertEquals;
|
|||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import monasca.common.model.alarm.AggregateFunction;
|
|
||||||
import monasca.common.model.alarm.AlarmExpression;
|
|
||||||
import monasca.common.model.alarm.AlarmOperator;
|
|
||||||
import monasca.common.model.alarm.AlarmSubExpression;
|
|
||||||
import monasca.common.model.metric.MetricDefinition;
|
import monasca.common.model.metric.MetricDefinition;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -172,4 +169,18 @@ public class AlarmSubExpressionTest {
|
|||||||
public void shouldAllowDecimalThresholds() {
|
public void shouldAllowDecimalThresholds() {
|
||||||
assertEquals(AlarmSubExpression.of("avg(hpcs.compute) > 2.375").getThreshold(), 2.375);
|
assertEquals(AlarmSubExpression.of("avg(hpcs.compute) > 2.375").getThreshold(), 2.375);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void shouldBeNonDeterministicByDefault() {
|
||||||
|
assertFalse(AlarmSubExpression.of("count(log.error{}) > 1.0").isDeterministic());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shouldBeDeterministicIfSet() {
|
||||||
|
assertTrue(AlarmSubExpression.of("count(log.error{}, deterministic) > 1.0").isDeterministic());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void shouldFailWithMalformedDeterministicKeyword() {
|
||||||
|
AlarmSubExpression.of("count(log.error{}, deterministici) > 1.0");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user