Skip to content

[Fix #1209] Adding Context and Filter predicate#1224

Merged
fjtirado merged 2 commits intoserverlessworkflow:mainfrom
fjtirado:Fix_#1209
Mar 13, 2026
Merged

[Fix #1209] Adding Context and Filter predicate#1224
fjtirado merged 2 commits intoserverlessworkflow:mainfrom
fjtirado:Fix_#1209

Conversation

@fjtirado
Copy link
Collaborator

@fjtirado fjtirado commented Mar 12, 2026

Fix #1209

Also, as suggested by @ricardozanini, Java prefix is removed from functions.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #1209 by expanding Java predicate/function support to optionally receive workflow and task context, enabling context-aware filtering and evaluation across the experimental Java runtime and fluent DSL.

Changes:

  • Introduces new context-aware predicate/function types (ContextPredicate, FilterPredicate, ContextFunction, FilterFunction) plus typed wrappers.
  • Updates switch/listen/for execution paths to build predicates/functions from the new container/wrapper types.
  • Refactors the fluent DSL and tests to use the renamed/updated function interfaces and new switch predicate container type.

Reviewed changes

Copilot reviewed 41 out of 41 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/UntilPredicate.java Stores predicates as Object (typed wrappers) and implements PredicateContainer to support multiple predicate shapes.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterPredicate.java Adds typed wrapper for FilterPredicate argument conversion.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterFunction.java Adds typed wrapper for FilterFunction argument conversion.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextPredicate.java Adds typed wrapper for ContextPredicate argument conversion.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextFunction.java Renames typed context function wrapper to match new ContextFunction interface.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SwitchCasePredicate.java New switch-case container supporting plain/typed/context/task-aware predicates.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SwitchCaseFunction.java Removes the old SwitchCaseFunction container implementation.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/PredicateContainer.java Introduces a common interface for types that “carry” a predicate object.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/OutputAsFunction.java Updates overloads to use FilterFunction / ContextFunction and new typed wrappers.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexFilter.java Adds loop predicate shape that receives workflow/task context.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexContext.java Adds loop predicate shape that receives workflow context.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/InputFromFunction.java Updates overloads to use FilterFunction / ContextFunction and new typed wrappers.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ForTaskFunction.java Extends while predicate options to include index + workflow/task context forms.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterPredicate.java Introduces predicate that receives workflow + task context.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterFunction.java Renames JavaFilterFunction to FilterFunction (context+task-aware function).
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ExportAsFunction.java Updates overloads to use FilterFunction / ContextFunction and new typed wrappers.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataPredicate.java Adds context-aware predicate overloads for event data filtering.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextPredicate.java Introduces predicate that receives workflow context.
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextFunction.java Renames JavaContextFunction to ContextFunction (workflow-context-aware function).
experimental/types/src/main/java/io/serverlessworkflow/api/types/func/CallJava.java Updates call variants and nested types to use ContextFunction / FilterFunction.
experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallTest.java Updates switch predicate test to use SwitchCasePredicate.
experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallJavaContextFunctionTest.java Updates test to use ContextFunction.
experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java Adds predicate building for new predicate types and typed wrappers; updates priority logic.
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaSwitchExecutorBuilder.java Switch executor now uses SwitchCasePredicate and JavaFuncUtils.from(...).
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaListenExecutorBuilder.java Listen executor now uses UntilPredicate + JavaFuncUtils.from(...).
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFuncUtils.java Replaces old typed-predicate construction helper with predicate-container based predicate building.
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaForExecutorBuilder.java Passes workflow/task context into the new loop predicate signature.
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFilterFunctionCallExecutorBuilder.java Updates builder to use FilterFunction.
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFilterFunctionCallExecutor.java Updates executor to call FilterFunction.apply(...).
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaContextFunctionCallExecutorBuilder.java Updates builder to use ContextFunction.
experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaContextFunctionCallExecutor.java Updates executor to call ContextFunction.apply(...).
experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLUniqueIdTest.java Updates test extraction/casts to FilterFunction.
experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java Updates DSL tests to use FilterFunction.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTransformations.java Updates DSL transformation interfaces to accept ContextFunction / FilterFunction.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTaskTransformations.java Updates task-specific transformation interfaces to accept ContextFunction / FilterFunction.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java Updates DSL Step APIs + Javadoc references to renamed function interfaces.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ReflectionUtils.java Updates type inference helpers to accept ContextFunction / FilterFunction.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java Updates DSL entrypoints and internal wrappers to use renamed function interfaces.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallStep.java Updates internal step representation to store ContextFunction / FilterFunction.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSwitchTaskBuilder.java Switch DSL builder now constructs SwitchCasePredicate.
experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallTaskBuilder.java Call-task DSL builder now accepts ContextFunction / FilterFunction.
Comments suppressed due to low confidence (2)

experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterFunction.java:25

  • This change renames the public API type JavaFilterFunction to FilterFunction (and similarly for context variants) across modules. That’s a breaking change beyond the stated goal of adding optional context parameters; if intentional, it should be called out in the PR description/release notes and (if needed) provide migration guidance or deprecation shims.
    experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java:136
  • buildIfFilter(...) still only recognizes Predicate and TypedPredicate. With the new ContextPredicate / FilterPredicate (and typed variants), when/if predicates stored in metadata will be silently ignored. Extend this method to handle the new predicate types the same way buildPredicate(...) does.
  public Optional<WorkflowPredicate> buildIfFilter(TaskBase task) {
    TaskMetadata metadata = task.getMetadata();
    if (metadata != null) {
      Object obj = metadata.getAdditionalProperties().get(TaskMetadataKeys.IF_PREDICATE);
      if (obj instanceof Predicate pred) {
        return Optional.of(fromPredicate(pred));
      } else if (obj instanceof TypedPredicate pred) {
        return Optional.of(fromPredicate(pred));
      }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 12, 2026 11:54
Signed-off-by: fjtirado <ftirados@redhat.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java:118

  • Test comment and assertion message still reference JavaFilterFunction, but the API type is now FilterFunction. Updating these strings will avoid confusion when reading failures and keep tests aligned with the renamed API.
    // JavaFilterFunction<T,R> is (T, WorkflowContextData, TaskContextData) -> R
    FilterFunction<String, Map<String, Object>> jf =
        (val, wfCtx, taskCtx) -> Map.of("wrapped", val, "wfId", wfCtx.instanceData().id());

    Workflow wf =
        FuncWorkflowBuilder.workflow("step-emit-export")
            .tasks(emit("emitWrapped", spec).exportAs(jf)) // chaining on Step
            .build();

    List<TaskItem> items = wf.getDo();
    assertEquals(1, items.size());
    Task t = items.get(0).getTask();
    assertNotNull(t.getEmitTask(), "EmitTask expected");

    // Export is attached to Task
    Export ex = t.getEmitTask().getExport();
    assertNotNull(ex, "Export should be set via Step.exportAs(JavaFilterFunction)");
    assertNotNull(ex.getAs(), "'as' should be populated");

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Member

@ricardozanini ricardozanini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but Co-Pilot is pointing out a few null checks that I think are worth adding.

@fjtirado
Copy link
Collaborator Author

LGTM, but Co-Pilot is pointing out a few null checks that I think are worth adding.

Yes, I handle them a bit differently from what copilot recommended, if class is null, lets use the non typed variant.

Copilot AI review requested due to automatic review settings March 13, 2026 12:17
Signed-off-by: fjtirado <ftirados@redhat.com>
@fjtirado fjtirado merged commit f263728 into serverlessworkflow:main Mar 13, 2026
3 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated 8 comments.

Comments suppressed due to low confidence (1)

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSwitchTaskBuilder.java:67

  • The Objects.requireNonNull failure message says "When is required", but this branch is validating that then is present for a default case. Update the message to reflect what is actually required (e.g., "Then is required") to avoid confusing users.
    if (switchCaseValue.predicate() == null) {
      Objects.requireNonNull(switchCaseValue.getThen(), "When is required");
      if (switchCaseValue.getThen().getFlowDirectiveEnum() != null) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +50 to 52
public <T, V> OutputAs withFunction(ContextFunction<T, V> value, Class<T> argClass) {
setObject(new TypedContextFunction<>(value, argClass));
return this;

public <T, V> InputFrom withFunction(JavaContextFunction<T, V> value, Class<T> argClass) {
setObject(new TypedJavaContextFunction<>(value, argClass));
public <T, V> InputFrom withFunction(ContextFunction<T, V> value, Class<T> argClass) {

public <T, V> ExportAs withFunction(JavaFilterFunction<T, V> value, Class<T> argClass) {
setObject(new TypedJavaFilterFunction<>(value, argClass));
public <T, V> ExportAs withFunction(FilterFunction<T, V> value, Class<T> argClass) {
Comment on lines +31 to 36
static WorkflowPredicate from(WorkflowApplication application, PredicateContainer source) {
assert (source.predicate() != null);
return application
.expressionFactory()
.buildPredicate(ExpressionDescriptor.object(source.predicate()));
}
Comment on lines +111 to +113
private WorkflowPredicate fromPredicate(ContextPredicate pred) {
return (w, t, n) -> pred.test(n.asJavaObject(), w);
}
Comment on lines +40 to 42
public <T, V> OutputAs withFunction(FilterFunction<T, V> value, Class<T> argClass) {
setObject(new TypedFilterFunction<>(value, argClass));
return this;
Comment on lines +40 to 42
public <T, V> InputFrom withFunction(FilterFunction<T, V> value, Class<T> argClass) {
setObject(new TypedFilterFunction<>(value, argClass));
return this;

public <T, V> ExportAs withFunction(JavaContextFunction<T, V> value, Class<T> argClass) {
setObject(new TypedJavaContextFunction<>(value, argClass));
public <T, V> ExportAs withFunction(ContextFunction<T, V> value, Class<T> argClass) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Experimental] Add WorkflowContext and TaskContext to Java predicates

3 participants