Search in sources :

Example 1 with RecordPathResult

use of org.apache.nifi.record.path.RecordPathResult in project nifi by apache.

the class UpdateRecord method processRelativePath.

private Record processRelativePath(final RecordPath replacementRecordPath, final Stream<FieldValue> destinationFields, Record record) {
    final List<FieldValue> destinationFieldValues = destinationFields.collect(Collectors.toList());
    for (final FieldValue fieldVal : destinationFieldValues) {
        final RecordPathResult replacementResult = replacementRecordPath.evaluate(record, fieldVal);
        final List<FieldValue> selectedFields = replacementResult.getSelectedFields().collect(Collectors.toList());
        final Object replacementObject = getReplacementObject(selectedFields);
        fieldVal.updateValue(replacementObject);
        record = updateRecord(destinationFieldValues, selectedFields, record);
    }
    return record;
}
Also used : RecordPathResult(org.apache.nifi.record.path.RecordPathResult) FieldValue(org.apache.nifi.record.path.FieldValue)

Example 2 with RecordPathResult

use of org.apache.nifi.record.path.RecordPathResult in project nifi by apache.

the class UpdateRecord method process.

@Override
protected Record process(Record record, final RecordSchema writeSchema, final FlowFile flowFile, final ProcessContext context) {
    final boolean evaluateValueAsRecordPath = context.getProperty(REPLACEMENT_VALUE_STRATEGY).getValue().equals(RECORD_PATH_VALUES.getValue());
    // Incorporate the RecordSchema that we will use for writing records into the Schema that we have
    // for the record, because it's possible that the updates to the record will not be valid otherwise.
    record.incorporateSchema(writeSchema);
    for (final String recordPathText : recordPaths) {
        final RecordPath recordPath = recordPathCache.getCompiled(recordPathText);
        final RecordPathResult result = recordPath.evaluate(record);
        if (evaluateValueAsRecordPath) {
            final String replacementValue = context.getProperty(recordPathText).evaluateAttributeExpressions(flowFile).getValue();
            final RecordPath replacementRecordPath = recordPathCache.getCompiled(replacementValue);
            // If the RecordPath is a Relative Path, then we have to evaluate it against each FieldValue.
            if (replacementRecordPath.isAbsolute()) {
                record = processAbsolutePath(replacementRecordPath, result.getSelectedFields(), record);
            } else {
                record = processRelativePath(replacementRecordPath, result.getSelectedFields(), record);
            }
        } else {
            final PropertyValue replacementValue = context.getProperty(recordPathText);
            if (replacementValue.isExpressionLanguagePresent()) {
                final Map<String, String> fieldVariables = new HashMap<>();
                result.getSelectedFields().forEach(fieldVal -> {
                    fieldVariables.clear();
                    fieldVariables.put(FIELD_NAME, fieldVal.getField().getFieldName());
                    fieldVariables.put(FIELD_VALUE, DataTypeUtils.toString(fieldVal.getValue(), (String) null));
                    fieldVariables.put(FIELD_TYPE, fieldVal.getField().getDataType().getFieldType().name());
                    final String evaluatedReplacementVal = replacementValue.evaluateAttributeExpressions(flowFile, fieldVariables).getValue();
                    fieldVal.updateValue(evaluatedReplacementVal);
                });
            } else {
                final String evaluatedReplacementVal = replacementValue.getValue();
                result.getSelectedFields().forEach(fieldVal -> fieldVal.updateValue(evaluatedReplacementVal));
            }
        }
    }
    return record;
}
Also used : HashMap(java.util.HashMap) RecordPathResult(org.apache.nifi.record.path.RecordPathResult) PropertyValue(org.apache.nifi.components.PropertyValue) RecordPath(org.apache.nifi.record.path.RecordPath)

Example 3 with RecordPathResult

use of org.apache.nifi.record.path.RecordPathResult in project nifi by apache.

the class UpdateRecord method processAbsolutePath.

private Record processAbsolutePath(final RecordPath replacementRecordPath, final Stream<FieldValue> destinationFields, final Record record) {
    final RecordPathResult replacementResult = replacementRecordPath.evaluate(record);
    final List<FieldValue> selectedFields = replacementResult.getSelectedFields().collect(Collectors.toList());
    final List<FieldValue> destinationFieldValues = destinationFields.collect(Collectors.toList());
    return updateRecord(destinationFieldValues, selectedFields, record);
}
Also used : RecordPathResult(org.apache.nifi.record.path.RecordPathResult) FieldValue(org.apache.nifi.record.path.FieldValue)

Example 4 with RecordPathResult

use of org.apache.nifi.record.path.RecordPathResult in project nifi by apache.

the class RecordPathSegment method evaluate.

@Override
public final RecordPathResult evaluate(final Record record) {
    final RecordPathEvaluationContext context = new StandardRecordPathEvaluationContext(record);
    final Stream<FieldValue> selectedFields = evaluate(context);
    return new RecordPathResult() {

        @Override
        public String getPath() {
            return RecordPathSegment.this.getPath();
        }

        @Override
        public Stream<FieldValue> getSelectedFields() {
            return selectedFields;
        }
    };
}
Also used : RecordPathResult(org.apache.nifi.record.path.RecordPathResult) FieldValue(org.apache.nifi.record.path.FieldValue) StandardRecordPathEvaluationContext(org.apache.nifi.record.path.StandardRecordPathEvaluationContext) StandardRecordPathEvaluationContext(org.apache.nifi.record.path.StandardRecordPathEvaluationContext) RecordPathEvaluationContext(org.apache.nifi.record.path.RecordPathEvaluationContext)

Example 5 with RecordPathResult

use of org.apache.nifi.record.path.RecordPathResult in project nifi by apache.

the class LookupRecord method route.

@Override
protected Set<Relationship> route(final Record record, final RecordSchema writeSchema, final FlowFile flowFile, final ProcessContext context, final Tuple<Map<String, RecordPath>, RecordPath> flowFileContext) {
    final Map<String, RecordPath> recordPaths = flowFileContext.getKey();
    final Map<String, Object> lookupCoordinates = new HashMap<>(recordPaths.size());
    for (final Map.Entry<String, RecordPath> entry : recordPaths.entrySet()) {
        final String coordinateKey = entry.getKey();
        final RecordPath recordPath = entry.getValue();
        final RecordPathResult pathResult = recordPath.evaluate(record);
        final List<FieldValue> lookupFieldValues = pathResult.getSelectedFields().filter(fieldVal -> fieldVal.getValue() != null).collect(Collectors.toList());
        if (lookupFieldValues.isEmpty()) {
            final Set<Relationship> rels = routeToMatchedUnmatched ? UNMATCHED_COLLECTION : SUCCESS_COLLECTION;
            getLogger().debug("RecordPath for property '{}' did not match any fields in a record for {}; routing record to {}", new Object[] { coordinateKey, flowFile, rels });
            return rels;
        }
        if (lookupFieldValues.size() > 1) {
            final Set<Relationship> rels = routeToMatchedUnmatched ? UNMATCHED_COLLECTION : SUCCESS_COLLECTION;
            getLogger().debug("RecordPath for property '{}' matched {} fields in a record for {}; routing record to {}", new Object[] { coordinateKey, lookupFieldValues.size(), flowFile, rels });
            return rels;
        }
        final FieldValue fieldValue = lookupFieldValues.get(0);
        final Object coordinateValue = (fieldValue.getValue() instanceof Number || fieldValue.getValue() instanceof Boolean) ? fieldValue.getValue() : DataTypeUtils.toString(fieldValue.getValue(), (String) null);
        lookupCoordinates.put(coordinateKey, coordinateValue);
    }
    final Optional<?> lookupValueOption;
    try {
        lookupValueOption = lookupService.lookup(lookupCoordinates);
    } catch (final Exception e) {
        throw new ProcessException("Failed to lookup coordinates " + lookupCoordinates + " in Lookup Service", e);
    }
    if (!lookupValueOption.isPresent()) {
        final Set<Relationship> rels = routeToMatchedUnmatched ? UNMATCHED_COLLECTION : SUCCESS_COLLECTION;
        return rels;
    }
    // Ensure that the Record has the appropriate schema to account for the newly added values
    final RecordPath resultPath = flowFileContext.getValue();
    if (resultPath != null) {
        record.incorporateSchema(writeSchema);
        final Object lookupValue = lookupValueOption.get();
        final RecordPathResult resultPathResult = flowFileContext.getValue().evaluate(record);
        final String resultContentsValue = context.getProperty(RESULT_CONTENTS).getValue();
        if (RESULT_RECORD_FIELDS.getValue().equals(resultContentsValue) && lookupValue instanceof Record) {
            final Record lookupRecord = (Record) lookupValue;
            // Use wants to add all fields of the resultant Record to the specified Record Path.
            // If the destination Record Path returns to us a Record, then we will add all field values of
            // the Lookup Record to the destination Record. However, if the destination Record Path returns
            // something other than a Record, then we can't add the fields to it. We can only replace it,
            // because it doesn't make sense to add fields to anything but a Record.
            resultPathResult.getSelectedFields().forEach(fieldVal -> {
                final Object destinationValue = fieldVal.getValue();
                if (destinationValue instanceof Record) {
                    final Record destinationRecord = (Record) destinationValue;
                    for (final String fieldName : lookupRecord.getRawFieldNames()) {
                        final Object value = lookupRecord.getValue(fieldName);
                        destinationRecord.setValue(fieldName, value);
                    }
                } else {
                    final Optional<Record> parentOption = fieldVal.getParentRecord();
                    if (parentOption.isPresent()) {
                        parentOption.get().setValue(fieldVal.getField().getFieldName(), lookupRecord);
                    }
                }
            });
        } else {
            resultPathResult.getSelectedFields().forEach(fieldVal -> fieldVal.updateValue(lookupValue));
        }
    }
    final Set<Relationship> rels = routeToMatchedUnmatched ? MATCHED_COLLECTION : SUCCESS_COLLECTION;
    return rels;
}
Also used : Arrays(java.util.Arrays) CapabilityDescription(org.apache.nifi.annotation.documentation.CapabilityDescription) ValidationContext(org.apache.nifi.components.ValidationContext) HashMap(java.util.HashMap) EventDriven(org.apache.nifi.annotation.behavior.EventDriven) SideEffectFree(org.apache.nifi.annotation.behavior.SideEffectFree) PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) ProcessException(org.apache.nifi.processor.exception.ProcessException) RecordPath(org.apache.nifi.record.path.RecordPath) ArrayList(java.util.ArrayList) RecordPathValidator(org.apache.nifi.record.path.validation.RecordPathValidator) HashSet(java.util.HashSet) RecordSchema(org.apache.nifi.serialization.record.RecordSchema) WritesAttributes(org.apache.nifi.annotation.behavior.WritesAttributes) Relationship(org.apache.nifi.processor.Relationship) Map(java.util.Map) Requirement(org.apache.nifi.annotation.behavior.InputRequirement.Requirement) ValidationResult(org.apache.nifi.components.ValidationResult) Record(org.apache.nifi.serialization.record.Record) RecordPathResult(org.apache.nifi.record.path.RecordPathResult) FlowFile(org.apache.nifi.flowfile.FlowFile) Collection(java.util.Collection) DataTypeUtils(org.apache.nifi.serialization.record.util.DataTypeUtils) ProcessContext(org.apache.nifi.processor.ProcessContext) Set(java.util.Set) WritesAttribute(org.apache.nifi.annotation.behavior.WritesAttribute) SeeAlso(org.apache.nifi.annotation.documentation.SeeAlso) AllowableValue(org.apache.nifi.components.AllowableValue) Collectors(java.util.stream.Collectors) List(java.util.List) InputRequirement(org.apache.nifi.annotation.behavior.InputRequirement) OnScheduled(org.apache.nifi.annotation.lifecycle.OnScheduled) DynamicProperty(org.apache.nifi.annotation.behavior.DynamicProperty) SupportsBatching(org.apache.nifi.annotation.behavior.SupportsBatching) LookupService(org.apache.nifi.lookup.LookupService) Tuple(org.apache.nifi.util.Tuple) Optional(java.util.Optional) RecordPathCache(org.apache.nifi.record.path.util.RecordPathCache) Tags(org.apache.nifi.annotation.documentation.Tags) FieldValue(org.apache.nifi.record.path.FieldValue) Collections(java.util.Collections) HashMap(java.util.HashMap) RecordPathResult(org.apache.nifi.record.path.RecordPathResult) RecordPath(org.apache.nifi.record.path.RecordPath) ProcessException(org.apache.nifi.processor.exception.ProcessException) ProcessException(org.apache.nifi.processor.exception.ProcessException) Relationship(org.apache.nifi.processor.Relationship) Record(org.apache.nifi.serialization.record.Record) FieldValue(org.apache.nifi.record.path.FieldValue) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

RecordPathResult (org.apache.nifi.record.path.RecordPathResult)6 FieldValue (org.apache.nifi.record.path.FieldValue)5 HashMap (java.util.HashMap)2 RecordPath (org.apache.nifi.record.path.RecordPath)2 RecordPathEvaluationContext (org.apache.nifi.record.path.RecordPathEvaluationContext)2 StandardRecordPathEvaluationContext (org.apache.nifi.record.path.StandardRecordPathEvaluationContext)2 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 DynamicProperty (org.apache.nifi.annotation.behavior.DynamicProperty)1 EventDriven (org.apache.nifi.annotation.behavior.EventDriven)1 InputRequirement (org.apache.nifi.annotation.behavior.InputRequirement)1 Requirement (org.apache.nifi.annotation.behavior.InputRequirement.Requirement)1