NIFI-6792

added a function in Expression Language to
Evaluate Variable value containing expression Language
NIFI-6792
Build related changes
added license to newly added class StringElEvaluator.java
restyled the classes having maven-checkstyle related issues
NIFI-6792
made changes suggested by reviewer MikeThomsen

Expression Language function name changed from stringEL to evaluateELString

This closes #3829

Signed-off-by: Mike Thomsen <mthomsen@apache.org>
This commit is contained in:
Manoj Mamidyala 2019-10-20 19:25:21 +05:30 committed by Mike Thomsen
parent 0b3a60ae3e
commit 6864f3eb25
No known key found for this signature in database
GPG Key ID: 88511C3D4CAD246F
6 changed files with 90 additions and 1 deletions

View File

@ -142,6 +142,7 @@ UNESCAPE_HTML4 : 'unescapeHtml4';
BASE64_ENCODE : 'base64Encode';
BASE64_DECODE : 'base64Decode';
GET_STATE_VALUE: 'getStateValue';
EVALUATE_EL_STRING: 'evaluateELString';
// 1 arg functions
SUBSTRING_AFTER : 'substringAfter';

View File

@ -74,7 +74,7 @@ tokens {
}
// functions that return Strings
zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECODE | BASE64_ENCODE | BASE64_DECODE | ESCAPE_JSON | ESCAPE_XML | ESCAPE_CSV | ESCAPE_HTML3 | ESCAPE_HTML4 | UNESCAPE_JSON | UNESCAPE_XML | UNESCAPE_CSV | UNESCAPE_HTML3 | UNESCAPE_HTML4 ) LPAREN! RPAREN!;
zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_DECODE | BASE64_ENCODE | BASE64_DECODE | ESCAPE_JSON | ESCAPE_XML | ESCAPE_CSV | ESCAPE_HTML3 | ESCAPE_HTML4 | UNESCAPE_JSON | UNESCAPE_XML | UNESCAPE_CSV | UNESCAPE_HTML3 | UNESCAPE_HTML4 | EVALUATE_EL_STRING) LPAREN! RPAREN!;
oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY |
PREPEND | APPEND | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH | JSON_PATH_DELETE | FROM_RADIX) LPAREN! anyArg RPAREN!) |
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);

View File

@ -106,6 +106,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.ToLowe
import org.apache.nifi.attribute.expression.language.evaluation.functions.ToRadixEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.ToStringEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.ToUpperEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.EvaluateELStringEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.TrimEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlDecodeEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlEncodeEvaluator;
@ -239,6 +240,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_ENCODE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.WHOLE_NUMBER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EVALUATE_EL_STRING;
public class ExpressionCompiler {
private final Set<Evaluator<?>> evaluators = new HashSet<>();
@ -567,6 +569,10 @@ public class ExpressionCompiler {
verifyArgCount(argEvaluators, 0, "toUpper");
return addToken(new ToUpperEvaluator(toStringEvaluator(subjectEvaluator)), "toUpper");
}
case EVALUATE_EL_STRING: {
verifyArgCount(argEvaluators, 0, "evaluateELString");
return addToken(new EvaluateELStringEvaluator(toStringEvaluator(subjectEvaluator)), "evaluateELString");
}
case URL_ENCODE: {
verifyArgCount(argEvaluators, 0, "urlEncode");
return addToken(new UrlEncodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlEncode");

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.attribute.expression.language.evaluation.functions;
import org.apache.nifi.attribute.expression.language.EvaluationContext;
import org.apache.nifi.attribute.expression.language.Query;
import org.apache.nifi.attribute.expression.language.StandardPreparedQuery;
import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResult;
public class EvaluateELStringEvaluator extends StringEvaluator {
private final Evaluator<String> subject;
public EvaluateELStringEvaluator(final Evaluator<String> subject) {
this.subject = subject;
}
@Override
public QueryResult<String> evaluate(EvaluationContext evaluationContext) {
final String subjectValue = subject.evaluate(evaluationContext).getValue();
final String evaluated = ((StandardPreparedQuery) Query.prepare(subjectValue)).evaluateExpressions(evaluationContext, null);
return new StringQueryResult(evaluated);
}
@Override
public Evaluator<?> getSubjectEvaluator() {
return subject;
}
}

View File

@ -157,6 +157,25 @@ public class TestQuery {
+ ":or( ${filename:startsWith('KYM3ABC')} )}", false);
}
@Test
public void testStringEL() {
final Map<String, String> attrs = new HashMap<>();
attrs.put("employee.gender", "male ");
attrs.put("employee.name", "Harry Potter");
attrs.put("id", "1234");
attrs.put("sql.query", "SELECT * FROM table WHERE ID = ${id}");
String query = "${sql.query:evaluateELString()}";
String query1 = "${employee.name:evaluateELString()}";
String query2 = "${employee.name:evaluateELString():toUpper()}";
String query3 = "${employee.gender:trim():evaluateELString()}";
verifyEquals(query, attrs, "SELECT * FROM table WHERE ID = 1234");
verifyEquals(query1, attrs, "Harry Potter");
verifyEquals(query2, attrs, "HARRY POTTER");
verifyEquals(query3, attrs, "male");
}
@Test
public void testCompileEmbedded() {
final String expression = "${x:equals( ${y} )}";

View File

@ -1107,6 +1107,22 @@ Expressions will provide the following results:
will return 0.
[.function]
=== evaluateELString
*Description*: [.description]#This function evaluates the Expression Language inside the variable value.#
*Subject Type*: [.subject]#String#
*Arguments*: No arguments
*Return Type*: [.returnType]#String#
*Examples*: If one of the registry variable named "query" has value "SELECT * FROM TABLE WHERE ID = ${id}"
and the value of the "id" field, we are getting from the flowfile attributes (i.e. id=20)
then the Expression `${query:evaluateELString()}` will return SELECT * FROM TABLE WHERE ID = 20
[[encode]]
== Encode/Decode Functions