@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.query.BooleanFilterPredicate;
import org.thingsboard.server.common.data.query.ComplexFilterPredicate ;
import org.thingsboard.server.common.data.query.EntityKey ;
import org.thingsboard.server.common.data.query.EntityKeyType ;
import org.thingsboard.server.common.data.query.FilterPredicateValue ;
import org.thingsboard.server.common.data.query.KeyFilter ;
import org.thingsboard.server.common.data.query.KeyFilterPredicate ;
import org.thingsboard.server.common.data.query.NumericFilterPredicate ;
@ -41,6 +42,7 @@ import java.time.Instant;
import java.time.ZoneId ;
import java.time.ZonedDateTime ;
import java.util.Set ;
import java.util.function.Function ;
@Data
class AlarmRuleState {
@ -246,38 +248,38 @@ class AlarmRuleState {
if ( value = = null ) {
return false ;
}
eval = eval & & eval ( value , keyFilter . getPredicate ( ) ) ;
eval = eval & & eval ( data , value , keyFilter . getPredicate ( ) ) ;
}
return eval ;
}
private boolean eval ( EntityKeyValue value , KeyFilterPredicate predicate ) {
private boolean eval ( DataSnapshot data , EntityKeyValue value , KeyFilterPredicate predicate ) {
switch ( predicate . getType ( ) ) {
case STRING :
return evalStrPredicate ( value , ( StringFilterPredicate ) predicate ) ;
return evalStrPredicate ( data , value , ( StringFilterPredicate ) predicate ) ;
case NUMERIC :
return evalNumPredicate ( value , ( NumericFilterPredicate ) predicate ) ;
case COMPLEX :
return evalComplexPredicate ( value , ( ComplexFilterPredicate ) predicate ) ;
return evalNumPredicate ( data , value , ( NumericFilterPredicate ) predicate ) ;
case BOOLEAN :
return evalBoolPredicate ( value , ( BooleanFilterPredicate ) predicate ) ;
return evalBoolPredicate ( data , value , ( BooleanFilterPredicate ) predicate ) ;
case COMPLEX :
return evalComplexPredicate ( data , value , ( ComplexFilterPredicate ) predicate ) ;
default :
return false ;
}
}
private boolean evalComplexPredicate ( EntityKeyValue ekv , ComplexFilterPredicate predicate ) {
private boolean evalComplexPredicate ( DataSnapshot data , EntityKeyValue ekv , ComplexFilterPredicate predicate ) {
switch ( predicate . getOperation ( ) ) {
case OR :
for ( KeyFilterPredicate kfp : predicate . getPredicates ( ) ) {
if ( eval ( ekv , kfp ) ) {
if ( eval ( data , ekv , kfp ) ) {
return true ;
}
}
return false ;
case AND :
for ( KeyFilterPredicate kfp : predicate . getPredicates ( ) ) {
if ( ! eval ( ekv , kfp ) ) {
if ( ! eval ( data , ekv , kfp ) ) {
return false ;
}
}
@ -287,109 +289,55 @@ class AlarmRuleState {
}
}
private boolean evalBoolPredicate ( EntityKeyValue ekv , BooleanFilterPredicate predicate ) {
Boolean value ;
switch ( ekv . getDataType ( ) ) {
case LONG :
value = ekv . getLngValue ( ) > 0 ;
break ;
case DOUBLE :
value = ekv . getDblValue ( ) > 0 ;
break ;
case BOOLEAN :
value = ekv . getBoolValue ( ) ;
break ;
case STRING :
try {
value = Boolean . parseBoolean ( ekv . getStrValue ( ) ) ;
break ;
} catch ( RuntimeException e ) {
return false ;
}
case JSON :
try {
value = Boolean . parseBoolean ( ekv . getJsonValue ( ) ) ;
break ;
} catch ( RuntimeException e ) {
return false ;
}
default :
return false ;
}
if ( value = = null ) {
private boolean evalBoolPredicate ( DataSnapshot data , EntityKeyValue ekv , BooleanFilterPredicate predicate ) {
Boolean val = getBoolValue ( ekv ) ;
if ( val = = null ) {
return false ;
}
Boolean predicateValue = getPredicateValue ( data , predicate . getValue ( ) , AlarmRuleState : : getBoolValue ) ;
switch ( predicate . getOperation ( ) ) {
case EQUAL :
return value . equals ( predicate . get Value( ) . getDefaultValue ( ) ) ;
return val . equals ( predicateValue ) ;
case NOT_EQUAL :
return ! value . equals ( predicate . get Value( ) . getDefaultValue ( ) ) ;
return ! val . equals ( predicateValue ) ;
default :
throw new RuntimeException ( "Operation not supported: " + predicate . getOperation ( ) ) ;
}
}
private boolean evalNumPredicate ( EntityKeyValue ekv , NumericFilterPredicate predicate ) {
Double value ;
switch ( ekv . getDataType ( ) ) {
case LONG :
value = ekv . getLngValue ( ) . doubleValue ( ) ;
break ;
case DOUBLE :
value = ekv . getDblValue ( ) ;
break ;
case BOOLEAN :
value = ekv . getBoolValue ( ) ? 1 . 0 : 0 . 0 ;
break ;
case STRING :
try {
value = Double . parseDouble ( ekv . getStrValue ( ) ) ;
break ;
} catch ( RuntimeException e ) {
return false ;
}
case JSON :
try {
value = Double . parseDouble ( ekv . getJsonValue ( ) ) ;
break ;
} catch ( RuntimeException e ) {
return false ;
}
default :
return false ;
}
if ( value = = null ) {
private boolean evalNumPredicate ( DataSnapshot data , EntityKeyValue ekv , NumericFilterPredicate predicate ) {
Double val = getDblValue ( ekv ) ;
if ( val = = null ) {
return false ;
}
Double predicateValue = predicate . getValue ( ) . getDefaultValue ( ) ;
Double predicateValue = getPredicateValue ( data , predicate . getValue ( ) , AlarmRuleState : : getDblValue ) ;
switch ( predicate . getOperation ( ) ) {
case NOT_EQUAL :
return ! value . equals ( predicateValue ) ;
return ! val . equals ( predicateValue ) ;
case EQUAL :
return value . equals ( predicateValue ) ;
return val . equals ( predicateValue ) ;
case GREATER :
return value > predicateValue ;
return val > predicateValue ;
case GREATER_OR_EQUAL :
return value > = predicateValue ;
return val > = predicateValue ;
case LESS :
return value < predicateValue ;
return val < predicateValue ;
case LESS_OR_EQUAL :
return value < = predicateValue ;
return val < = predicateValue ;
default :
throw new RuntimeException ( "Operation not supported: " + predicate . getOperation ( ) ) ;
}
}
private boolean evalStrPredicate ( EntityKeyValue ekv , StringFilterPredicate predicate ) {
String val ;
String predicateValue ;
private boolean evalStrPredicate ( DataSnapshot data , EntityKeyValue ekv , StringFilterPredicate predicate ) {
String val = getStrValue ( ekv ) ;
if ( val = = null ) {
return false ;
}
String predicateValue = getPredicateValue ( data , predicate . getValue ( ) , AlarmRuleState : : getStrValue ) ;
if ( predicate . isIgnoreCase ( ) ) {
val = ekv . getStrValue ( ) . toLowerCase ( ) ;
predicateValue = predicate . getValue ( ) . getDefaultValue ( ) . toLowerCase ( ) ;
} else {
val = ekv . getStrValue ( ) ;
predicateValue = predicate . getValue ( ) . getDefaultValue ( ) ;
val = val . toLowerCase ( ) ;
predicateValue = predicateValue . toLowerCase ( ) ;
}
switch ( predicate . getOperation ( ) ) {
case CONTAINS :
@ -409,4 +357,99 @@ class AlarmRuleState {
}
}
private < T > T getPredicateValue ( DataSnapshot data , FilterPredicateValue < T > value , Function < EntityKeyValue , T > transformFunction ) {
EntityKeyValue ekv = getDynamicPredicateValue ( data , value ) ;
if ( ekv ! = null ) {
T result = transformFunction . apply ( ekv ) ;
if ( result ! = null ) {
return result ;
}
}
return value . getDefaultValue ( ) ;
}
private < T > EntityKeyValue getDynamicPredicateValue ( DataSnapshot data , FilterPredicateValue < T > value ) {
EntityKeyValue ekv = null ;
if ( value . getDynamicValue ( ) ! = null ) {
ekv = data . getValue ( new EntityKey ( EntityKeyType . ATTRIBUTE , value . getDynamicValue ( ) . getSourceAttribute ( ) ) ) ;
if ( ekv = = null ) {
ekv = data . getValue ( new EntityKey ( EntityKeyType . SERVER_ATTRIBUTE , value . getDynamicValue ( ) . getSourceAttribute ( ) ) ) ;
if ( ekv = = null ) {
ekv = data . getValue ( new EntityKey ( EntityKeyType . SHARED_ATTRIBUTE , value . getDynamicValue ( ) . getSourceAttribute ( ) ) ) ;
if ( ekv = = null ) {
ekv = data . getValue ( new EntityKey ( EntityKeyType . CLIENT_ATTRIBUTE , value . getDynamicValue ( ) . getSourceAttribute ( ) ) ) ;
}
}
}
}
return ekv ;
}
private static String getStrValue ( EntityKeyValue ekv ) {
switch ( ekv . getDataType ( ) ) {
case LONG :
return ekv . getLngValue ( ) ! = null ? ekv . getLngValue ( ) . toString ( ) : null ;
case DOUBLE :
return ekv . getDblValue ( ) ! = null ? ekv . getDblValue ( ) . toString ( ) : null ;
case BOOLEAN :
return ekv . getBoolValue ( ) ! = null ? ekv . getBoolValue ( ) . toString ( ) : null ;
case STRING :
return ekv . getStrValue ( ) ;
case JSON :
return ekv . getJsonValue ( ) ;
default :
return null ;
}
}
private static Double getDblValue ( EntityKeyValue ekv ) {
switch ( ekv . getDataType ( ) ) {
case LONG :
return ekv . getLngValue ( ) ! = null ? ekv . getLngValue ( ) . doubleValue ( ) : null ;
case DOUBLE :
return ekv . getDblValue ( ) ! = null ? ekv . getDblValue ( ) : null ;
case BOOLEAN :
return ekv . getBoolValue ( ) ! = null ? ( ekv . getBoolValue ( ) ? 1 . 0 : 0 . 0 ) : null ;
case STRING :
try {
return Double . parseDouble ( ekv . getStrValue ( ) ) ;
} catch ( RuntimeException e ) {
return null ;
}
case JSON :
try {
return Double . parseDouble ( ekv . getJsonValue ( ) ) ;
} catch ( RuntimeException e ) {
return null ;
}
default :
return null ;
}
}
private static Boolean getBoolValue ( EntityKeyValue ekv ) {
switch ( ekv . getDataType ( ) ) {
case LONG :
return ekv . getLngValue ( ) ! = null ? ekv . getLngValue ( ) > 0 : null ;
case DOUBLE :
return ekv . getDblValue ( ) ! = null ? ekv . getDblValue ( ) > 0 : null ;
case BOOLEAN :
return ekv . getBoolValue ( ) ;
case STRING :
try {
return Boolean . parseBoolean ( ekv . getStrValue ( ) ) ;
} catch ( RuntimeException e ) {
return null ;
}
case JSON :
try {
return Boolean . parseBoolean ( ekv . getJsonValue ( ) ) ;
} catch ( RuntimeException e ) {
return null ;
}
default :
return null ;
}
}
}