Skip to content

Commit

Permalink
enforcing camel producer interface in buildtime
Browse files Browse the repository at this point in the history
Signed-off-by: Ricardo Zanini <zanini@redhat.com>
  • Loading branch information
ricardozanini committed Dec 14, 2022
1 parent 20a3ac3 commit 78fa07e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
import java.util.Objects;

import org.kie.kogito.addons.quarkus.camel.runtime.CamelConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.kie.kogito.process.expr.ExpressionHandlerFactory;

import com.fasterxml.jackson.databind.JsonNode;

Expand All @@ -36,31 +35,30 @@
*/
public final class CamelFunctionStaticValidator {

private static final Logger LOGGER = LoggerFactory.getLogger(CamelFunctionStaticValidator.class);

private CamelFunctionStaticValidator() {
}

/**
* Validation for the Function Definition within the given Workflow
*
* @param workflow the workflow reference
* @param workflow the workflow reference
* @param functionDefName the name of the function definition
* @throws IllegalArgumentException if the referenced function has more than one argument in the call
*/
public static void validateFunctionDefinition(final Workflow workflow, final String functionDefName) {
for (State state : workflow.getStates()) {
// only states that have actions are valid
switch (state.getType()) {
case OPERATION:
((OperationState) state).getActions().forEach(action -> validateAction(action, functionDefName));
((OperationState) state).getActions().forEach(action -> validateAction(action, functionDefName, workflow));
break;
case FOREACH:
((ForEachState) state).getActions().forEach(action -> validateAction(action, functionDefName));
((ForEachState) state).getActions().forEach(action -> validateAction(action, functionDefName, workflow));
break;
case CALLBACK:
validateAction(((CallbackState) state).getAction(), functionDefName);
validateAction(((CallbackState) state).getAction(), functionDefName, workflow);
break;
// Sonar compliance...
// Sonar compliance
default:
break;
}
Expand All @@ -73,26 +71,57 @@ public static void validateFunctionDefinition(final Workflow workflow, final Str
* @param functionRef the given Function Reference
* @throws IllegalArgumentException if the there's more than one argument in the function call
*/
public static void validateFunctionRef(final FunctionRef functionRef) {
public static void validateFunctionRef(final FunctionRef functionRef, final Workflow workflow) {
final JsonNode jsonNode = functionRef.getArguments();
if (jsonNode == null) {
return;
}
if (jsonNode.size() > 2) {
throw new IllegalArgumentException("Camel functions only support 'body', 'header', or no arguments. Please review the arguments: \n" + jsonNode.asText());
switch (jsonNode.size()) {
case 0:
return;
case 1:
verifyBodyArguments(jsonNode, functionRef);
break;
case 2:
verifyBodyArguments(jsonNode, functionRef);
verifyHeaderArguments(jsonNode, functionRef, workflow);
break;
default:
throw new IllegalArgumentException("Camel functions only support 'body', 'header', or no arguments. Please review the arguments: \n" + jsonNode.asText());
}
}

private static void verifyHeaderArguments(final JsonNode jsonNode, final FunctionRef functionRef, final Workflow workflow) {
final JsonNode headers = jsonNode.get(CamelConstants.HEADERS);
if (headers != null && (headers.isArray() || !headers.isObject())) {
throw new IllegalArgumentException("Camel functions headers arguments must be a key/value object. Please review the arguments: \n" + headers.asText());
if (headers == null) {
throw new IllegalArgumentException(
"Camel functions only support 'body', 'header', or no arguments. "
+ "Please review the arguments for the function '" + functionRef.getRefName() + "': \n" + jsonNode.asText());
}
if (headers.isTextual() && !ExpressionHandlerFactory.get(workflow.getExpressionLang(), headers.asText()).isValid()) {
throw new IllegalArgumentException(
"Camel functions headers arguments must be a valid expression or a key/value object. "
+ "Please review the arguments for the function '" + functionRef.getRefName() + "': \n"
+ headers.asText());
}
if (!headers.isObject()) {
throw new IllegalArgumentException(
"Camel functions headers arguments must be a valid expression or a key/value object. "
+ "Please review the arguments for the function '" + functionRef.getRefName() + "': \n"
+ headers.asText());
}
}

private static void verifyBodyArguments(final JsonNode jsonNode, final FunctionRef functionRef) {
if (jsonNode.get(CamelConstants.BODY) == null) {
LOGGER.warn("No body arguments found in the function reference '{}'. The first parameter will be used as the Camel message body. Please use 'body: { }'.", functionRef.getRefName());
throw new IllegalArgumentException("No body arguments found in the function reference '" + functionRef.getRefName()
+ "'. Please review the function arguments to include a '\"body\": {}' argument.");
}
}

private static void validateAction(final Action action, final String functionDefName) {
private static void validateAction(final Action action, final String functionDefName, final Workflow workflow) {
if (Objects.equals(action.getFunctionRef().getRefName(), functionDefName)) {
validateFunctionRef(action.getFunctionRef());
validateFunctionRef(action.getFunctionRef(), workflow);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class CamelWorkItemFunctionNamespace extends WorkItemFunctionNamespace {
@Override
protected <T extends RuleFlowNodeContainerFactory<T, ?>> WorkItemNodeFactory<T> fillWorkItemHandler(Workflow workflow, ParserContext parserContext, WorkItemNodeFactory<T> workItemNodeFactory,
FunctionRef functionRef) {
CamelFunctionStaticValidator.validateFunctionRef(functionRef);
CamelFunctionStaticValidator.validateFunctionRef(functionRef, workflow);
return workItemNodeFactory.workName(NAME).metaData(OPERATION, getFunctionName(functionRef));
}

Expand Down

0 comments on commit 78fa07e

Please sign in to comment.