Search in sources :

Example 6 with Criteria

use of org.apache.nifi.update.attributes.Criteria in project nifi by apache.

the class RuleResource method updateEvaluationContext.

@PUT
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("/evaluation-context")
public Response updateEvaluationContext(@Context final UriInfo uriInfo, final EvaluationContextEntity requestEntity) {
    // get the web context
    final NiFiWebConfigurationContext configurationContext = (NiFiWebConfigurationContext) servletContext.getAttribute("nifi-web-configuration-context");
    // ensure the evaluation context has been specified
    if (requestEntity == null) {
        throw new WebApplicationException(badRequest("The evaluation context must be specified."));
    }
    // ensure the id has been specified
    if (requestEntity.getRuleOrder() == null && requestEntity.getFlowFilePolicy() == null) {
        throw new WebApplicationException(badRequest("Either the rule order or the matching strategy must be specified."));
    }
    // build the web context config
    final NiFiWebConfigurationRequestContext requestContext = getConfigurationRequestContext(requestEntity.getProcessorId(), requestEntity.getRevision(), requestEntity.getClientId());
    // load the criteria
    final Criteria criteria = getCriteria(configurationContext, requestContext);
    // if a new rule order is specified, attempt to set it
    if (requestEntity.getRuleOrder() != null) {
        try {
            criteria.reorder(requestEntity.getRuleOrder());
        } catch (final IllegalArgumentException iae) {
            throw new WebApplicationException(iae, badRequest(iae.getMessage()));
        }
    }
    // if a new matching strategy is specified, attempt to set it
    if (requestEntity.getFlowFilePolicy() != null) {
        try {
            criteria.setFlowFilePolicy(FlowFilePolicy.valueOf(requestEntity.getFlowFilePolicy()));
        } catch (final IllegalArgumentException iae) {
            throw new WebApplicationException(iae, badRequest("The specified matching strategy is unknown: " + requestEntity.getFlowFilePolicy()));
        }
    }
    // save the criteria
    saveCriteria(requestContext, criteria);
    // create the response entity
    final EvaluationContextEntity responseEntity = new EvaluationContextEntity();
    responseEntity.setClientId(requestEntity.getClientId());
    responseEntity.setRevision(requestEntity.getRevision());
    responseEntity.setProcessorId(requestEntity.getProcessorId());
    responseEntity.setFlowFilePolicy(criteria.getFlowFilePolicy().name());
    responseEntity.setRuleOrder(criteria.getRuleOrder());
    // generate the response
    final ResponseBuilder response = Response.ok(responseEntity);
    return noCache(response).build();
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) NiFiWebConfigurationRequestContext(org.apache.nifi.web.NiFiWebConfigurationRequestContext) EvaluationContextEntity(org.apache.nifi.update.attributes.entity.EvaluationContextEntity) Criteria(org.apache.nifi.update.attributes.Criteria) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) NiFiWebConfigurationContext(org.apache.nifi.web.NiFiWebConfigurationContext) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) PUT(javax.ws.rs.PUT)

Example 7 with Criteria

use of org.apache.nifi.update.attributes.Criteria in project nifi by apache.

the class RuleResource method updateRule.

@PUT
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("/rules/{id}")
public Response updateRule(@Context final UriInfo uriInfo, @PathParam("id") final String ruleId, final RuleEntity requestEntity) {
    // get the web context
    final NiFiWebConfigurationContext nifiWebContext = (NiFiWebConfigurationContext) servletContext.getAttribute("nifi-web-configuration-context");
    // ensure the rule has been specified
    if (requestEntity == null || requestEntity.getRule() == null) {
        throw new WebApplicationException(badRequest("The rule must be specified."));
    }
    final RuleDTO ruleDto = requestEntity.getRule();
    // ensure the id has been specified
    if (ruleDto.getId() == null) {
        throw new WebApplicationException(badRequest("The rule id must be specified."));
    }
    if (!ruleDto.getId().equals(ruleId)) {
        throw new WebApplicationException(badRequest("The rule id in the path does not equal the rule id in the request body."));
    }
    // ensure the rule name was specified
    if (ruleDto.getName() == null || ruleDto.getName().isEmpty()) {
        throw new WebApplicationException(badRequest("The rule name must be specified and cannot be blank."));
    }
    // ensure there are some conditions
    if (ruleDto.getConditions() == null || ruleDto.getConditions().isEmpty()) {
        throw new WebApplicationException(badRequest("The rule conditions must be set."));
    }
    // ensure there are some actions
    if (ruleDto.getActions() == null || ruleDto.getActions().isEmpty()) {
        throw new WebApplicationException(badRequest("The rule actions must be set."));
    }
    // build the web context config
    final NiFiWebConfigurationRequestContext requestContext = getConfigurationRequestContext(requestEntity.getProcessorId(), requestEntity.getRevision(), requestEntity.getClientId());
    // load the criteria
    final UpdateAttributeModelFactory factory = new UpdateAttributeModelFactory();
    final Criteria criteria = getCriteria(nifiWebContext, requestContext);
    // attempt to locate the rule
    Rule rule = criteria.getRule(ruleId);
    // if the rule isn't found add it
    boolean newRule = false;
    if (rule == null) {
        newRule = true;
        rule = new Rule();
        rule.setId(ruleId);
    }
    try {
        // evaluate the conditions and actions before modifying the rule
        final Set<Condition> conditions = factory.createConditions(ruleDto.getConditions());
        final Set<Action> actions = factory.createActions(ruleDto.getActions());
        // update the rule
        rule.setName(ruleDto.getName());
        rule.setConditions(conditions);
        rule.setActions(actions);
    } catch (final IllegalArgumentException iae) {
        throw new WebApplicationException(iae, badRequest(iae.getMessage()));
    }
    // add the new rule if application
    if (newRule) {
        criteria.addRule(rule);
    }
    // save the criteria
    saveCriteria(requestContext, criteria);
    // create the response entity
    final RuleEntity responseEntity = new RuleEntity();
    responseEntity.setClientId(requestEntity.getClientId());
    responseEntity.setRevision(requestEntity.getRevision());
    responseEntity.setProcessorId(requestEntity.getProcessorId());
    responseEntity.setRule(DtoFactory.createRuleDTO(rule));
    // generate the response
    final ResponseBuilder response;
    if (newRule) {
        final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
        response = Response.created(uriBuilder.path(ruleId).build()).entity(responseEntity);
    } else {
        response = Response.ok(responseEntity);
    }
    return noCache(response).build();
}
Also used : Condition(org.apache.nifi.update.attributes.Condition) Action(org.apache.nifi.update.attributes.Action) WebApplicationException(javax.ws.rs.WebApplicationException) RuleDTO(org.apache.nifi.update.attributes.dto.RuleDTO) Criteria(org.apache.nifi.update.attributes.Criteria) NiFiWebConfigurationRequestContext(org.apache.nifi.web.NiFiWebConfigurationRequestContext) UpdateAttributeModelFactory(org.apache.nifi.update.attributes.UpdateAttributeModelFactory) Rule(org.apache.nifi.update.attributes.Rule) RuleEntity(org.apache.nifi.update.attributes.entity.RuleEntity) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) UriBuilder(javax.ws.rs.core.UriBuilder) NiFiWebConfigurationContext(org.apache.nifi.web.NiFiWebConfigurationContext) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) PUT(javax.ws.rs.PUT)

Example 8 with Criteria

use of org.apache.nifi.update.attributes.Criteria in project nifi by apache.

the class CriteriaSerDe method deserialize.

/**
 * Deserializes the specified criteria.
 *
 * @param string the string representation of the criteria
 * @return the criteria object
 */
public static Criteria deserialize(final String string) {
    Criteria criteria = null;
    if (string != null && !string.trim().equals("")) {
        try {
            // deserialize the binding
            final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
            XMLStreamReader xsr = XmlUtils.createSafeReader(new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8)));
            final JAXBElement<CriteriaBinding> element = unmarshaller.unmarshal(xsr, CriteriaBinding.class);
            // create the criteria from the binding
            final CriteriaBinding binding = element.getValue();
            criteria = new Criteria(binding.getFlowFilePolicy(), binding.getRules());
        } catch (final JAXBException | XMLStreamException e) {
            throw new IllegalArgumentException(e);
        }
    }
    return criteria;
}
Also used : XMLStreamReader(javax.xml.stream.XMLStreamReader) XMLStreamException(javax.xml.stream.XMLStreamException) ByteArrayInputStream(java.io.ByteArrayInputStream) JAXBException(javax.xml.bind.JAXBException) Criteria(org.apache.nifi.update.attributes.Criteria) Unmarshaller(javax.xml.bind.Unmarshaller)

Example 9 with Criteria

use of org.apache.nifi.update.attributes.Criteria in project nifi by apache.

the class UpdateAttribute method onTrigger.

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
    final ComponentLog logger = getLogger();
    final Criteria criteria = criteriaCache.get();
    FlowFile incomingFlowFile = session.get();
    if (incomingFlowFile == null) {
        return;
    }
    // record which rule should be applied to which flow file - when operating
    // in 'use clone' mode, this collection will contain a number of entries
    // that map to single element lists. this is because the original flowfile
    // is cloned for each matching rule. in 'use original' mode, this collection
    // will contain a single entry that maps a list of multiple rules. this is
    // because is the original flowfile is used for all matching rules. in this
    // case the order of the matching rules is preserved in the list
    final Map<FlowFile, List<Rule>> matchedRules = new HashMap<>();
    final Map<String, String> stateInitialAttributes;
    final Map<String, String> stateWorkingAttributes;
    StateMap stateMap = null;
    try {
        if (stateful) {
            stateMap = context.getStateManager().getState(Scope.LOCAL);
            stateInitialAttributes = stateMap.toMap();
            stateWorkingAttributes = new HashMap<>(stateMap.toMap());
        } else {
            stateInitialAttributes = null;
            stateWorkingAttributes = null;
        }
    } catch (IOException e) {
        logger.error("Failed to get the initial state when processing {}; transferring FlowFile back to its incoming queue", new Object[] { incomingFlowFile }, e);
        session.transfer(incomingFlowFile);
        context.yield();
        return;
    }
    Map<String, Action> defaultActions = this.defaultActions;
    List<FlowFile> flowFilesToTransfer = new LinkedList<>();
    // if there is update criteria specified, evaluate it
    if (criteria != null && evaluateCriteria(session, context, criteria, incomingFlowFile, matchedRules, stateInitialAttributes)) {
        // apply the actions for each rule and transfer the flowfile
        for (final Map.Entry<FlowFile, List<Rule>> entry : matchedRules.entrySet()) {
            FlowFile match = entry.getKey();
            final List<Rule> rules = entry.getValue();
            boolean updateWorking = incomingFlowFile.equals(match);
            // execute each matching rule(s)
            match = executeActions(session, context, rules, defaultActions, match, stateInitialAttributes, stateWorkingAttributes);
            if (updateWorking) {
                incomingFlowFile = match;
            }
            if (debugEnabled) {
                logger.debug("Updated attributes for {}; transferring to '{}'", new Object[] { match, REL_SUCCESS.getName() });
            }
            // add the match to the list to transfer
            flowFilesToTransfer.add(match);
        }
    } else {
        // Either we're running without any rules or the FlowFile didn't match any
        incomingFlowFile = executeActions(session, context, null, defaultActions, incomingFlowFile, stateInitialAttributes, stateWorkingAttributes);
        if (debugEnabled) {
            logger.debug("Updated attributes for {}; transferring to '{}'", new Object[] { incomingFlowFile, REL_SUCCESS.getName() });
        }
        // add the flowfile to the list to transfer
        flowFilesToTransfer.add(incomingFlowFile);
    }
    if (stateInitialAttributes != null) {
        try {
            // Able to use "equals()" since we're just checking if the map was modified at all
            if (!stateWorkingAttributes.equals(stateInitialAttributes)) {
                boolean setState = context.getStateManager().replace(stateMap, stateWorkingAttributes, Scope.LOCAL);
                if (!setState) {
                    logger.warn("Failed to update the state after successfully processing {} due to having an old version of the StateMap. This is normally due to multiple threads running at " + "once; transferring to '{}'", new Object[] { incomingFlowFile, REL_FAILED_SET_STATE.getName() });
                    flowFilesToTransfer.remove(incomingFlowFile);
                    if (flowFilesToTransfer.size() > 0) {
                        session.remove(flowFilesToTransfer);
                    }
                    session.transfer(incomingFlowFile, REL_FAILED_SET_STATE);
                    return;
                }
            }
        } catch (IOException e) {
            logger.error("Failed to set the state after successfully processing {} due a failure when setting the state. This is normally due to multiple threads running at " + "once; transferring to '{}'", new Object[] { incomingFlowFile, REL_FAILED_SET_STATE.getName() }, e);
            flowFilesToTransfer.remove(incomingFlowFile);
            if (flowFilesToTransfer.size() > 0) {
                session.remove(flowFilesToTransfer);
            }
            session.transfer(incomingFlowFile, REL_FAILED_SET_STATE);
            context.yield();
            return;
        }
    }
    for (FlowFile toTransfer : flowFilesToTransfer) {
        session.getProvenanceReporter().modifyAttributes(toTransfer);
    }
    session.transfer(flowFilesToTransfer, REL_SUCCESS);
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) Action(org.apache.nifi.update.attributes.Action) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) StateMap(org.apache.nifi.components.state.StateMap) Criteria(org.apache.nifi.update.attributes.Criteria) IOException(java.io.IOException) ComponentLog(org.apache.nifi.logging.ComponentLog) LinkedList(java.util.LinkedList) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Rule(org.apache.nifi.update.attributes.Rule) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) StateMap(org.apache.nifi.components.state.StateMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 10 with Criteria

use of org.apache.nifi.update.attributes.Criteria in project nifi by apache.

the class UpdateAttribute method customValidate.

@Override
protected Collection<ValidationResult> customValidate(final ValidationContext context) {
    final List<ValidationResult> reasons = new ArrayList<>(super.customValidate(context));
    if (!context.getProperty(STORE_STATE).getValue().equals(DO_NOT_STORE_STATE)) {
        String initValue = context.getProperty(STATEFUL_VARIABLES_INIT_VALUE).getValue();
        if (initValue == null) {
            reasons.add(new ValidationResult.Builder().subject(STATEFUL_VARIABLES_INIT_VALUE.getDisplayName()).valid(false).explanation("initial state value must be set if the processor is configured to store state.").build());
        }
    }
    Criteria criteria = null;
    try {
        criteria = CriteriaSerDe.deserialize(context.getAnnotationData());
    } catch (IllegalArgumentException iae) {
        reasons.add(new ValidationResult.Builder().valid(false).explanation("Unable to deserialize the update criteria." + iae.getMessage()).build());
    }
    // if there is criteria, validate it
    if (criteria != null) {
        final List<Rule> rules = criteria.getRules();
        if (rules == null) {
            reasons.add(new ValidationResult.Builder().valid(false).explanation("Update criteria has been specified by no rules were found.").build());
        } else {
            // validate the each rule
            for (final Rule rule : rules) {
                if (rule.getName() == null || rule.getName().trim().isEmpty()) {
                    reasons.add(new ValidationResult.Builder().valid(false).explanation("A rule name was not specified.").build());
                }
                // validate each condition
                final Set<Condition> conditions = rule.getConditions();
                if (conditions == null) {
                    reasons.add(new ValidationResult.Builder().valid(false).explanation(String.format("No conditions for rule '%s' found.", rule.getName())).build());
                } else {
                    for (final Condition condition : conditions) {
                        if (condition.getExpression() == null) {
                            reasons.add(new ValidationResult.Builder().valid(false).explanation(String.format("No expression for a condition in rule '%s' was found.", rule.getName())).build());
                        } else {
                            final String expression = condition.getExpression().trim();
                            reasons.add(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.BOOLEAN, false).validate(String.format("Condition for rule '%s'.", rule.getName()), expression, context));
                        }
                    }
                }
                // validate each action
                final Set<Action> actions = rule.getActions();
                if (actions == null) {
                    reasons.add(new ValidationResult.Builder().valid(false).explanation(String.format("No actions for rule '%s' found.", rule.getName())).build());
                } else {
                    for (final Action action : actions) {
                        if (action.getAttribute() == null) {
                            reasons.add(new ValidationResult.Builder().valid(false).explanation(String.format("An action in rule '%s' is missing the attribute name.", rule.getName())).build());
                        } else if (action.getValue() == null) {
                            reasons.add(new ValidationResult.Builder().valid(false).explanation(String.format("No value for attribute '%s' in rule '%s' was found.", action.getAttribute(), rule.getName())).build());
                        } else {
                            reasons.add(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING, true).validate(String.format("Action for rule '%s'.", rule.getName()), action.getValue(), context));
                        }
                    }
                }
            }
        }
    }
    return reasons;
}
Also used : Condition(org.apache.nifi.update.attributes.Condition) Action(org.apache.nifi.update.attributes.Action) ArrayList(java.util.ArrayList) Criteria(org.apache.nifi.update.attributes.Criteria) ValidationResult(org.apache.nifi.components.ValidationResult) Rule(org.apache.nifi.update.attributes.Rule)

Aggregations

Criteria (org.apache.nifi.update.attributes.Criteria)14 Rule (org.apache.nifi.update.attributes.Rule)10 Path (javax.ws.rs.Path)8 Produces (javax.ws.rs.Produces)8 ResponseBuilder (javax.ws.rs.core.Response.ResponseBuilder)8 NiFiWebConfigurationContext (org.apache.nifi.web.NiFiWebConfigurationContext)8 Action (org.apache.nifi.update.attributes.Action)5 RuleDTO (org.apache.nifi.update.attributes.dto.RuleDTO)5 GET (javax.ws.rs.GET)4 WebApplicationException (javax.ws.rs.WebApplicationException)4 NiFiWebConfigurationRequestContext (org.apache.nifi.web.NiFiWebConfigurationRequestContext)4 NiFiWebRequestContext (org.apache.nifi.web.NiFiWebRequestContext)4 ArrayList (java.util.ArrayList)3 Consumes (javax.ws.rs.Consumes)3 NotFoundException (javax.ws.rs.NotFoundException)3 Condition (org.apache.nifi.update.attributes.Condition)3 RuleEntity (org.apache.nifi.update.attributes.entity.RuleEntity)3 RulesEntity (org.apache.nifi.update.attributes.entity.RulesEntity)3 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2