Skip to content

Commit 0157f0c

Browse files
authored
[Fix #984] Fixing node response type (#985)
Signed-off-by: fjtirado <ftirados@redhat.com>
1 parent be3f29f commit 0157f0c

File tree

9 files changed

+166
-31
lines changed

9 files changed

+166
-31
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import io.serverlessworkflow.api.types.SchemaInline;
2121
import io.serverlessworkflow.api.types.Workflow;
22+
import io.serverlessworkflow.impl.additional.NamedWorkflowAdditionalObject;
2223
import io.serverlessworkflow.impl.additional.WorkflowAdditionalObject;
2324
import io.serverlessworkflow.impl.config.ConfigManager;
2425
import io.serverlessworkflow.impl.config.ConfigSecretManager;
@@ -172,13 +173,16 @@ public SchemaValidator getValidator(SchemaInline inline) {
172173
() -> new RuntimeDescriptor("reference impl", "1.0.0_alpha", Collections.emptyMap());
173174
private boolean lifeCycleCEPublishingEnabled = true;
174175
private WorkflowModelFactory modelFactory;
175-
private Map<String, WorkflowAdditionalObject<?>> additionalObjects;
176+
private Map<String, WorkflowAdditionalObject<?>> additionalObjects = new HashMap<>();
176177
private SecretManager secretManager;
177178
private ConfigManager configManager;
178179
private SchedulerListener schedulerListener;
179180
private Optional<URITemplateResolver> templateResolver;
180181

181-
private Builder() {}
182+
private Builder() {
183+
ServiceLoader.load(NamedWorkflowAdditionalObject.class)
184+
.forEach(a -> additionalObjects.put(a.name(), a));
185+
}
182186

183187
public Builder withListener(WorkflowExecutionListener listener) {
184188
listeners.add(listener);
@@ -257,9 +261,6 @@ public Builder withConfigManager(ConfigManager configManager) {
257261

258262
public <T> Builder withAdditionalObject(
259263
String name, WorkflowAdditionalObject<T> additionalObject) {
260-
if (additionalObjects == null) {
261-
additionalObjects = new HashMap<>();
262-
}
263264
additionalObjects.put(name, additionalObject);
264265
return this;
265266
}
@@ -314,9 +315,7 @@ public WorkflowApplication build() {
314315
}
315316
schedulerListener = new SchedulerListener(scheduler);
316317
listeners.add(schedulerListener);
317-
if (additionalObjects == null) {
318-
additionalObjects = Collections.emptyMap();
319-
}
318+
320319
if (configManager == null) {
321320
configManager =
322321
ServiceLoader.load(ConfigManager.class)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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.additional;
17+
18+
public interface NamedWorkflowAdditionalObject<T> extends WorkflowAdditionalObject<T> {
19+
String name();
20+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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.executors.http;
17+
18+
import io.serverlessworkflow.impl.TaskContext;
19+
import io.serverlessworkflow.impl.WorkflowContext;
20+
21+
public class HttpConverterResolver {
22+
23+
public static final String HTTP_MODEL_CONVERTER = "httpModelConverter";
24+
25+
private static class DefaultHolder {
26+
private static final HttpModelConverter converter =
27+
new HttpModelConverter() {
28+
@Override
29+
public Class<?> responseType() {
30+
return Object.class;
31+
}
32+
};
33+
}
34+
35+
public static HttpModelConverter converter(
36+
WorkflowContext workflowContext, TaskContext taskContext) {
37+
return workflowContext
38+
.definition()
39+
.application()
40+
.<HttpModelConverter>additionalObject(HTTP_MODEL_CONVERTER, workflowContext, taskContext)
41+
.orElseGet(() -> DefaultHolder.converter);
42+
}
43+
44+
private HttpConverterResolver() {}
45+
}

impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/HttpExecutor.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@
4545

4646
public class HttpExecutor implements CallableTask<CallHTTP> {
4747

48-
// TODO allow changing default converter
49-
private static final HttpModelConverter defaultConverter = new HttpModelConverter() {};
50-
5148
private WorkflowValueResolver<WebTarget> targetSupplier;
5249
private Optional<WorkflowValueResolver<Map<String, Object>>> headersMap;
5350
private Optional<WorkflowValueResolver<Map<String, Object>>> queryMap;
@@ -124,8 +121,7 @@ public HttpExecutor build(WorkflowValueResolver<URI> uriSupplier) {
124121
? getTargetSupplier(uriSupplier)
125122
: getTargetSupplier(uriSupplier, pathSupplier);
126123
executor.authProvider = AuthProviderFactory.getAuth(definition, authPolicy);
127-
executor.requestFunction =
128-
buildRequestSupplier(method, body, definition.application(), defaultConverter);
124+
executor.requestFunction = buildRequestSupplier(method, body, definition.application());
129125
executor.headersMap = Optional.ofNullable(headersMap);
130126
executor.queryMap = Optional.ofNullable(queryMap);
131127
return executor;
@@ -176,27 +172,31 @@ public void init(CallHTTP task, WorkflowDefinition definition) {
176172
: Optional.empty();
177173
this.requestFunction =
178174
buildRequestSupplier(
179-
httpArgs.getMethod().toUpperCase(),
180-
httpArgs.getBody(),
181-
definition.application(),
182-
defaultConverter);
175+
httpArgs.getMethod().toUpperCase(), httpArgs.getBody(), definition.application());
183176
}
184177

185178
private static RequestSupplier buildRequestSupplier(
186-
String method, Object body, WorkflowApplication application, HttpModelConverter converter) {
179+
String method, Object body, WorkflowApplication application) {
180+
187181
switch (method.toUpperCase()) {
188182
case HttpMethod.POST:
189183
WorkflowFilter bodyFilter = WorkflowUtils.buildWorkflowFilter(application, body);
190-
return (request, w, context, node) ->
191-
converter.toModel(
192-
application.modelFactory(),
193-
node,
194-
request.post(
195-
converter.toEntity(bodyFilter.apply(w, context, node)), node.objectClass()));
184+
return (request, w, t, node) -> {
185+
HttpModelConverter converter = HttpConverterResolver.converter(w, t);
186+
return w.definition()
187+
.application()
188+
.modelFactory()
189+
.fromAny(
190+
request.post(
191+
converter.toEntity(bodyFilter.apply(w, t, node)), converter.responseType()));
192+
};
196193
case HttpMethod.GET:
197194
default:
198195
return (request, w, t, n) ->
199-
converter.toModel(application.modelFactory(), n, request.get(n.objectClass()));
196+
w.definition()
197+
.application()
198+
.modelFactory()
199+
.fromAny(request.get(HttpConverterResolver.converter(w, t).responseType()));
200200
}
201201
}
202202

impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/HttpModelConverter.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
package io.serverlessworkflow.impl.executors.http;
1717

1818
import io.serverlessworkflow.impl.WorkflowModel;
19-
import io.serverlessworkflow.impl.WorkflowModelFactory;
2019
import jakarta.ws.rs.client.Entity;
2120

2221
public interface HttpModelConverter {
2322

24-
default WorkflowModel toModel(WorkflowModelFactory factory, WorkflowModel model, Object entity) {
25-
return factory.fromAny(model, entity);
26-
}
27-
28-
default Entity toEntity(WorkflowModel model) {
23+
default Entity<?> toEntity(WorkflowModel model) {
2924
return Entity.json(model.as(model.objectClass()).orElseThrow());
3025
}
26+
27+
Class<?> responseType();
3128
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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.executors.http.jackson;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import io.serverlessworkflow.impl.TaskContextData;
20+
import io.serverlessworkflow.impl.WorkflowContextData;
21+
import io.serverlessworkflow.impl.additional.NamedWorkflowAdditionalObject;
22+
import io.serverlessworkflow.impl.executors.http.HttpConverterResolver;
23+
import io.serverlessworkflow.impl.executors.http.HttpModelConverter;
24+
25+
public class JacksonModelConverterFactory
26+
implements NamedWorkflowAdditionalObject<HttpModelConverter> {
27+
28+
private static class JacksonModelConverterHolder {
29+
30+
private static HttpModelConverter converter =
31+
new HttpModelConverter() {
32+
@Override
33+
public Class<?> responseType() {
34+
return JsonNode.class;
35+
}
36+
};
37+
}
38+
39+
@Override
40+
public HttpModelConverter apply(WorkflowContextData t, TaskContextData u) {
41+
return JacksonModelConverterHolder.converter;
42+
}
43+
44+
@Override
45+
public String name() {
46+
return HttpConverterResolver.HTTP_MODEL_CONVERTER;
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.serverlessworkflow.impl.executors.http.jackson.JacksonModelConverterFactory

impl/test/src/test/java/io/serverlessworkflow/impl/test/HTTPWorkflowDefinitionTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ private static Stream<Arguments> provideParameters() {
106106
"workflows-samples/call-http-endpoint-interpolation.yaml", petInput, petCondition),
107107
Arguments.of(
108108
"workflows-samples/call-http-query-parameters.yaml", starTrekInput, starTrekCondition),
109+
Arguments.of(
110+
"workflows-samples/callFindByStatusHttp.yaml",
111+
Map.of(),
112+
new Condition<WorkflowModel>(o -> !o.asCollection().isEmpty(), "HasElementCondition")),
109113
Arguments.of(
110114
"workflows-samples/call-http-query-parameters-external-schema.yaml",
111115
starTrekInput,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: test
4+
name: http-call-find-by-status
5+
version: 1.0.0
6+
do:
7+
- tryGetPet:
8+
try:
9+
- getPet:
10+
call: http
11+
with:
12+
headers:
13+
content-type: application/json
14+
method: get
15+
endpoint:
16+
uri: https://petstore.swagger.io/v2/pet/findByStatus?status=sold
17+
catch:
18+
errors:
19+
with:
20+
type: https://serverlessworkflow.io/spec/1.0.0/errors/communication
21+
status: 404

0 commit comments

Comments
 (0)