NIFI-271 checkpoint

This commit is contained in:
joewitt 2015-04-21 15:24:04 -04:00
parent 6d728406de
commit afb4fe52b9
20 changed files with 328 additions and 282 deletions

View File

@ -27,6 +27,7 @@ import org.apache.nifi.provenance.lineage.LineageComputationType;
* *
*/ */
public class AsyncLineageSubmission implements ComputeLineageSubmission { public class AsyncLineageSubmission implements ComputeLineageSubmission {
private final String lineageIdentifier = UUID.randomUUID().toString(); private final String lineageIdentifier = UUID.randomUUID().toString();
private final Date submissionTime = new Date(); private final Date submissionTime = new Date();

View File

@ -22,9 +22,6 @@ import java.util.concurrent.TimeUnit;
import org.apache.nifi.provenance.search.Query; import org.apache.nifi.provenance.search.Query;
import org.apache.nifi.provenance.search.QuerySubmission; import org.apache.nifi.provenance.search.QuerySubmission;
/**
*
*/
public class AsyncQuerySubmission implements QuerySubmission { public class AsyncQuerySubmission implements QuerySubmission {
public static final int TTL = (int) TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS); public static final int TTL = (int) TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS);
@ -40,8 +37,8 @@ public class AsyncQuerySubmission implements QuerySubmission {
* number of steps, indicating how many results must be added to this * number of steps, indicating how many results must be added to this
* AsyncQuerySubmission before it is considered finished * AsyncQuerySubmission before it is considered finished
* *
* @param query * @param query the query to execute
* @param numSteps * @param numSteps how many steps to include
*/ */
public AsyncQuerySubmission(final Query query, final int numSteps) { public AsyncQuerySubmission(final Query query, final int numSteps) {
this.query = query; this.query = query;

View File

@ -41,14 +41,21 @@ public class SearchableFields {
public static final SearchableField Details = new NamedSearchableField("Details", "details", "Details", false, SearchableFieldType.STRING); public static final SearchableField Details = new NamedSearchableField("Details", "details", "Details", false, SearchableFieldType.STRING);
public static final SearchableField Relationship = new NamedSearchableField("Relationship", "relationship", "Relationship", false, SearchableFieldType.STRING); public static final SearchableField Relationship = new NamedSearchableField("Relationship", "relationship", "Relationship", false, SearchableFieldType.STRING);
public static final SearchableField LineageStartDate = new NamedSearchableField("LineageStartDate", "lineageStartDate", "Lineage Start Date", false, SearchableFieldType.DATE); public static final SearchableField LineageStartDate
public static final SearchableField LineageIdentifier = new NamedSearchableField("LineageIdentifiers", "lineageIdentifier", "Lineage Identifier", false, SearchableFieldType.STRING); = new NamedSearchableField("LineageStartDate", "lineageStartDate", "Lineage Start Date", false, SearchableFieldType.DATE);
public static final SearchableField LineageIdentifier
= new NamedSearchableField("LineageIdentifiers", "lineageIdentifier", "Lineage Identifier", false, SearchableFieldType.STRING);
public static final SearchableField ContentClaimSection = new NamedSearchableField("ContentClaimSection", "contentClaimSection", "Content Claim Section", false, SearchableFieldType.STRING); public static final SearchableField ContentClaimSection
public static final SearchableField ContentClaimContainer = new NamedSearchableField("ContentClaimContainer", "contentClaimContainer", "Content Claim Container", false, SearchableFieldType.STRING); = new NamedSearchableField("ContentClaimSection", "contentClaimSection", "Content Claim Section", false, SearchableFieldType.STRING);
public static final SearchableField ContentClaimIdentifier = new NamedSearchableField("ContentClaimIdentifier", "contentClaimIdentifier", "Content Claim Identifier", false, SearchableFieldType.STRING); public static final SearchableField ContentClaimContainer
public static final SearchableField ContentClaimOffset = new NamedSearchableField("ContentClaimOffset", "contentClaimOffset", "Content Claim Offset", false, SearchableFieldType.LONG); = new NamedSearchableField("ContentClaimContainer", "contentClaimContainer", "Content Claim Container", false, SearchableFieldType.STRING);
public static final SearchableField SourceQueueIdentifier = new NamedSearchableField("SourceQueueIdentifier", "sourceQueueIdentifier", "Source Queue Identifier", false, SearchableFieldType.STRING); public static final SearchableField ContentClaimIdentifier
= new NamedSearchableField("ContentClaimIdentifier", "contentClaimIdentifier", "Content Claim Identifier", false, SearchableFieldType.STRING);
public static final SearchableField ContentClaimOffset
= new NamedSearchableField("ContentClaimOffset", "contentClaimOffset", "Content Claim Offset", false, SearchableFieldType.LONG);
public static final SearchableField SourceQueueIdentifier
= new NamedSearchableField("SourceQueueIdentifier", "sourceQueueIdentifier", "Source Queue Identifier", false, SearchableFieldType.STRING);
private static final Map<String, SearchableField> standardFields; private static final Map<String, SearchableField> standardFields;

View File

@ -266,7 +266,8 @@ public class StandardLineageResult implements ComputeLineageResult {
final FlowFileNode childNode = new FlowFileNode(childUuid, record.getEventTime()); final FlowFileNode childNode = new FlowFileNode(childUuid, record.getEventTime());
final boolean isNewFlowFile = nodes.add(childNode); final boolean isNewFlowFile = nodes.add(childNode);
if (!isNewFlowFile) { if (!isNewFlowFile) {
final String msg = "Unable to generate Lineage Graph because multiple events were registered claiming to have generated the same FlowFile (UUID = " + childNode.getFlowFileUuid() + ")"; final String msg = "Unable to generate Lineage Graph because multiple "
+ "events were registered claiming to have generated the same FlowFile (UUID = " + childNode.getFlowFileUuid() + ")";
logger.error(msg); logger.error(msg);
setError(msg); setError(msg);
return; return;
@ -288,12 +289,13 @@ public class StandardLineageResult implements ComputeLineageResult {
break; break;
case RECEIVE: case RECEIVE:
case CREATE: { case CREATE: {
// for a receive event, we want to create a FlowFile Node that represents the FlowFile received // for a receive event, we want to create a FlowFile Node that represents the FlowFile received
// and create an edge from the Receive Event to the FlowFile Node // and create an edge from the Receive Event to the FlowFile Node
final LineageNode flowFileNode = new FlowFileNode(record.getFlowFileUuid(), record.getEventTime()); final LineageNode flowFileNode = new FlowFileNode(record.getFlowFileUuid(), record.getEventTime());
final boolean isNewFlowFile = nodes.add(flowFileNode); final boolean isNewFlowFile = nodes.add(flowFileNode);
if (!isNewFlowFile) { if (!isNewFlowFile) {
final String msg = "Found cycle in graph. This indicates that multiple events were registered claiming to have generated the same FlowFile (UUID = " + flowFileNode.getFlowFileUuid() + ")"; final String msg = "Found cycle in graph. This indicates that multiple events "
+ "were registered claiming to have generated the same FlowFile (UUID = " + flowFileNode.getFlowFileUuid() + ")";
setError(msg); setError(msg);
logger.error(msg); logger.error(msg);
return; return;

View File

@ -34,6 +34,13 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<excludes>**/antlr/AttributeExpressionParser.java,**/antlr/AttributeExpressionLexer.java</excludes>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>

View File

@ -23,21 +23,22 @@ import org.apache.nifi.expression.AttributeValueDecorator;
import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.exception.ProcessException; import org.apache.nifi.processor.exception.ProcessException;
/** /**
* An implementation of PreparedQuery that throws an {@link AttributeExpressionLanguageException} when attempting * An implementation of PreparedQuery that throws an
* to evaluate the query. This allows a PreparedQuery to be created, even though it can't * {@link AttributeExpressionLanguageException} when attempting to evaluate the
* be evaluated. * query. This allows a PreparedQuery to be created, even though it can't be
* evaluated.
*/ */
public class InvalidPreparedQuery implements PreparedQuery { public class InvalidPreparedQuery implements PreparedQuery {
private final String query; private final String query;
private final String explanation; private final String explanation;
public InvalidPreparedQuery(final String query, final String explanation) { public InvalidPreparedQuery(final String query, final String explanation) {
this.query = query; this.query = query;
this.explanation = explanation; this.explanation = explanation;
} }
@Override @Override
public String evaluateExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { public String evaluateExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException {
throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation);

View File

@ -16,8 +16,6 @@
*/ */
package org.apache.nifi.attribute.expression.language; package org.apache.nifi.attribute.expression.language;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.*;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -116,6 +114,73 @@ import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream; import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.Tree; import org.antlr.runtime.tree.Tree;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_ATTRIBUTES;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_DELINEATED_VALUES;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ALL_MATCHING_ATTRIBUTES;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.AND;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ANY_ATTRIBUTE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ANY_DELINEATED_VALUE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ANY_MATCHING_ATTRIBUTE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.APPEND;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ATTRIBUTE_REFERENCE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ATTR_NAME;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.CONTAINS;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.COUNT;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.DIVIDE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.ENDS_WITH;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EQUALS;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EQUALS_IGNORE_CASE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.EXPRESSION;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FALSE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FIND;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.FORMAT;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.GREATER_THAN;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.GREATER_THAN_OR_EQUAL;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.HOSTNAME;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.INDEX_OF;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IP;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IS_EMPTY;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.IS_NULL;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.JOIN;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LAST_INDEX_OF;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LENGTH;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LESS_THAN;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.LESS_THAN_OR_EQUAL;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MATCHES;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MINUS;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MOD;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MULTIPLY;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.MULTI_ATTRIBUTE_REFERENCE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NEXT_INT;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NOT;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NOT_NULL;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NOW;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.NUMBER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.OR;
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.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;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.STARTS_WITH;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.STRING_LITERAL;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.SUBSTRING_AFTER;
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.TO_DATE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_LOWER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_NUMBER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_RADIX;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_STRING;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TO_UPPER;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.TRIM;
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_ENCODE;
import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID;
import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator; import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator;
/** /**
@ -229,11 +294,9 @@ public class Query {
} }
/** /**
* * @param value expression to validate
* * @param allowSurroundingCharacters whether to allow surrounding chars
* @param value * @throws AttributeExpressionLanguageParsingException if problems parsing given expression
* @param allowSurroundingCharacters
* @throws AttributeExpressionLanguageParsingException
*/ */
public static void validateExpression(final String value, final boolean allowSurroundingCharacters) throws AttributeExpressionLanguageParsingException { public static void validateExpression(final String value, final boolean allowSurroundingCharacters) throws AttributeExpressionLanguageParsingException {
if (!allowSurroundingCharacters) { if (!allowSurroundingCharacters) {
@ -333,8 +396,8 @@ public class Query {
/** /**
* Un-escapes ${...} patterns that were escaped * Un-escapes ${...} patterns that were escaped
* *
* @param value * @param value to un-escape
* @return * @return un-escaped value
*/ */
public static String unescape(final String value) { public static String unescape(final String value) {
return value.replaceAll("\\$\\$(?=\\$*\\{.*?\\})", "\\$"); return value.replaceAll("\\$\\$(?=\\$*\\{.*?\\})", "\\$");

View File

@ -49,9 +49,6 @@ public class GreaterThanEvaluator extends BooleanEvaluator {
return new BooleanQueryResult(subjectValue > comparisonValue); return new BooleanQueryResult(subjectValue > comparisonValue);
} }
;
@Override @Override
public Evaluator<?> getSubjectEvaluator() { public Evaluator<?> getSubjectEvaluator() {
return subject; return subject;

View File

@ -49,9 +49,6 @@ public class GreaterThanOrEqualEvaluator extends BooleanEvaluator {
return new BooleanQueryResult(subjectValue >= comparisonValue); return new BooleanQueryResult(subjectValue >= comparisonValue);
} }
;
@Override @Override
public Evaluator<?> getSubjectEvaluator() { public Evaluator<?> getSubjectEvaluator() {
return subject; return subject;

View File

@ -24,12 +24,13 @@ 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.QueryResult;
public class IsEmptyEvaluator extends BooleanEvaluator { public class IsEmptyEvaluator extends BooleanEvaluator {
private final Evaluator<?> subjectEvaluator; private final Evaluator<?> subjectEvaluator;
public IsEmptyEvaluator(final Evaluator<?> subjectEvaluator) { public IsEmptyEvaluator(final Evaluator<?> subjectEvaluator) {
this.subjectEvaluator = subjectEvaluator; this.subjectEvaluator = subjectEvaluator;
} }
@Override @Override
public QueryResult<Boolean> evaluate(final Map<String, String> attributes) { public QueryResult<Boolean> evaluate(final Map<String, String> attributes) {
final Object subjectValue = subjectEvaluator.evaluate(attributes).getValue(); final Object subjectValue = subjectEvaluator.evaluate(attributes).getValue();

View File

@ -49,9 +49,6 @@ public class LessThanEvaluator extends BooleanEvaluator {
return new BooleanQueryResult(subjectValue < comparisonValue); return new BooleanQueryResult(subjectValue < comparisonValue);
} }
;
@Override @Override
public Evaluator<?> getSubjectEvaluator() { public Evaluator<?> getSubjectEvaluator() {
return subject; return subject;

View File

@ -49,9 +49,6 @@ public class LessThanOrEqualEvaluator extends BooleanEvaluator {
return new BooleanQueryResult(subjectValue <= comparisonValue); return new BooleanQueryResult(subjectValue <= comparisonValue);
} }
;
@Override @Override
public Evaluator<?> getSubjectEvaluator() { public Evaluator<?> getSubjectEvaluator() {
return subject; return subject;

View File

@ -23,20 +23,21 @@ 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.StringEvaluator;
public class ReplaceEmptyEvaluator extends StringEvaluator { public class ReplaceEmptyEvaluator extends StringEvaluator {
private final StringEvaluator subjectEvaluator; private final StringEvaluator subjectEvaluator;
private final StringEvaluator replacementEvaluator; private final StringEvaluator replacementEvaluator;
public ReplaceEmptyEvaluator(final StringEvaluator subjectEvaluator, final StringEvaluator replacementEvaluator) { public ReplaceEmptyEvaluator(final StringEvaluator subjectEvaluator, final StringEvaluator replacementEvaluator) {
this.subjectEvaluator = subjectEvaluator; this.subjectEvaluator = subjectEvaluator;
this.replacementEvaluator = replacementEvaluator; this.replacementEvaluator = replacementEvaluator;
} }
@Override @Override
public QueryResult<String> evaluate(final Map<String, String> attributes) { public QueryResult<String> evaluate(final Map<String, String> attributes) {
final QueryResult<String> subjectResult = subjectEvaluator.evaluate(attributes); final QueryResult<String> subjectResult = subjectEvaluator.evaluate(attributes);
final String subjectValue = subjectResult.getValue(); final String subjectValue = subjectResult.getValue();
final boolean isEmpty = subjectValue == null || subjectValue.toString().trim().isEmpty(); final boolean isEmpty = subjectValue == null || subjectValue.toString().trim().isEmpty();
if ( isEmpty ) { if (isEmpty) {
return replacementEvaluator.evaluate(attributes); return replacementEvaluator.evaluate(attributes);
} else { } else {
return subjectResult; return subjectResult;

View File

@ -28,19 +28,19 @@ public class CountEvaluator extends NumberEvaluator implements ReduceEvaluator<L
private final Evaluator<?> subjectEvaluator; private final Evaluator<?> subjectEvaluator;
private long count = 0L; private long count = 0L;
public CountEvaluator(final Evaluator<?> subjectEvaluator) { public CountEvaluator(final Evaluator<?> subjectEvaluator) {
this.subjectEvaluator = subjectEvaluator; this.subjectEvaluator = subjectEvaluator;
} }
@Override @Override
public QueryResult<Long> evaluate(final Map<String, String> attributes) { public QueryResult<Long> evaluate(final Map<String, String> attributes) {
final QueryResult<?> result = subjectEvaluator.evaluate(attributes); final QueryResult<?> result = subjectEvaluator.evaluate(attributes);
if ( result.getValue() == null ) { if (result.getValue() == null) {
return new NumberQueryResult(count); return new NumberQueryResult(count);
} }
if ( result.getResultType() == ResultType.BOOLEAN && ((Boolean) result.getValue()).equals(Boolean.FALSE) ) { if (result.getResultType() == ResultType.BOOLEAN && ((Boolean) result.getValue()).equals(Boolean.FALSE)) {
return new NumberQueryResult(count); return new NumberQueryResult(count);
} }

View File

@ -24,34 +24,35 @@ import org.apache.nifi.attribute.expression.language.evaluation.StringEvaluator;
import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResult; import org.apache.nifi.attribute.expression.language.evaluation.StringQueryResult;
public class JoinEvaluator extends StringEvaluator implements ReduceEvaluator<String> { public class JoinEvaluator extends StringEvaluator implements ReduceEvaluator<String> {
private final StringEvaluator subjectEvaluator; private final StringEvaluator subjectEvaluator;
private final StringEvaluator delimiterEvaluator; private final StringEvaluator delimiterEvaluator;
private final StringBuilder sb = new StringBuilder(); private final StringBuilder sb = new StringBuilder();
private int evalCount = 0; private int evalCount = 0;
public JoinEvaluator(final StringEvaluator subject, final StringEvaluator delimiter) { public JoinEvaluator(final StringEvaluator subject, final StringEvaluator delimiter) {
this.subjectEvaluator = subject; this.subjectEvaluator = subject;
this.delimiterEvaluator = delimiter; this.delimiterEvaluator = delimiter;
} }
@Override @Override
public QueryResult<String> evaluate(final Map<String, String> attributes) { public QueryResult<String> evaluate(final Map<String, String> attributes) {
String subject = subjectEvaluator.evaluate(attributes).getValue(); String subject = subjectEvaluator.evaluate(attributes).getValue();
if ( subject == null ) { if (subject == null) {
subject = ""; subject = "";
} }
final String delimiter = delimiterEvaluator.evaluate(attributes).getValue(); final String delimiter = delimiterEvaluator.evaluate(attributes).getValue();
if ( evalCount > 0 ) { if (evalCount > 0) {
sb.append(delimiter); sb.append(delimiter);
} }
sb.append(subject); sb.append(subject);
evalCount++; evalCount++;
return new StringQueryResult( sb.toString() ); return new StringQueryResult(sb.toString());
} }
@Override @Override
public Evaluator<?> getSubjectEvaluator() { public Evaluator<?> getSubjectEvaluator() {
return subjectEvaluator; return subjectEvaluator;

View File

@ -24,19 +24,20 @@ import org.apache.nifi.attribute.expression.language.evaluation.reduce.ReduceEva
import org.apache.nifi.expression.AttributeExpression.ResultType; import org.apache.nifi.expression.AttributeExpression.ResultType;
public class MappingEvaluator<T> implements Evaluator<T> { public class MappingEvaluator<T> implements Evaluator<T> {
private final ReduceEvaluator<T> mappingEvaluator; private final ReduceEvaluator<T> mappingEvaluator;
private final MultiAttributeEvaluator multiAttributeEvaluator; private final MultiAttributeEvaluator multiAttributeEvaluator;
public MappingEvaluator(final ReduceEvaluator<T> mappingEvaluator, final MultiAttributeEvaluator multiAttributeEval) { public MappingEvaluator(final ReduceEvaluator<T> mappingEvaluator, final MultiAttributeEvaluator multiAttributeEval) {
this.mappingEvaluator = mappingEvaluator; this.mappingEvaluator = mappingEvaluator;
this.multiAttributeEvaluator = multiAttributeEval; this.multiAttributeEvaluator = multiAttributeEval;
} }
@Override @Override
public QueryResult<T> evaluate(final Map<String, String> attributes) { public QueryResult<T> evaluate(final Map<String, String> attributes) {
QueryResult<T> result = mappingEvaluator.evaluate(attributes); QueryResult<T> result = mappingEvaluator.evaluate(attributes);
while ( multiAttributeEvaluator.getEvaluationsRemaining() > 0 ) { while (multiAttributeEvaluator.getEvaluationsRemaining() > 0) {
result = mappingEvaluator.evaluate(attributes); result = mappingEvaluator.evaluate(attributes);
} }

View File

@ -44,7 +44,7 @@ public class MultiMatchAttributeEvaluator extends MultiAttributeEvaluator {
/** /**
* Can be called only after the first call to evaluate * Can be called only after the first call to evaluate
* *
* @return * @return number of remaining evaluations
*/ */
@Override @Override
public int getEvaluationsRemaining() { public int getEvaluationsRemaining() {

View File

@ -17,6 +17,7 @@
package org.apache.nifi.attribute.expression.language.exception; package org.apache.nifi.attribute.expression.language.exception;
public class IllegalAttributeException extends RuntimeException { public class IllegalAttributeException extends RuntimeException {
private static final long serialVersionUID = 12348721897342L; private static final long serialVersionUID = 12348721897342L;
public IllegalAttributeException() { public IllegalAttributeException() {

View File

@ -31,34 +31,34 @@ public class TestStandardPreparedQuery {
public void testSimpleReference() { public void testSimpleReference() {
final Map<String, String> attrs = new HashMap<>(); final Map<String, String> attrs = new HashMap<>();
attrs.put("xx", "world"); attrs.put("xx", "world");
assertEquals("world", evaluate("${xx}", attrs)); assertEquals("world", evaluate("${xx}", attrs));
assertEquals("hello, world!", evaluate("hello, ${xx}!", attrs)); assertEquals("hello, world!", evaluate("hello, ${xx}!", attrs));
} }
@Test @Test
public void testEmbeddedReference() { public void testEmbeddedReference() {
final Map<String, String> attrs = new HashMap<>(); final Map<String, String> attrs = new HashMap<>();
attrs.put("xx", "yy"); attrs.put("xx", "yy");
attrs.put("yy", "world"); attrs.put("yy", "world");
assertEquals("world", evaluate("${${xx}}", attrs)); assertEquals("world", evaluate("${${xx}}", attrs));
} }
@Test @Test
public void test10MIterations() { public void test10MIterations() {
final Map<String, String> attrs = new HashMap<>(); final Map<String, String> attrs = new HashMap<>();
attrs.put("xx", "world"); attrs.put("xx", "world");
final StandardPreparedQuery prepared = (StandardPreparedQuery) Query.prepare("${xx}"); final StandardPreparedQuery prepared = (StandardPreparedQuery) Query.prepare("${xx}");
final long start = System.nanoTime(); final long start = System.nanoTime();
for (int i=0; i < 10000000; i++) { for (int i = 0; i < 10000000; i++) {
assertEquals( "world", prepared.evaluateExpressions(attrs, null) ); assertEquals("world", prepared.evaluateExpressions(attrs, null));
} }
final long nanos = System.nanoTime() - start; final long nanos = System.nanoTime() - start;
System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos)); System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos));
} }
@Test @Test
@Ignore("Takes too long") @Ignore("Takes too long")
public void test10MIterationsWithQuery() { public void test10MIterationsWithQuery() {
@ -66,14 +66,14 @@ public class TestStandardPreparedQuery {
attrs.put("xx", "world"); attrs.put("xx", "world");
final long start = System.nanoTime(); final long start = System.nanoTime();
for (int i=0; i < 10000000; i++) { for (int i = 0; i < 10000000; i++) {
assertEquals( "world", Query.evaluateExpressions("${xx}", attrs) ); assertEquals("world", Query.evaluateExpressions("${xx}", attrs));
} }
final long nanos = System.nanoTime() - start; final long nanos = System.nanoTime() - start;
System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos)); System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos));
} }
@Test @Test
public void testSeveralSequentialExpressions() { public void testSeveralSequentialExpressions() {
final Map<String, String> attributes = new HashMap<>(); final Map<String, String> attributes = new HashMap<>();
@ -83,10 +83,10 @@ public class TestStandardPreparedQuery {
assertEquals("Hello, World, how are you?!", evaluate("Hello, ${audience}${comma}${question}!", attributes)); assertEquals("Hello, World, how are you?!", evaluate("Hello, ${audience}${comma}${question}!", attributes));
} }
private String evaluate(final String query, final Map<String, String> attrs) { private String evaluate(final String query, final Map<String, String> attrs) {
final String evaluated = ((StandardPreparedQuery) Query.prepare(query)).evaluateExpressions(attrs, null); final String evaluated = ((StandardPreparedQuery) Query.prepare(query)).evaluateExpressions(attrs, null);
return evaluated; return evaluated;
} }
} }