Skip to content

Commit 29831cf

Browse files
committed
[Fix #468] Try/raise implementation
Signed-off-by: Francisco Javier Tirado Sarti <ftirados@redhat.com>
1 parent d201c5f commit 29831cf

File tree

18 files changed

+474
-32
lines changed

18 files changed

+474
-32
lines changed

api/src/main/resources/schema/workflow.yaml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -777,19 +777,22 @@ $defs:
777777
errors:
778778
type: object
779779
title: CatchErrors
780-
description: The configuration of a concept used to catch errors.
780+
properties:
781+
with:
782+
$ref: '#/$defs/errorFilter'
783+
description: static error filter
781784
as:
782785
type: string
783786
title: CatchAs
784787
description: The name of the runtime expression variable to save the error as. Defaults to 'error'.
785788
when:
786789
type: string
787790
title: CatchWhen
788-
description: A runtime expression used to determine whether or not to catch the filtered error.
791+
description: A runtime expression used to determine whether to catch the filtered error.
789792
exceptWhen:
790793
type: string
791794
title: CatchExceptWhen
792-
description: A runtime expression used to determine whether or not to catch the filtered error.
795+
description: A runtime expression used to determine whether not to catch the filtered error.
793796
retry:
794797
oneOf:
795798
- $ref: '#/$defs/retryPolicy'
@@ -1152,6 +1155,27 @@ $defs:
11521155
title: ErrorDetails
11531156
description: A human-readable explanation specific to this occurrence of the error.
11541157
required: [ type, status ]
1158+
errorFilter:
1159+
type: object
1160+
title: ErrorFilter
1161+
description: Error filtering base on static values. For error filtering on dynamic values, use catch.when property
1162+
minProperties: 1
1163+
properties:
1164+
type:
1165+
type: string
1166+
description: if present, means this value should be used for filtering
1167+
status:
1168+
type: integer
1169+
description: if present, means this value should be used for filtering
1170+
instance:
1171+
type: string
1172+
description: if present, means this value should be used for filtering
1173+
title:
1174+
type: string
1175+
description: if present, means this value should be used for filtering
1176+
details:
1177+
type: string
1178+
description: if present, means this value should be used for filtering
11551179
uriTemplate:
11561180
title: UriTemplate
11571181
anyOf:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.impl;
17+
18+
import java.util.function.BiFunction;
19+
20+
@FunctionalInterface
21+
public interface StringFilter extends BiFunction<WorkflowContext, TaskContext<?>, String> {}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.impl;
17+
18+
public record WorkflowError(
19+
String type, int status, String instance, String title, String details) {
20+
21+
private static final String ERROR_FORMAT = "https://serverlessworkflow.io/spec/1.0.0/errors/%s";
22+
public static final String RUNTIME_TYPE = String.format(ERROR_FORMAT, "runtime");
23+
public static final String COMM_TYPE = String.format(ERROR_FORMAT, "communication");
24+
25+
public static Builder error(String type, int status) {
26+
return new Builder(type, status);
27+
}
28+
29+
public static Builder communication(int status, TaskContext<?> context, Exception ex) {
30+
return new Builder(COMM_TYPE, status)
31+
.instance(context.position().jsonPointer())
32+
.title(ex.getMessage());
33+
}
34+
35+
public static Builder runtime(int status, TaskContext<?> context, Exception ex) {
36+
return new Builder(RUNTIME_TYPE, status)
37+
.instance(context.position().jsonPointer())
38+
.title(ex.getMessage());
39+
}
40+
41+
public static class Builder {
42+
43+
private final String type;
44+
private int status;
45+
private String instance;
46+
private String title;
47+
private String details;
48+
49+
private Builder(String type, int status) {
50+
this.type = type;
51+
this.status = status;
52+
}
53+
54+
public Builder instance(String instance) {
55+
this.instance = instance;
56+
return this;
57+
}
58+
59+
public Builder title(String title) {
60+
this.title = title;
61+
return this;
62+
}
63+
64+
public Builder details(String details) {
65+
this.details = details;
66+
return this;
67+
}
68+
69+
public WorkflowError build() {
70+
return new WorkflowError(type, status, instance, title, details);
71+
}
72+
}
73+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.impl;
17+
18+
public class WorkflowException extends RuntimeException {
19+
20+
private static final long serialVersionUID = 1L;
21+
22+
private final WorkflowError worflowError;
23+
24+
public WorkflowException(WorkflowError error) {
25+
this(error, null);
26+
}
27+
28+
public WorkflowException(WorkflowError error, Throwable cause) {
29+
super(error.toString(), cause);
30+
this.worflowError = error;
31+
}
32+
33+
public WorkflowError getWorflowError() {
34+
return worflowError;
35+
}
36+
}

impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public class WorkflowInstance {
4040
.inputFilter()
4141
.ifPresent(f -> taskContext.input(f.apply(workflowContext, taskContext, input)));
4242
state = WorkflowState.STARTED;
43-
taskContext.rawOutput(
44-
WorkflowUtils.processTaskList(definition.workflow().getDo(), workflowContext, taskContext));
43+
44+
WorkflowUtils.processTaskList(definition.workflow().getDo(), workflowContext, taskContext);
4545
definition
4646
.outputFilter()
4747
.ifPresent(

impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowPositionFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@
1717

1818
import java.util.function.Supplier;
1919

20+
@FunctionalInterface
2021
public interface WorkflowPositionFactory extends Supplier<WorkflowPosition> {}

impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowUtils.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@ public static Optional<WorkflowFilter> buildWorkflowFilter(
9292
: Optional.empty();
9393
}
9494

95+
public static StringFilter buildStringFilter(
96+
ExpressionFactory exprFactory, String expression, String literal) {
97+
return expression != null ? from(buildWorkflowFilter(exprFactory, expression)) : from(literal);
98+
}
99+
100+
public static StringFilter buildStringFilter(ExpressionFactory exprFactory, String str) {
101+
return ExpressionUtils.isExpr(str) ? from(buildWorkflowFilter(exprFactory, str)) : from(str);
102+
}
103+
104+
public static StringFilter from(WorkflowFilter filter) {
105+
return (w, t) -> filter.apply(w, t, t.input()).asText();
106+
}
107+
108+
private static StringFilter from(String literal) {
109+
return (w, t) -> literal;
110+
}
111+
95112
private static WorkflowFilter buildWorkflowFilter(
96113
ExpressionFactory exprFactory, String str, Object object) {
97114
if (str != null) {
@@ -127,7 +144,7 @@ private static TaskItem findTaskByName(ListIterator<TaskItem> iter, String taskN
127144
throw new IllegalArgumentException("Cannot find task with name " + taskName);
128145
}
129146

130-
public static JsonNode processTaskList(
147+
public static void processTaskList(
131148
List<TaskItem> tasks, WorkflowContext context, TaskContext<?> parentTask) {
132149
parentTask.position().addProperty("do");
133150
TaskContext<? extends TaskBase> currentContext = parentTask;
@@ -136,7 +153,7 @@ public static JsonNode processTaskList(
136153
TaskItem nextTask = iter.next();
137154
while (nextTask != null) {
138155
TaskItem task = nextTask;
139-
parentTask.position().addIndex(iter.nextIndex()).addProperty(task.getName());
156+
parentTask.position().addIndex(iter.previousIndex()).addProperty(task.getName());
140157
context
141158
.definition()
142159
.listeners()
@@ -175,7 +192,7 @@ public static JsonNode processTaskList(
175192
}
176193
}
177194
parentTask.position().back();
178-
return currentContext.output();
195+
parentTask.rawOutput(currentContext.output());
179196
}
180197

181198
public static WorkflowFilter buildWorkflowFilter(ExpressionFactory exprFactory, String str) {

impl/core/src/main/java/io/serverlessworkflow/impl/executors/DefaultTaskExecutorFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public TaskExecutor<? extends TaskBase> getTaskExecutor(
6767
return new SetExecutor(task.getSetTask(), definition);
6868
} else if (task.getForTask() != null) {
6969
return new ForExecutor(task.getForTask(), definition);
70+
} else if (task.getRaiseTask() != null) {
71+
return new RaiseExecutor(task.getRaiseTask(), definition);
72+
} else if (task.getTryTask() != null) {
73+
return new TryExecutor(task.getTryTask(), definition);
7074
}
7175
throw new UnsupportedOperationException(task.get().getClass().getName() + " not supported yet");
7276
}

impl/core/src/main/java/io/serverlessworkflow/impl/executors/DoExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ protected DoExecutor(DoTask task, WorkflowDefinition definition) {
2929

3030
@Override
3131
protected void internalExecute(WorkflowContext workflow, TaskContext<DoTask> taskContext) {
32-
taskContext.rawOutput(WorkflowUtils.processTaskList(task.getDo(), workflow, taskContext));
32+
WorkflowUtils.processTaskList(task.getDo(), workflow, taskContext);
3333
}
3434
}

impl/core/src/main/java/io/serverlessworkflow/impl/executors/ForExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ protected void internalExecute(WorkflowContext workflow, TaskContext<ForTask> ta
5252
JsonNode item = iter.next();
5353
taskContext.variables().put(task.getFor().getEach(), item);
5454
taskContext.variables().put(task.getFor().getAt(), i++);
55-
taskContext.rawOutput(WorkflowUtils.processTaskList(task.getDo(), workflow, taskContext));
55+
WorkflowUtils.processTaskList(task.getDo(), workflow, taskContext);
5656
}
5757
}
5858
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy