From aa48caacac303b6d418796e3025f9756fc7f0458 Mon Sep 17 00:00:00 2001 From: Pierre Villard Date: Tue, 4 Dec 2018 22:28:33 +0100 Subject: [PATCH 1/2] NIFI-5867 - add thread() EL function to get thread name --- .../language/antlr/AttributeExpressionLexer.g | 1 + .../antlr/AttributeExpressionParser.g | 2 +- .../language/compile/ExpressionCompiler.java | 4 ++ .../evaluation/functions/ThreadEvaluator.java | 45 +++++++++++++++++++ .../expression/language/TestQuery.java | 5 +++ .../asciidoc/expression-language-guide.adoc | 18 ++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java diff --git a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g index 6c0bcff19a4f..637327c4961c 100644 --- a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g +++ b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g @@ -107,6 +107,7 @@ IP : 'ip'; UUID : 'UUID'; HOSTNAME : 'hostname'; // requires boolean arg: prefer FQDN NOW : 'now'; +THREAD : 'thread'; // 0 arg functions diff --git a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g index 4d48ee093f28..0c63c553ce0c 100644 --- a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g +++ b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g @@ -128,7 +128,7 @@ functionCall : functionRef -> ^(FUNCTION_CALL functionRef); booleanLiteral : TRUE | FALSE; -zeroArgStandaloneFunction : (IP | UUID | NOW | NEXT_INT | HOSTNAME | RANDOM) LPAREN! RPAREN!; +zeroArgStandaloneFunction : (IP | UUID | NOW | NEXT_INT | HOSTNAME | THREAD | RANDOM) LPAREN! RPAREN!; oneArgStandaloneFunction : ((TO_LITERAL | MATH | GET_STATE_VALUE)^ LPAREN! anyArg RPAREN!) | (HOSTNAME^ LPAREN! booleanLiteral RPAREN!); standaloneFunction : zeroArgStandaloneFunction | oneArgStandaloneFunction; diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/compile/ExpressionCompiler.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/compile/ExpressionCompiler.java index 4a4a20407460..de4333c17990 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/compile/ExpressionCompiler.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/compile/ExpressionCompiler.java @@ -91,6 +91,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.SubstringBeforeEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.SubstringBeforeLastEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.SubstringEvaluator; +import org.apache.nifi.attribute.expression.language.evaluation.functions.ThreadEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.ToLowerEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.ToRadixEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.functions.ToStringEvaluator; @@ -199,6 +200,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_AFTER_LAST; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_BEFORE; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_BEFORE_LAST; +import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.THREAD; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_DATE; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_DECIMAL; import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_LITERAL; @@ -1009,6 +1011,8 @@ public Evaluator buildEvaluator(final Tree tree) { throw new AttributeExpressionLanguageException(e); } } + case THREAD: + return addToken(new ThreadEvaluator(), "thread"); case HOSTNAME: { if (tree.getChildCount() == 0) { try { diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java new file mode 100644 index 000000000000..bc659d3318a8 --- /dev/null +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java @@ -0,0 +1,45 @@ +/* + * 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 java.util.Map; + +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 ThreadEvaluator extends StringEvaluator { + + private final StringQueryResult thread; + + public ThreadEvaluator() { + // See org.apache.nifi.engine.FlowEngine + thread = new StringQueryResult(Thread.currentThread().getName()); + } + + @Override + public QueryResult evaluate(final Map attributes) { + return thread; + } + + @Override + public Evaluator getSubjectEvaluator() { + return null; + } + +} diff --git a/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java b/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java index 2a43bdc865c6..001b1f4357e2 100644 --- a/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java +++ b/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java @@ -1774,6 +1774,11 @@ public void testIfElse() { verifyEquals("${literal(true):ifElse(false, 'b')}", attributes, "false"); } + @Test + public void testThread() { + final Map attributes = new HashMap<>(); + verifyEquals("${thread()}", attributes, "main"); + } private void verifyEquals(final String expression, final Map attributes, final Object expectedResult) { verifyEquals(expression,attributes, null, expectedResult); diff --git a/nifi-docs/src/main/asciidoc/expression-language-guide.adoc b/nifi-docs/src/main/asciidoc/expression-language-guide.adoc index 3ade4bba05c8..70b2802a8173 100644 --- a/nifi-docs/src/main/asciidoc/expression-language-guide.adoc +++ b/nifi-docs/src/main/asciidoc/expression-language-guide.adoc @@ -2062,6 +2062,24 @@ names begin with the letter `a`. *Examples*: UpdateAttribute processor has stored the key "count" with value "20" in state. '${getStateValue("count")}` returns `20`. + + +[.function] +=== thread + +*Description*: [.description]#Returns the name of the thread used by the processor when evaluating the Expression. This can be useful + when using a processor with multiple concurrent tasks and where some data uniqueness is required.# + +*Subject Type*: [.subjectless]#No Subject# + +*Arguments*: No arguments + +*Return Type*: [.returnType]#String# + +*Examples*: `${thread()}` could return something like `Timer-Driven Process Thread-4`. + + + [[multi]] == Evaluating Multiple Attributes From 09c1ff18e1523cd04bd55b8ef28e299679a72f51 Mon Sep 17 00:00:00 2001 From: Pierre Villard Date: Wed, 5 Dec 2018 11:49:29 +0100 Subject: [PATCH 2/2] moved thread name evaluation in evaluate method --- .../language/evaluation/functions/ThreadEvaluator.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java index bc659d3318a8..4ebfbe518a31 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/ThreadEvaluator.java @@ -25,16 +25,10 @@ public class ThreadEvaluator extends StringEvaluator { - private final StringQueryResult thread; - - public ThreadEvaluator() { - // See org.apache.nifi.engine.FlowEngine - thread = new StringQueryResult(Thread.currentThread().getName()); - } - @Override public QueryResult evaluate(final Map attributes) { - return thread; + // See org.apache.nifi.engine.FlowEngine + return new StringQueryResult(Thread.currentThread().getName()); } @Override