mirror of https://github.com/apache/nifi.git
NIFI-2852 base64 expression language functions
Signed-off-by: jpercivall <joepercivall@yahoo.com>
This commit is contained in:
parent
6ad633d174
commit
6f1af31ff2
|
@ -127,6 +127,8 @@ UNESCAPE_XML : 'unescapeXml';
|
||||||
UNESCAPE_CSV : 'unescapeCsv';
|
UNESCAPE_CSV : 'unescapeCsv';
|
||||||
UNESCAPE_HTML3 : 'unescapeHtml3';
|
UNESCAPE_HTML3 : 'unescapeHtml3';
|
||||||
UNESCAPE_HTML4 : 'unescapeHtml4';
|
UNESCAPE_HTML4 : 'unescapeHtml4';
|
||||||
|
BASE64_ENCODE : 'base64Encode';
|
||||||
|
BASE64_DECODE : 'base64Decode';
|
||||||
|
|
||||||
// 1 arg functions
|
// 1 arg functions
|
||||||
SUBSTRING_AFTER : 'substringAfter';
|
SUBSTRING_AFTER : 'substringAfter';
|
||||||
|
@ -226,4 +228,4 @@ ESC
|
||||||
ATTRIBUTE_NAME : (
|
ATTRIBUTE_NAME : (
|
||||||
~('$' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n' | '0'..'9')
|
~('$' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n' | '0'..'9')
|
||||||
~('$' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n')*
|
~('$' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n')*
|
||||||
);
|
);
|
|
@ -73,7 +73,7 @@ tokens {
|
||||||
}
|
}
|
||||||
|
|
||||||
// functions that return Strings
|
// functions that return Strings
|
||||||
zeroArgString : (TO_UPPER | TO_LOWER | TRIM | TO_STRING | URL_ENCODE | URL_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 ) LPAREN! RPAREN!;
|
||||||
oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY |
|
oneArgString : ((SUBSTRING_BEFORE | SUBSTRING_BEFORE_LAST | SUBSTRING_AFTER | SUBSTRING_AFTER_LAST | REPLACE_NULL | REPLACE_EMPTY |
|
||||||
PREPEND | APPEND | FORMAT | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH) LPAREN! anyArg RPAREN!) |
|
PREPEND | APPEND | FORMAT | STARTS_WITH | ENDS_WITH | CONTAINS | JOIN | JSON_PATH) LPAREN! anyArg RPAREN!) |
|
||||||
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
|
(TO_RADIX LPAREN! anyArg (COMMA! anyArg)? RPAREN!);
|
||||||
|
@ -138,4 +138,4 @@ expression : DOLLAR LBRACE attributeRefOrFunctionCall (COLON functionCall)* RBRA
|
||||||
^(EXPRESSION attributeRefOrFunctionCall functionCall*);
|
^(EXPRESSION attributeRefOrFunctionCall functionCall*);
|
||||||
|
|
||||||
query : expression EOF ->
|
query : expression EOF ->
|
||||||
^(QUERY expression);
|
^(QUERY expression);
|
|
@ -86,3 +86,5 @@ URL_DECODE=72
|
||||||
URL_ENCODE=73
|
URL_ENCODE=73
|
||||||
UUID=74
|
UUID=74
|
||||||
WHITESPACE=75
|
WHITESPACE=75
|
||||||
|
BASE64_ENCODE=76
|
||||||
|
BASE64_DECODE=77
|
||||||
|
|
|
@ -94,6 +94,8 @@ import org.apache.nifi.attribute.expression.language.evaluation.functions.ToUppe
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.TrimEvaluator;
|
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.UrlDecodeEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlEncodeEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.UrlEncodeEvaluator;
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.Base64DecodeEvaluator;
|
||||||
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.Base64EncodeEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.functions.UuidEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.functions.UuidEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.literals.BooleanLiteralEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.literals.BooleanLiteralEvaluator;
|
||||||
import org.apache.nifi.attribute.expression.language.evaluation.literals.NumberLiteralEvaluator;
|
import org.apache.nifi.attribute.expression.language.evaluation.literals.NumberLiteralEvaluator;
|
||||||
|
@ -192,6 +194,8 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TRUE;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TRUE;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_DECODE;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_DECODE;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_ENCODE;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.URL_ENCODE;
|
||||||
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.BASE64_DECODE;
|
||||||
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.BASE64_ENCODE;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_JSON;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_JSON;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_CSV;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_CSV;
|
||||||
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_HTML3;
|
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ESCAPE_HTML3;
|
||||||
|
@ -933,6 +937,14 @@ public class Query {
|
||||||
verifyArgCount(argEvaluators, 0, "urlDecode");
|
verifyArgCount(argEvaluators, 0, "urlDecode");
|
||||||
return addToken(new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode");
|
return addToken(new UrlDecodeEvaluator(toStringEvaluator(subjectEvaluator)), "urlDecode");
|
||||||
}
|
}
|
||||||
|
case BASE64_ENCODE: {
|
||||||
|
verifyArgCount(argEvaluators, 0, "base64Encode");
|
||||||
|
return addToken(new Base64EncodeEvaluator(toStringEvaluator(subjectEvaluator)), "base64Encode");
|
||||||
|
}
|
||||||
|
case BASE64_DECODE: {
|
||||||
|
verifyArgCount(argEvaluators, 0, "base64Decode");
|
||||||
|
return addToken(new Base64DecodeEvaluator(toStringEvaluator(subjectEvaluator)), "base64Decode");
|
||||||
|
}
|
||||||
case ESCAPE_CSV: {
|
case ESCAPE_CSV: {
|
||||||
verifyArgCount(argEvaluators, 0, "escapeCsv");
|
verifyArgCount(argEvaluators, 0, "escapeCsv");
|
||||||
return addToken(CharSequenceTranslatorEvaluator.csvEscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
|
return addToken(CharSequenceTranslatorEvaluator.csvEscapeEvaluator(toStringEvaluator(subjectEvaluator)), "escapeJson");
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Base64;
|
||||||
|
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 Base64DecodeEvaluator extends StringEvaluator {
|
||||||
|
|
||||||
|
private final Evaluator<String> subject;
|
||||||
|
|
||||||
|
public Base64DecodeEvaluator(final Evaluator<String> subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryResult<String> evaluate(final Map<String, String> attributes) {
|
||||||
|
final String subjectValue = subject.evaluate(attributes).getValue();
|
||||||
|
if (subjectValue == null) {
|
||||||
|
return new StringQueryResult(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new StringQueryResult(new String(Base64.getDecoder().decode(subjectValue), "UTF-8"));
|
||||||
|
} catch (final UnsupportedEncodingException e) {
|
||||||
|
return null; // won't happen. It's UTF-8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Evaluator<?> getSubjectEvaluator() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Base64;
|
||||||
|
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 Base64EncodeEvaluator extends StringEvaluator {
|
||||||
|
|
||||||
|
private final Evaluator<String> subject;
|
||||||
|
|
||||||
|
public Base64EncodeEvaluator(final Evaluator<String> subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryResult<String> evaluate(final Map<String, String> attributes) {
|
||||||
|
final String subjectValue = subject.evaluate(attributes).getValue();
|
||||||
|
if (subjectValue == null) {
|
||||||
|
return new StringQueryResult(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new StringQueryResult(Base64.getEncoder().encodeToString(subjectValue.getBytes("UTF-8")));
|
||||||
|
} catch (final UnsupportedEncodingException e) {
|
||||||
|
return null; // won't happen.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Evaluator<?> getSubjectEvaluator() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1020,6 +1020,22 @@ public class TestQuery {
|
||||||
verifyEquals("${filename:substringAfter('-'):toNumber():toRadix(36, 3):toUpper()}", attributes, "073");
|
verifyEquals("${filename:substringAfter('-'):toNumber():toRadix(36, 3):toUpper()}", attributes, "073");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBase64Encode(){
|
||||||
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
|
attributes.put("userpass", "admin:admin");
|
||||||
|
verifyEquals("${userpass:base64Encode()}", attributes, "YWRtaW46YWRtaW4=");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBase64Decode(){
|
||||||
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
|
attributes.put("userpassbase64", "YWRtaW46YWRtaW4=");
|
||||||
|
verifyEquals("${userpassbase64:base64Decode()}", attributes, "admin:admin");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDateFormatConversion() {
|
public void testDateFormatConversion() {
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
|
|
|
@ -1179,6 +1179,42 @@ Each of the following functions will encode a string according the rules of the
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[.function]
|
||||||
|
=== base64Encode
|
||||||
|
|
||||||
|
*Description*: [.description]#Returns a Base64 encoded string. This is useful for being able to transfer binary data as ascii.#
|
||||||
|
|
||||||
|
*Subject Type*: [.subject]#String#
|
||||||
|
|
||||||
|
*Arguments*: No arguments
|
||||||
|
|
||||||
|
*Return Type*: [.returnType]#String#
|
||||||
|
|
||||||
|
*Examples*: We can Base64-Encoded an attribute named "payload" by using the Expression
|
||||||
|
`${payload:base64Encode()}` If the attribute payload had a value of "admin:admin"
|
||||||
|
then the Expression `${payload:base64Encode()}` will return "YWRtaW46YWRtaW4=".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[.function]
|
||||||
|
=== base64Decode
|
||||||
|
|
||||||
|
*Description*: [.description]#Reverses the Base64 encoding on given string.#
|
||||||
|
|
||||||
|
*Subject Type*: [.subject]#String#
|
||||||
|
|
||||||
|
*Arguments*: No arguments
|
||||||
|
|
||||||
|
*Return Type*: [.returnType]#String#
|
||||||
|
|
||||||
|
*Examples*: If we have a Base64-Encoded attribute named "payload" with the value
|
||||||
|
"YWRtaW46YWRtaW4=", then the Expression
|
||||||
|
`${payload:base64Decode()}` will return "admin:admin".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[searching]]
|
[[searching]]
|
||||||
== Searching
|
== Searching
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue