Skip to content

Commit 27bb3c0

Browse files
committed
tests and refactoring
Signed-off-by: Dmitrii Tikhomirov <chani.liet@gmail.com>
1 parent 3745db6 commit 27bb3c0

File tree

12 files changed

+400
-115
lines changed

12 files changed

+400
-115
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.openapi;
17+
18+
import io.serverlessworkflow.impl.TaskContext;
19+
import io.serverlessworkflow.impl.WorkflowContext;
20+
import io.serverlessworkflow.impl.WorkflowModel;
21+
import io.serverlessworkflow.impl.WorkflowValueResolver;
22+
import java.net.URI;
23+
24+
class ExpressionURISupplier implements TargetSupplier {
25+
private WorkflowValueResolver<String> resolver;
26+
27+
ExpressionURISupplier(WorkflowValueResolver<String> resolver) {
28+
this.resolver = resolver;
29+
}
30+
31+
@Override
32+
public URI apply(WorkflowContext workflow, TaskContext task, WorkflowModel node) {
33+
return URI.create(resolver.apply(workflow, task, node));
34+
}
35+
}

impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/HttpCallAdapter.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import java.util.Map;
3737

3838
@SuppressWarnings("rawtypes")
39-
public class HttpCallAdapter {
39+
class HttpCallAdapter {
4040

4141
private ReferenceableAuthenticationPolicy auth;
4242
private Map<String, Schema> body;
@@ -49,19 +49,19 @@ public class HttpCallAdapter {
4949
private URI target;
5050
private Map<String, Object> workflowParams;
5151

52-
public HttpCallAdapter auth(ReferenceableAuthenticationPolicy policy) {
52+
HttpCallAdapter auth(ReferenceableAuthenticationPolicy policy) {
5353
if (policy != null) {
5454
this.auth = policy;
5555
}
5656
return this;
5757
}
5858

59-
public HttpCallAdapter body(Map<String, Schema> body) {
59+
HttpCallAdapter body(Map<String, Schema> body) {
6060
this.body = body;
6161
return this;
6262
}
6363

64-
public CallHTTP build() {
64+
CallHTTP build() {
6565
CallHTTP callHTTP = new CallHTTP();
6666

6767
HTTPArguments httpArgs = new HTTPArguments();
@@ -96,43 +96,42 @@ public CallHTTP build() {
9696
return callHTTP;
9797
}
9898

99-
public HttpCallAdapter contentType(String contentType) {
99+
HttpCallAdapter contentType(String contentType) {
100100
this.contentType = contentType;
101101
return this;
102102
}
103103

104-
public HttpCallAdapter headers(
105-
Collection<io.swagger.v3.oas.models.parameters.Parameter> headers) {
104+
HttpCallAdapter headers(Collection<io.swagger.v3.oas.models.parameters.Parameter> headers) {
106105
this.headers = headers;
107106
return this;
108107
}
109108

110-
public HttpCallAdapter method(String method) {
109+
HttpCallAdapter method(String method) {
111110
this.method = method;
112111
return this;
113112
}
114113

115-
public HttpCallAdapter query(Collection<io.swagger.v3.oas.models.parameters.Parameter> query) {
114+
HttpCallAdapter query(Collection<io.swagger.v3.oas.models.parameters.Parameter> query) {
116115
this.query = query;
117116
return this;
118117
}
119118

120-
public HttpCallAdapter redirect(boolean redirect) {
119+
HttpCallAdapter redirect(boolean redirect) {
121120
this.redirect = redirect;
122121
return this;
123122
}
124123

125-
public HttpCallAdapter server(String server) {
124+
HttpCallAdapter server(String server) {
126125
this.server = URI.create(server);
127126
return this;
128127
}
129128

130-
public HttpCallAdapter target(URI target) {
129+
HttpCallAdapter target(URI target) {
131130
this.target = target;
132131
return this;
133132
}
134133

135-
public HttpCallAdapter workflowParams(Map<String, Object> workflowParams) {
134+
HttpCallAdapter workflowParams(Map<String, Object> workflowParams) {
136135
this.workflowParams = workflowParams;
137136
return this;
138137
}
@@ -194,10 +193,7 @@ private void addQueryParams(HTTPArguments httpArgs) {
194193
} else if (value instanceof Character asCharacter) {
195194
httpQuery.setAdditionalProperty(name, asCharacter.toString());
196195
} else {
197-
throw new IllegalArgumentException(
198-
"Query parameter "
199-
+ name
200-
+ " must be a type of String, Number, Boolean or Character");
196+
httpQuery.setAdditionalProperty(name, value.toString());
201197
}
202198
}
203199
}

impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIExecutor.java

Lines changed: 56 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,15 @@
2626
import io.serverlessworkflow.impl.WorkflowApplication;
2727
import io.serverlessworkflow.impl.WorkflowContext;
2828
import io.serverlessworkflow.impl.WorkflowDefinition;
29+
import io.serverlessworkflow.impl.WorkflowException;
2930
import io.serverlessworkflow.impl.WorkflowModel;
30-
import io.serverlessworkflow.impl.WorkflowValueResolver;
3131
import io.serverlessworkflow.impl.executors.CallableTask;
3232
import io.serverlessworkflow.impl.executors.http.HttpExecutor;
3333
import io.serverlessworkflow.impl.expressions.ExpressionDescriptor;
3434
import io.serverlessworkflow.impl.expressions.ExpressionFactory;
3535
import io.serverlessworkflow.impl.resources.ResourceLoader;
3636
import jakarta.ws.rs.core.UriBuilder;
3737
import java.net.URI;
38-
import java.util.Objects;
3938
import java.util.concurrent.CompletableFuture;
4039
import java.util.stream.Collectors;
4140

@@ -49,39 +48,6 @@ public class OpenAPIExecutor implements CallableTask<CallOpenAPI> {
4948

5049
private ResourceLoader resourceLoader;
5150

52-
private static TargetSupplier getTargetSupplier(
53-
Endpoint endpoint, ExpressionFactory expressionFactory) {
54-
if (endpoint.getEndpointConfiguration() != null) {
55-
EndpointUri uri = endpoint.getEndpointConfiguration().getUri();
56-
if (uri.getLiteralEndpointURI() != null) {
57-
return getURISupplier(uri.getLiteralEndpointURI());
58-
} else if (uri.getExpressionEndpointURI() != null) {
59-
return new ExpressionURISupplier(
60-
expressionFactory.resolveString(
61-
ExpressionDescriptor.from(uri.getExpressionEndpointURI())));
62-
}
63-
} else if (endpoint.getRuntimeExpression() != null) {
64-
return new ExpressionURISupplier(
65-
expressionFactory.resolveString(
66-
ExpressionDescriptor.from(endpoint.getRuntimeExpression())));
67-
} else if (endpoint.getUriTemplate() != null) {
68-
return getURISupplier(endpoint.getUriTemplate());
69-
}
70-
throw new IllegalArgumentException("Invalid endpoint definition " + endpoint);
71-
}
72-
73-
private static TargetSupplier getURISupplier(UriTemplate template) {
74-
if (template.getLiteralUri() != null) {
75-
return (w, t, n) -> template.getLiteralUri();
76-
} else if (template.getLiteralUriTemplate() != null) {
77-
return (w, t, n) ->
78-
UriBuilder.fromUri(template.getLiteralUriTemplate())
79-
.resolveTemplates(n.asMap().orElseThrow(), false)
80-
.build();
81-
}
82-
throw new IllegalArgumentException("Invalid uritemplate definition " + template);
83-
}
84-
8551
@Override
8652
public boolean accept(Class<? extends TaskBase> clazz) {
8753
return clazz.equals(CallOpenAPI.class);
@@ -90,52 +56,53 @@ public boolean accept(Class<? extends TaskBase> clazz) {
9056
@Override
9157
public CompletableFuture<WorkflowModel> apply(
9258
WorkflowContext workflowContext, TaskContext taskContext, WorkflowModel input) {
93-
9459
String operationId = task.getWith().getOperationId();
9560
URI openAPIEndpoint = targetSupplier.apply(workflowContext, taskContext, input);
9661
OpenAPIProcessor processor = new OpenAPIProcessor(operationId, openAPIEndpoint);
9762
OperationDefinition operation = processor.parse();
9863

9964
OperationPathResolver pathResolver =
100-
new OperationPathResolver(operation.getPath(), input.asMap().orElseThrow());
101-
URI resolvedPath = pathResolver.passPathParams().apply(workflowContext, taskContext, input);
102-
103-
HttpCallAdapter httpCallAdapter =
104-
new HttpCallAdapter()
105-
.auth(task.getWith().getAuthentication())
106-
.body(operation.getBody())
107-
.contentType(operation.getContentType())
108-
.headers(
109-
operation.getParameters().stream()
110-
.filter(p -> "header".equals(p.getIn()))
111-
.collect(Collectors.toUnmodifiableSet()))
112-
.method(operation.getMethod())
113-
.query(
114-
operation.getParameters().stream()
115-
.filter(p -> "query".equals(p.getIn()))
116-
.collect(Collectors.toUnmodifiableSet()))
117-
.redirect(task.getWith().isRedirect())
118-
.target(resolvedPath)
119-
.workflowParams(task.getWith().getParameters().getAdditionalProperties());
65+
new OperationPathResolver(
66+
operation.getPath(),
67+
application,
68+
task.getWith().getParameters().getAdditionalProperties());
12069

12170
return CompletableFuture.supplyAsync(
12271
() -> {
123-
RuntimeException ex = null;
72+
HttpCallAdapter httpCallAdapter =
73+
new HttpCallAdapter()
74+
.auth(task.getWith().getAuthentication())
75+
.body(operation.getBody())
76+
.contentType(operation.getContentType())
77+
.headers(
78+
operation.getParameters().stream()
79+
.filter(p -> "header".equals(p.getIn()))
80+
.collect(Collectors.toUnmodifiableSet()))
81+
.method(operation.getMethod())
82+
.query(
83+
operation.getParameters().stream()
84+
.filter(p -> "query".equals(p.getIn()))
85+
.collect(Collectors.toUnmodifiableSet()))
86+
.redirect(task.getWith().isRedirect())
87+
.target(pathResolver.resolve(workflowContext, taskContext, input))
88+
.workflowParams(task.getWith().getParameters().getAdditionalProperties());
89+
90+
WorkflowException workflowException = null;
91+
12492
for (var server : operation.getServers()) {
12593
CallHTTP callHTTP = httpCallAdapter.server(server).build();
12694
HttpExecutor executor = new HttpExecutor();
12795
executor.init(callHTTP, definition);
12896

12997
try {
13098
return executor.apply(workflowContext, taskContext, input).get();
99+
} catch (WorkflowException e) {
100+
workflowException = e;
131101
} catch (Exception e) {
132-
133-
System.out.println("Call to " + server + " failed: " + e.getMessage());
134-
ex = new RuntimeException(e);
102+
throw new RuntimeException(e);
135103
}
136104
}
137-
Objects.requireNonNull(ex, "Should have at least one exception");
138-
throw ex; // if we there, we failed all servers and ex is not null
105+
throw workflowException; // if we there, we failed all servers and ex is not null
139106
},
140107
workflowContext.definition().application().executorService());
141108
}
@@ -153,20 +120,35 @@ public void init(CallOpenAPI task, WorkflowDefinition definition) {
153120
task.getWith().getDocument().getEndpoint(), application.expressionFactory());
154121
}
155122

156-
public interface TargetSupplier {
157-
URI apply(WorkflowContext workflow, TaskContext taskContext, WorkflowModel input);
158-
}
159-
160-
private static class ExpressionURISupplier implements TargetSupplier {
161-
private WorkflowValueResolver<String> expr;
162-
163-
public ExpressionURISupplier(WorkflowValueResolver<String> expr) {
164-
this.expr = expr;
123+
private TargetSupplier getTargetSupplier(Endpoint endpoint, ExpressionFactory expressionFactory) {
124+
if (endpoint.getEndpointConfiguration() != null) {
125+
EndpointUri uri = endpoint.getEndpointConfiguration().getUri();
126+
if (uri.getLiteralEndpointURI() != null) {
127+
return getURISupplier(uri.getLiteralEndpointURI());
128+
} else if (uri.getExpressionEndpointURI() != null) {
129+
return new ExpressionURISupplier(
130+
expressionFactory.resolveString(
131+
ExpressionDescriptor.from(uri.getExpressionEndpointURI())));
132+
}
133+
} else if (endpoint.getRuntimeExpression() != null) {
134+
return new ExpressionURISupplier(
135+
expressionFactory.resolveString(
136+
ExpressionDescriptor.from(endpoint.getRuntimeExpression())));
137+
} else if (endpoint.getUriTemplate() != null) {
138+
return getURISupplier(endpoint.getUriTemplate());
165139
}
140+
throw new IllegalArgumentException("Invalid endpoint definition " + endpoint);
141+
}
166142

167-
@Override
168-
public URI apply(WorkflowContext workflow, TaskContext task, WorkflowModel node) {
169-
return URI.create(expr.apply(workflow, task, node));
143+
private TargetSupplier getURISupplier(UriTemplate template) {
144+
if (template.getLiteralUri() != null) {
145+
return (w, t, n) -> template.getLiteralUri();
146+
} else if (template.getLiteralUriTemplate() != null) {
147+
return (w, t, n) ->
148+
UriBuilder.fromUri(template.getLiteralUriTemplate())
149+
.resolveTemplates(n.asMap().orElseThrow(), false)
150+
.build();
170151
}
152+
throw new IllegalArgumentException("Invalid uri template definition " + template);
171153
}
172154
}

impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIProcessor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@
2424
import java.util.List;
2525
import java.util.Set;
2626

27-
public class OpenAPIProcessor {
27+
class OpenAPIProcessor {
2828

2929
private final String operationId;
3030
private final URI openAPIEndpoint;
3131

32-
public OpenAPIProcessor(String operationId, URI openAPIEndpoint) {
32+
OpenAPIProcessor(String operationId, URI openAPIEndpoint) {
3333
this.operationId = operationId;
3434
this.openAPIEndpoint = openAPIEndpoint;
3535
}
3636

37-
public OperationDefinition parse() {
37+
OperationDefinition parse() {
3838
OpenAPIV3Parser parser = new OpenAPIV3Parser();
3939
ParseOptions opts = new ParseOptions();
4040
opts.setResolve(true);
@@ -45,7 +45,7 @@ public OperationDefinition parse() {
4545
return getOperation(openapi);
4646
}
4747

48-
public OperationDefinition getOperation(OpenAPI openAPI) {
48+
OperationDefinition getOperation(OpenAPI openAPI) {
4949
if (openAPI == null || openAPI.getPaths() == null) {
5050
throw new IllegalArgumentException("Invalid OpenAPI document");
5151
}

0 commit comments

Comments
 (0)