NIFI-2852 base64 expression language functions

Signed-off-by: jpercivall <joepercivall@yahoo.com>
This commit is contained in:
Joe N 2016-10-03 18:16:14 -04:00 committed by jpercivall
parent 6ad633d174
commit 6f1af31ff2
8 changed files with 181 additions and 3 deletions

View File

@ -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')*
); );

View File

@ -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);

View File

@ -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

View File

@ -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");

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<>();

View File

@ -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