Skip to content

Commit 1b4d6fc

Browse files
committed
Add taskInput taskOutput and workflowInput
Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com>
1 parent 4b9a780 commit 1b4d6fc

3 files changed

Lines changed: 131 additions & 558 deletions

File tree

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/EnrichWithModelBiFunction.java

Lines changed: 0 additions & 39 deletions
This file was deleted.

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java

Lines changed: 81 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer;
3333
import io.serverlessworkflow.impl.TaskContextData;
3434
import io.serverlessworkflow.impl.WorkflowContextData;
35-
import io.serverlessworkflow.impl.WorkflowModel;
36-
import io.serverlessworkflow.impl.jackson.JsonUtils;
3735
import java.net.URI;
3836
import java.util.Collection;
3937
import java.util.List;
@@ -281,123 +279,6 @@ public static FuncPredicateEventConfigurer event(String type) {
281279
return OPS.event(type);
282280
}
283281

284-
/**
285-
* Create an input transformation that enriches the typed last state with the root workflow input
286-
* as WorkflowModel.
287-
*
288-
* <p>This is useful when you want to combine the last task output (with its actual type) with the
289-
* original workflow input as WorkflowModel.
290-
*
291-
* <p>Example usage:
292-
*
293-
* <pre>{@code
294-
* function("processData", (Long input) -> input + 5, Long.class),
295-
* function("combineData", (Long enrichedValue) -> enrichedValue, Long.class)
296-
* .inputFrom(
297-
* FuncDSL.enrichInput((Long lastState, WorkflowModel rootInputModel) -> {
298-
* Long rootInput = rootInputModel.as(Long.class).orElse(0L);
299-
* return lastState + rootInput;
300-
* }),
301-
* Long.class)
302-
* }</pre>
303-
*
304-
* @param fn the enrichment function that receives typed lastState and WorkflowModel rootInput
305-
* @param <T> the type of the last state
306-
* @param <R> the type of the enriched result
307-
* @return a JavaContextFunction that can be used with inputFrom
308-
*/
309-
public static <T, R> JavaContextFunction<T, R> enrichInput(EnrichWithModelBiFunction<T, R> fn) {
310-
return (lastState, workflowContext) -> {
311-
final WorkflowModel rootInput = workflowContext.instanceData().input();
312-
return fn.apply(lastState, rootInput);
313-
};
314-
}
315-
316-
/**
317-
* Create an input transformation that uses only the root workflow input as WorkflowModel.
318-
*
319-
* <p>This is useful when you want to transform the task input based solely on the original
320-
* workflow input, ignoring the last state.
321-
*
322-
* <p>Example usage:
323-
*
324-
* <pre>{@code
325-
* function("processData", (Long input) -> input * 2, Long.class)
326-
* .inputFrom(enrichInput(rootInput -> rootInput.asNumber().orElseThrow()))
327-
* }</pre>
328-
*
329-
* @param fn the function that receives the root workflow input and returns the enriched result
330-
* @param <R> the type of the enriched result
331-
* @return a JavaContextFunction that can be used with inputFrom
332-
*/
333-
public static <R> JavaContextFunction<Object, R> enrichInput(Function<WorkflowModel, R> fn) {
334-
return (lastState, workflowContext) -> {
335-
final WorkflowModel rootInput = workflowContext.instanceData().input();
336-
return fn.apply(rootInput);
337-
};
338-
}
339-
340-
/**
341-
* Create an output transformation that enriches the typed task output with the root workflow
342-
* input as WorkflowModel.
343-
*
344-
* <p>This is useful when you want to combine the task output (converted to a specific type) with
345-
* the original workflow input as WorkflowModel. The task output will be converted to the
346-
* specified type using Jackson conversion before being passed to the enrichment function.
347-
*
348-
* <p>Example usage:
349-
*
350-
* <pre>{@code
351-
* // Task returns Long, but we want to work with it as Integer in the enrichment function
352-
* function("processData", (Long input) -> input + 5, Long.class)
353-
* .outputAs(FuncDSL.enrichOutput((taskOutput, rootInputModel) -> {
354-
* // taskOutput is converted from Long to Integer
355-
* Long rootInput = rootInputModel.as(Long.class).orElse(0L);
356-
* return taskOutput + rootInput.intValue();
357-
* }, Integer.class))
358-
* }</pre>
359-
*
360-
* @param fn the enrichment function that receives typed taskOutput and WorkflowModel rootInput
361-
* @param taskOutputClass the target type to convert the task output to before passing it to the
362-
* enrichment function
363-
* @param <T> the target type for the task output conversion
364-
* @param <R> the type of the enriched result
365-
* @return a JavaContextFunction that can be used with outputAs
366-
*/
367-
public static <T, R> JavaContextFunction<T, R> enrichOutput(
368-
EnrichWithModelBiFunction<T, R> fn, Class<T> taskOutputClass) {
369-
return (taskOutput, workflowContext) -> {
370-
Objects.requireNonNull(taskOutputClass, "taskOutputClass must not be null");
371-
final WorkflowModel rootInput = workflowContext.instanceData().input();
372-
final T typedTaskOutput = JsonUtils.convertValue(taskOutput, taskOutputClass);
373-
return fn.apply(typedTaskOutput, rootInput);
374-
};
375-
}
376-
377-
/**
378-
* Create an output transformation that uses only the root workflow input as WorkflowModel.
379-
*
380-
* <p>This is useful when you want to transform the task output based solely on the original
381-
* workflow input, ignoring the actual task output.
382-
*
383-
* <p>Example usage:
384-
*
385-
* <pre>{@code
386-
* function("processData", (Long input) -> input * 2, Long.class)
387-
* .outputAs(FuncDSL.enrichOutput(rootInput -> rootInput.asNumber().orElseThrow()))
388-
* }</pre>
389-
*
390-
* @param fn the function that receives the root workflow input and returns the enriched result
391-
* @param <R> the type of the enriched result
392-
* @return a JavaContextFunction that can be used with outputAs
393-
*/
394-
public static <R> JavaContextFunction<Object, R> enrichOutput(Function<WorkflowModel, R> fn) {
395-
return (ignore, workflowContext) -> {
396-
final WorkflowModel rootInput = workflowContext.instanceData().input();
397-
return fn.apply(rootInput);
398-
};
399-
}
400-
401282
/**
402283
* Create a {@link FuncCallStep} that calls a simple Java {@link Function} with explicit input
403284
* type.
@@ -1441,4 +1322,85 @@ public static FuncCallHttpStep post(
14411322

14421323
return http(name).POST().endpoint(endpoint, auth).body(body);
14431324
}
1325+
1326+
/**
1327+
* Extracts and deserializes the workflow input data into the specified type from a workflow
1328+
* context.
1329+
*
1330+
* <p>This utility method provides type-safe access to the workflow's initial input.
1331+
*
1332+
* <p>Use this method when you have access to the {@link WorkflowContextData} and need to retrieve
1333+
* the original input that was provided when the workflow instance was started.
1334+
*
1335+
* <p><b>Usage Example:</b>
1336+
*
1337+
* <pre>{@code
1338+
* inputFrom((object, WorkflowContextData workflowContext) -> {
1339+
* OrderRequest order = workflowInput(workflowContext, OrderRequest.class);
1340+
* return new Input(order);
1341+
* }
1342+
* }</pre>
1343+
*
1344+
* @param <T> the type to deserialize the input into
1345+
* @param context the workflow context containing instance data and input
1346+
* @param inputClass the class object representing the target type for deserialization
1347+
* @return the deserialized workflow input object of type T
1348+
*/
1349+
public static <T> T taskInput(WorkflowContextData context, Class<T> inputClass) {
1350+
return context.instanceData().input().as(inputClass).orElseThrow();
1351+
}
1352+
1353+
/**
1354+
* Extracts and deserializes the workflow input data into the specified type from a task context.
1355+
*
1356+
* <p>This utility method provides type-safe access to the workflow's initial input.
1357+
*
1358+
* <p>Use this method when you only have access to the {@link TaskContextData} but need to
1359+
* retrieve the original workflow input (not the task's input). This is useful when a task needs
1360+
* to reference the initial workflow input data.
1361+
*
1362+
* <p><b>Usage Example:</b>
1363+
*
1364+
* <pre>{@code
1365+
* inputFrom((Object obj, TaskContextData taskContextData) -> {
1366+
* OrderRequest order = taskInput(taskContextData, OrderRequest.class);
1367+
* return new Input(order);
1368+
* }
1369+
* }</pre>
1370+
*
1371+
* @param <T> the type to deserialize the input into
1372+
* @param taskContextData the task context from which to retrieve the workflow input
1373+
* @param inputClass the class object representing the target type for deserialization
1374+
* @return the deserialized workflow input object of type T
1375+
*/
1376+
public static <T> T taskInput(TaskContextData taskContextData, Class<T> inputClass) {
1377+
return taskContextData.input().as(inputClass).orElseThrow();
1378+
}
1379+
1380+
/**
1381+
* Extracts and deserializes the output data from a task into the specified type.
1382+
*
1383+
* <p>This utility method provides type-safe access to a task's output.
1384+
*
1385+
* <p>Use this method when you need to access the result/output produced by a task execution. This
1386+
* is particularly useful in subsequent tasks that need to process or transform the output of a
1387+
* previous task in the workflow.
1388+
*
1389+
* <p><b>Usage Example:</b>
1390+
*
1391+
* <pre>{@code
1392+
* .exportAs((object, workflowContext, taskContextData) -> {
1393+
* Long input = taskOutput(taskContextData, Long.class);
1394+
* return input * 2;
1395+
* }))
1396+
* }</pre>
1397+
*
1398+
* @param <T> the type to deserialize the task output into
1399+
* @param taskContextData the task context containing the output data
1400+
* @param inputClass the class object representing the target type for deserialization
1401+
* @return the deserialized task output object of type T
1402+
*/
1403+
public static <T> T taskOutput(TaskContextData taskContextData, Class<T> inputClass) {
1404+
return taskContextData.output().as(inputClass).orElseThrow();
1405+
}
14441406
}

0 commit comments

Comments
 (0)