You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by js...@apache.org on 2016/04/21 20:40:19 UTC

nifi git commit: NIFI-1661 add random() function to expression language.

Repository: nifi
Updated Branches:
  refs/heads/master b50cf7d4d -> 32398693d


NIFI-1661 add random() function to expression language.

Signed-off-by: Joe Skora <js...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/32398693
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/32398693
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/32398693

Branch: refs/heads/master
Commit: 32398693d5917e35d3a6cd1549edd795e16fa8ec
Parents: b50cf7d
Author: Chris McDermott <ch...@hpe.com>
Authored: Sun Apr 3 16:19:55 2016 -0400
Committer: Joe Skora <js...@apache.org>
Committed: Thu Apr 21 14:05:00 2016 -0400

----------------------------------------------------------------------
 nifi-commons/nifi-expression-language/pom.xml   |  5 +++
 .../language/antlr/AttributeExpressionLexer.g   |  1 +
 .../language/antlr/AttributeExpressionParser.g  |  2 +-
 .../attribute/expression/language/Query.java    |  8 ++++
 .../RandomNumberGeneratorEvaluator.java         | 42 ++++++++++++++++++++
 .../expression/language/TestQuery.java          | 27 +++++++++++++
 .../asciidoc/expression-language-guide.adoc     | 10 +++++
 pom.xml                                         |  6 +++
 8 files changed, 100 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-commons/nifi-expression-language/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-expression-language/pom.xml b/nifi-commons/nifi-expression-language/pom.xml
index ef552e9..da6d7d8 100644
--- a/nifi-commons/nifi-expression-language/pom.xml
+++ b/nifi-commons/nifi-expression-language/pom.xml
@@ -56,5 +56,10 @@
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-utils</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g
----------------------------------------------------------------------
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 d56a27b..1214273 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
@@ -116,6 +116,7 @@ URL_ENCODE : 'urlEncode';
 URL_DECODE : 'urlDecode';
 NOT : 'not';
 COUNT : 'count';
+RANDOM : 'random';
 
 // 1 arg functions
 SUBSTRING_AFTER	: 'substringAfter';

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g
----------------------------------------------------------------------
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 780d8c5..45460aa 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
@@ -126,7 +126,7 @@ functionCall : functionRef ->
 	^(FUNCTION_CALL functionRef);
 
 booleanLiteral : TRUE | FALSE;
-zeroArgStandaloneFunction : (IP | UUID | NOW | NEXT_INT | HOSTNAME) LPAREN! RPAREN!;
+zeroArgStandaloneFunction : (IP | UUID | NOW | NEXT_INT | HOSTNAME | RANDOM) LPAREN! RPAREN!;
 oneArgStandaloneFunction : (TO_LITERAL^ LPAREN! anyArg RPAREN!) | 
                            (HOSTNAME^ LPAREN! booleanLiteral RPAREN!);
 standaloneFunction : zeroArgStandaloneFunction | oneArgStandaloneFunction;

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java
index b3a364a..792443d 100644
--- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java
+++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java
@@ -74,6 +74,7 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.OneUpS
 import org.apache.nifi.attribute.expression.language.evaluation.functions.OrEvaluator;
 import org.apache.nifi.attribute.expression.language.evaluation.functions.PlusEvaluator;
 import org.apache.nifi.attribute.expression.language.evaluation.functions.PrependEvaluator;
+import org.apache.nifi.attribute.expression.language.evaluation.functions.RandomNumberGeneratorEvaluator;
 import org.apache.nifi.attribute.expression.language.evaluation.functions.ReplaceAllEvaluator;
 import org.apache.nifi.attribute.expression.language.evaluation.functions.ReplaceEmptyEvaluator;
 import org.apache.nifi.attribute.expression.language.evaluation.functions.ReplaceEvaluator;
@@ -166,6 +167,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre
 import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.PLUS;
 import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.PREPEND;
 import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE;
+import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.RANDOM;
 import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE_ALL;
 import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE_EMPTY;
 import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.REPLACE_NULL;
@@ -878,6 +880,9 @@ public class Query {
             case NEXT_INT: {
                 return new OneUpSequenceEvaluator();
             }
+            case RANDOM: {
+                return new RandomNumberGeneratorEvaluator();
+            }
             default:
                 throw new AttributeExpressionLanguageParsingException("Unexpected token: " + tree.toString());
         }
@@ -1268,6 +1273,9 @@ public class Query {
             case DIVIDE: {
                 return addToken(new DivideEvaluator(toNumberEvaluator(subjectEvaluator), toNumberEvaluator(argEvaluators.get(0))), "divide");
             }
+            case RANDOM : {
+                return addToken(new RandomNumberGeneratorEvaluator(), "random");
+            }
             case INDEX_OF: {
                 verifyArgCount(argEvaluators, 1, "indexOf");
                 return addToken(new IndexOfEvaluator(toStringEvaluator(subjectEvaluator),

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/RandomNumberGeneratorEvaluator.java
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/RandomNumberGeneratorEvaluator.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/RandomNumberGeneratorEvaluator.java
new file mode 100644
index 0000000..84be971
--- /dev/null
+++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/functions/RandomNumberGeneratorEvaluator.java
@@ -0,0 +1,42 @@
+/*
+ * 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 java.util.Random;
+
+import org.apache.nifi.attribute.expression.language.evaluation.Evaluator;
+import org.apache.nifi.attribute.expression.language.evaluation.NumberEvaluator;
+import org.apache.nifi.attribute.expression.language.evaluation.NumberQueryResult;
+import org.apache.nifi.attribute.expression.language.evaluation.QueryResult;
+
+public class RandomNumberGeneratorEvaluator extends NumberEvaluator {
+
+    private static final Random RNG = new Random();
+
+
+    @Override
+    public QueryResult<Long> evaluate(final Map<String, String> attributes) {
+        return new NumberQueryResult(Math.abs(RNG.nextLong()));
+    }
+
+    @Override
+    public Evaluator<?> getSubjectEvaluator() {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java
----------------------------------------------------------------------
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 751a0ac..41e1934 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
@@ -19,6 +19,8 @@ package org.apache.nifi.attribute.expression.language;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
@@ -40,6 +42,7 @@ import org.antlr.runtime.tree.Tree;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
+
 import org.mockito.Mockito;
 
 public class TestQuery {
@@ -56,6 +59,7 @@ public class TestQuery {
         assertValid("${attr:toNumber():multiply(3)}");
         assertValid("${hostname()}");
         assertValid("${literal(3)}");
+        assertValid("${random()}");
         // left here because it's convenient for looking at the output
         //System.out.println(Query.compile("").evaluate(null));
     }
@@ -1094,6 +1098,11 @@ public class TestQuery {
     }
 
     @Test
+    public void testRandomFunctionReturnsNumberType() {
+        assertEquals(ResultType.NUMBER, Query.getResultType("${random()}"));
+    }
+
+    @Test
     public void testAnyAttributeEmbedded() {
         final Map<String, String> attributes = new HashMap<>();
         attributes.put("a1", "test1");
@@ -1124,6 +1133,24 @@ public class TestQuery {
     }
 
     @Test
+    public void testRandomFunction() {
+        final Map<String, String> attrs = Collections.<String, String> emptyMap();
+        final Long negOne = Long.valueOf(-1L);
+        final HashSet<Long> results = new HashSet<Long>(100);
+        for (int i = 0; i < results.size(); i++) {
+            long result = (Long) getResult("${random()}", attrs).getValue();
+            assertThat("random", result, greaterThan(negOne));
+            assertEquals("duplicate random", true, results.add(result));
+        }
+    }
+
+    QueryResult<?> getResult(String expr, Map<String, String> attrs) {
+        final Query query = Query.compile(expr);
+        final QueryResult<?> result = query.evaluate(attrs);
+        return result;
+    }
+
+    @Test
     public void testFunctionAfterReduce() {
         // Cannot call gt(2) after count() because count() is a 'reducing function'
         // and must be the last function in an expression.

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/nifi-docs/src/main/asciidoc/expression-language-guide.adoc
----------------------------------------------------------------------
diff --git a/nifi-docs/src/main/asciidoc/expression-language-guide.adoc b/nifi-docs/src/main/asciidoc/expression-language-guide.adoc
index a78c559..6f72510 100644
--- a/nifi-docs/src/main/asciidoc/expression-language-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/expression-language-guide.adoc
@@ -1299,8 +1299,18 @@ Expressions will provide the following results:
 | `${fileSize:toRadix(2, 16)}` | `0000010000000000`
 |=======================================================================================
 
+[.function]
+=== random
+
+*Description*: [.description]#Returns a random number ( 0 to 2^63 - 1) using an insecure random number generator.#
+
+*Subject Type*: [.subjectless]#No subject#
 
+*Arguments*: No arguments
+
+*Return Type*: [.returnType]#Number#
 
+*Examples*: ${random():mod(10):plus(1)} returns random number between 1 and 10 inclusive.
 
 [[dates]]
 == Date Manipulation

http://git-wip-us.apache.org/repos/asf/nifi/blob/32398693/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 29b936b..9acd949 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1198,6 +1198,12 @@ language governing permissions and limitations under the License. -->
                 <version>2.4.5</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>org.hamcrest</groupId>
+                <artifactId>hamcrest-all</artifactId>
+                <version>1.3</version>
+                <scope>test</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
     <dependencies>