diff --git a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AuthProviderFactory.java b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AuthProviderFactory.java index 86322e1a..b63891f9 100644 --- a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AuthProviderFactory.java +++ b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/AuthProviderFactory.java @@ -16,10 +16,10 @@ package io.serverlessworkflow.impl.executors.http; import io.serverlessworkflow.api.types.AuthenticationPolicyUnion; -import io.serverlessworkflow.api.types.EndpointConfiguration; import io.serverlessworkflow.api.types.ReferenceableAuthenticationPolicy; import io.serverlessworkflow.api.types.Workflow; import io.serverlessworkflow.impl.WorkflowApplication; +import io.serverlessworkflow.impl.WorkflowDefinition; import java.util.Optional; class AuthProviderFactory { @@ -29,18 +29,18 @@ private AuthProviderFactory() {} static final String AUTH_HEADER_NAME = "Authorization"; public static Optional getAuth( - WorkflowApplication app, Workflow workflow, EndpointConfiguration endpointConfiguration) { - if (endpointConfiguration == null) { - return Optional.empty(); - } - ReferenceableAuthenticationPolicy auth = endpointConfiguration.getAuthentication(); + WorkflowDefinition definition, ReferenceableAuthenticationPolicy auth) { if (auth == null) { return Optional.empty(); } if (auth.getAuthenticationPolicyReference() != null) { - return buildFromReference(app, workflow, auth.getAuthenticationPolicyReference().getUse()); + return buildFromReference( + definition.application(), + definition.workflow(), + auth.getAuthenticationPolicyReference().getUse()); } else if (auth.getAuthenticationPolicy() != null) { - return buildFromPolicy(app, workflow, auth.getAuthenticationPolicy()); + return buildFromPolicy( + definition.application(), definition.workflow(), auth.getAuthenticationPolicy()); } return Optional.empty(); } diff --git a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/HttpExecutor.java b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/HttpExecutor.java index 63bcab9d..f912cb58 100644 --- a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/HttpExecutor.java +++ b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/HttpExecutor.java @@ -20,6 +20,7 @@ import io.serverlessworkflow.api.types.CallHTTP; import io.serverlessworkflow.api.types.Endpoint; import io.serverlessworkflow.api.types.HTTPArguments; +import io.serverlessworkflow.api.types.ReferenceableAuthenticationPolicy; import io.serverlessworkflow.api.types.TaskBase; import io.serverlessworkflow.impl.TaskContext; import io.serverlessworkflow.impl.WorkflowApplication; @@ -30,12 +31,14 @@ import io.serverlessworkflow.impl.WorkflowModel; import io.serverlessworkflow.impl.WorkflowValueResolver; import io.serverlessworkflow.impl.executors.CallableTask; +import io.serverlessworkflow.impl.expressions.ExpressionDescriptor; import jakarta.ws.rs.HttpMethod; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.client.WebTarget; +import java.net.URI; import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -44,13 +47,104 @@ public class HttpExecutor implements CallableTask { private static final Client client = ClientBuilder.newClient(); + // TODO allow changing default converter + private static final HttpModelConverter defaultConverter = new HttpModelConverter() {}; private TargetSupplier targetSupplier; private Optional>> headersMap; private Optional>> queryMap; private Optional authProvider; private RequestSupplier requestFunction; - private HttpModelConverter converter = new HttpModelConverter() {}; + + public static class HttpExecutorBuilder { + + private final WorkflowDefinition definition; + + private ReferenceableAuthenticationPolicy authPolicy; + private WorkflowValueResolver> headersMap; + private WorkflowValueResolver> queryMap; + private WorkflowValueResolver pathSupplier; + private Object body; + private boolean redirect; + private String method = HttpMethod.GET; + + private HttpExecutorBuilder(WorkflowDefinition definition) { + this.definition = definition; + } + + public HttpExecutorBuilder withAuth(ReferenceableAuthenticationPolicy policy) { + this.authPolicy = policy; + return this; + } + + public HttpExecutorBuilder withBody(Object body) { + this.body = body; + return this; + } + + public HttpExecutorBuilder withPath(WorkflowValueResolver pathSupplier) { + this.pathSupplier = pathSupplier; + return this; + } + + public HttpExecutorBuilder withHeaders(WorkflowValueResolver> headersMap) { + this.headersMap = headersMap; + return this; + } + + public HttpExecutorBuilder withQueryMap(WorkflowValueResolver> queryMap) { + this.queryMap = queryMap; + return this; + } + + public HttpExecutorBuilder withHeaders(Map headersMap) { + return withHeaders( + definition + .application() + .expressionFactory() + .resolveMap(ExpressionDescriptor.object(headersMap))); + } + + public HttpExecutorBuilder withQueryMap(Map headersMap) { + return withQueryMap( + definition + .application() + .expressionFactory() + .resolveMap(ExpressionDescriptor.object(headersMap))); + } + + public HttpExecutorBuilder withMethod(String method) { + this.method = method; + return this; + } + + public HttpExecutorBuilder redirect(boolean redirect) { + this.redirect = redirect; + return this; + } + + public HttpExecutor build(String uri) { + return build((w, f, n) -> URI.create(uri)); + } + + public HttpExecutor build(WorkflowValueResolver uriSupplier) { + HttpExecutor executor = new HttpExecutor(); + executor.targetSupplier = + pathSupplier == null + ? getTargetSupplier(uriSupplier) + : getTargetSupplier(uriSupplier, pathSupplier); + executor.authProvider = AuthProviderFactory.getAuth(definition, authPolicy); + executor.requestFunction = + buildRequestSupplier(method, body, definition.application(), defaultConverter); + executor.headersMap = Optional.ofNullable(headersMap); + executor.queryMap = Optional.ofNullable(queryMap); + return executor; + } + } + + public static HttpExecutorBuilder builder(WorkflowDefinition definition) { + return new HttpExecutorBuilder(definition); + } @FunctionalInterface private interface RequestSupplier { @@ -60,22 +154,21 @@ WorkflowModel apply( @Override public void init(CallHTTP task, WorkflowDefinition definition) { - HTTPArguments httpArgs = task.getWith(); - - WorkflowApplication application = definition.application(); + final HTTPArguments httpArgs = task.getWith(); + final Endpoint endpoint = httpArgs.getEndpoint(); this.authProvider = - AuthProviderFactory.getAuth( - application, - definition.workflow(), - task.getWith().getEndpoint().getEndpointConfiguration()); + endpoint.getEndpointConfiguration() == null + ? Optional.empty() + : AuthProviderFactory.getAuth( + definition, endpoint.getEndpointConfiguration().getAuthentication()); - this.targetSupplier = getTargetSupplier(definition, httpArgs.getEndpoint()); + this.targetSupplier = getTargetSupplier(definition.resourceLoader().uriSupplier(endpoint)); this.headersMap = httpArgs.getHeaders() != null ? Optional.of( buildMapResolver( - application, + definition.application(), httpArgs.getHeaders().getRuntimeExpression(), httpArgs.getHeaders().getHTTPHeaders() != null ? httpArgs.getHeaders().getHTTPHeaders().getAdditionalProperties() @@ -85,30 +178,36 @@ public void init(CallHTTP task, WorkflowDefinition definition) { httpArgs.getQuery() != null ? Optional.of( buildMapResolver( - application, + definition.application(), httpArgs.getQuery().getRuntimeExpression(), httpArgs.getQuery().getHTTPQuery() != null ? httpArgs.getQuery().getHTTPQuery().getAdditionalProperties() : null)) : Optional.empty(); - switch (httpArgs.getMethod().toUpperCase()) { + this.requestFunction = + buildRequestSupplier( + httpArgs.getMethod().toUpperCase(), + httpArgs.getBody(), + definition.application(), + defaultConverter); + } + + private static RequestSupplier buildRequestSupplier( + String method, Object body, WorkflowApplication application, HttpModelConverter converter) { + switch (method.toUpperCase()) { case HttpMethod.POST: WorkflowValueResolver> bodyFilter = - buildMapResolver(application, null, httpArgs.getBody()); - this.requestFunction = - (request, w, context, node) -> - converter.toModel( - application.modelFactory(), - node, - request.post( - converter.toEntity(bodyFilter.apply(w, context, node)), - node.objectClass())); - break; + buildMapResolver(application, null, body); + return (request, w, context, node) -> + converter.toModel( + application.modelFactory(), + node, + request.post( + converter.toEntity(bodyFilter.apply(w, context, node)), node.objectClass())); case HttpMethod.GET: default: - this.requestFunction = - (request, w, t, n) -> - converter.toModel(application.modelFactory(), n, request.get(n.objectClass())); + return (request, w, t, n) -> + converter.toModel(application.modelFactory(), n, request.get(n.objectClass())); } } @@ -162,26 +261,17 @@ public boolean accept(Class clazz) { return clazz.equals(CallHTTP.class); } + private static TargetSupplier getTargetSupplier(WorkflowValueResolver uriSupplier) { + return (w, t, n) -> client.target(uriSupplier.apply(w, t, n)); + } + private static TargetSupplier getTargetSupplier( - WorkflowDefinition definition, Endpoint endpoint) { + WorkflowValueResolver uriSupplier, WorkflowValueResolver pathSupplier) { return (w, t, n) -> - client.target(definition.resourceLoader().uriSupplier(endpoint).apply(w, t, n)); + client.target(uriSupplier.apply(w, t, n).resolve(pathSupplier.apply(w, t, n))); } private static interface TargetSupplier { WebTarget apply(WorkflowContext workflow, TaskContext task, WorkflowModel node); } - - private static class ExpressionURISupplier implements TargetSupplier { - private WorkflowValueResolver expr; - - public ExpressionURISupplier(WorkflowValueResolver expr) { - this.expr = expr; - } - - @Override - public WebTarget apply(WorkflowContext workflow, TaskContext task, WorkflowModel node) { - return client.target(expr.apply(workflow, task, node)); - } - } } diff --git a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/HttpCallAdapter.java b/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/HttpCallAdapter.java deleted file mode 100644 index 21ddf230..00000000 --- a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/HttpCallAdapter.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.openapi; - -import io.serverlessworkflow.api.types.CallHTTP; -import io.serverlessworkflow.api.types.Endpoint; -import io.serverlessworkflow.api.types.EndpointConfiguration; -import io.serverlessworkflow.api.types.HTTPArguments; -import io.serverlessworkflow.api.types.HTTPHeaders; -import io.serverlessworkflow.api.types.HTTPQuery; -import io.serverlessworkflow.api.types.Headers; -import io.serverlessworkflow.api.types.Query; -import io.serverlessworkflow.api.types.ReferenceableAuthenticationPolicy; -import io.serverlessworkflow.api.types.UriTemplate; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.parameters.Parameter; -import java.net.URI; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -@SuppressWarnings("rawtypes") -class HttpCallAdapter { - - private ReferenceableAuthenticationPolicy auth; - private Map body; - private String contentType; - private Collection headers; - private String method; - private Collection query; - private boolean redirect; - private URI server; - private URI target; - private Map workflowParams; - - HttpCallAdapter auth(ReferenceableAuthenticationPolicy policy) { - if (policy != null) { - this.auth = policy; - } - return this; - } - - HttpCallAdapter body(Map body) { - this.body = body; - return this; - } - - CallHTTP build() { - CallHTTP callHTTP = new CallHTTP(); - - HTTPArguments httpArgs = new HTTPArguments(); - callHTTP.withWith(httpArgs); - - Endpoint endpoint = new Endpoint(); - httpArgs.withEndpoint(endpoint); - - if (this.auth != null) { - EndpointConfiguration endPointConfig = new EndpointConfiguration(); - endPointConfig.setAuthentication(this.auth); - endpoint.setEndpointConfiguration(endPointConfig); - } - - httpArgs.setRedirect(this.redirect); - httpArgs.setMethod(this.method); - - addHttpHeaders(httpArgs); - addQueryParams(httpArgs); - addBody(httpArgs); - - addTarget(endpoint); - - return callHTTP; - } - - HttpCallAdapter contentType(String contentType) { - this.contentType = contentType; - return this; - } - - HttpCallAdapter headers(Collection headers) { - this.headers = headers; - return this; - } - - HttpCallAdapter method(String method) { - this.method = method; - return this; - } - - HttpCallAdapter query(Collection query) { - this.query = query; - return this; - } - - HttpCallAdapter redirect(boolean redirect) { - this.redirect = redirect; - return this; - } - - HttpCallAdapter server(String server) { - this.server = URI.create(server); - return this; - } - - HttpCallAdapter target(URI target) { - this.target = target; - return this; - } - - HttpCallAdapter workflowParams(Map workflowParams) { - this.workflowParams = workflowParams; - return this; - } - - private void addBody(HTTPArguments httpArgs) { - Map bodyContent = new LinkedHashMap<>(); - if (!(body == null || body.isEmpty())) { - for (Map.Entry entry : body.entrySet()) { - String name = entry.getKey(); - if (workflowParams.containsKey(name)) { - Object value = workflowParams.get(name); - bodyContent.put(name, value); - } - } - if (!bodyContent.isEmpty()) { - httpArgs.setBody(bodyContent); - } - } - } - - private void addHttpHeaders(HTTPArguments httpArgs) { - if (!(headers == null || headers.isEmpty())) { - Headers hdrs = new Headers(); - HTTPHeaders httpHeaders = new HTTPHeaders(); - hdrs.setHTTPHeaders(httpHeaders); - httpArgs.setHeaders(hdrs); - - for (Parameter p : headers) { - String name = p.getName(); - if (workflowParams.containsKey(name)) { - Object value = workflowParams.get(name); - if (value instanceof String asString) { - httpHeaders.setAdditionalProperty(name, asString); - } else { - throw new IllegalArgumentException("Header parameter " + name + " must be a String"); - } - } - } - } - } - - private void addQueryParams(HTTPArguments httpArgs) { - if (!(query == null || query.isEmpty())) { - Query queryParams = new Query(); - httpArgs.setQuery(queryParams); - HTTPQuery httpQuery = new HTTPQuery(); - queryParams.setHTTPQuery(httpQuery); - - for (Parameter p : query) { - String name = p.getName(); - if (workflowParams.containsKey(name)) { - Object value = workflowParams.get(name); - if (value instanceof String asString) { - httpQuery.setAdditionalProperty(name, asString); - } else if (value instanceof Number asNumber) { - httpQuery.setAdditionalProperty(name, asNumber.toString()); - } else if (value instanceof Boolean asBoolean) { - httpQuery.setAdditionalProperty(name, asBoolean.toString()); - } else if (value instanceof Character asCharacter) { - httpQuery.setAdditionalProperty(name, asCharacter.toString()); - } else { - httpQuery.setAdditionalProperty(name, value.toString()); - } - } - } - } - } - - private void addTarget(Endpoint endpoint) { - if (this.target == null) { - throw new IllegalArgumentException("No Server defined for the OpenAPI operation"); - } - UriTemplate uriTemplate = new UriTemplate(); - uriTemplate.withLiteralUri(this.server.resolve(this.target.getPath())); - endpoint.setUriTemplate(uriTemplate); - } -} diff --git a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIExecutor.java b/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIExecutor.java index 2dd65d8b..0ea78ddb 100644 --- a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIExecutor.java +++ b/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIExecutor.java @@ -15,97 +15,113 @@ */ package io.serverlessworkflow.impl.executors.openapi; -import io.serverlessworkflow.api.types.CallHTTP; import io.serverlessworkflow.api.types.CallOpenAPI; +import io.serverlessworkflow.api.types.ExternalResource; import io.serverlessworkflow.api.types.OpenAPIArguments; import io.serverlessworkflow.api.types.TaskBase; import io.serverlessworkflow.impl.TaskContext; +import io.serverlessworkflow.impl.WorkflowApplication; import io.serverlessworkflow.impl.WorkflowContext; import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.WorkflowModel; import io.serverlessworkflow.impl.executors.CallableTask; import io.serverlessworkflow.impl.executors.http.HttpExecutor; +import io.serverlessworkflow.impl.executors.http.HttpExecutor.HttpExecutorBuilder; +import io.serverlessworkflow.impl.resources.ResourceLoaderUtils; +import io.swagger.v3.oas.models.parameters.Parameter; +import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; public class OpenAPIExecutor implements CallableTask { - private OperationDefinitionSupplier operationDefinitionSupplier; - private OpenAPIArguments with; + private OpenAPIProcessor processor; + private ExternalResource resource; + private Map parameters; + private HttpExecutorBuilder builder; @Override public boolean accept(Class clazz) { return clazz.equals(CallOpenAPI.class); } + @Override + public void init(CallOpenAPI task, WorkflowDefinition definition) { + OpenAPIArguments with = task.getWith(); + this.processor = new OpenAPIProcessor(with.getOperationId()); + this.resource = with.getDocument(); + this.parameters = with.getParameters().getAdditionalProperties(); + this.builder = + HttpExecutor.builder(definition) + .withAuth(with.getAuthentication()) + .redirect(with.isRedirect()); + } + @Override public CompletableFuture apply( WorkflowContext workflowContext, TaskContext taskContext, WorkflowModel input) { + Collection executors = + workflowContext + .definition() + .resourceLoader() + .>load( + resource, + r -> { + OperationDefinition o = processor.parse(ResourceLoaderUtils.readString(r)); + fillHttpBuilder(workflowContext.definition().application(), o); + return o.getServers().stream().map(s -> builder.build(s)).toList(); + }, + workflowContext, + taskContext, + input); - OperationDefinition operation = - operationDefinitionSupplier.get(workflowContext, taskContext, input); - HttpCallAdapter httpCallAdapter = - getHttpCallAdapter(operation, workflowContext, taskContext, input); - - Iterator iter = operation.getServers().iterator(); + Iterator iter = executors.iterator(); if (!iter.hasNext()) { throw new IllegalArgumentException( - "List of servers is empty for operation " + operation.getOperation()); + "List of servers is empty for schema " + resource.getName()); } CompletableFuture future = - executeServer(iter.next(), httpCallAdapter, workflowContext, taskContext, input); + iter.next().apply(workflowContext, taskContext, input); while (iter.hasNext()) { - future.exceptionallyCompose( - i -> executeServer(iter.next(), httpCallAdapter, workflowContext, taskContext, input)); + future.exceptionallyCompose(i -> iter.next().apply(workflowContext, taskContext, input)); } return future; } - private CompletableFuture executeServer( - String server, - HttpCallAdapter callAdapter, - WorkflowContext workflowContext, - TaskContext taskContext, - WorkflowModel input) { - CallHTTP callHTTP = callAdapter.server(server).build(); - HttpExecutor executor = new HttpExecutor(); - executor.init(callHTTP, workflowContext.definition()); - return executor.apply(workflowContext, taskContext, input); - } + private void fillHttpBuilder(WorkflowApplication application, OperationDefinition operation) { + Map headersMap = new HashMap(); + Map queryMap = new HashMap(); + Map pathParameters = new HashMap(); - @Override - public void init(CallOpenAPI task, WorkflowDefinition definition) { - with = task.getWith(); - operationDefinitionSupplier = new OperationDefinitionSupplier(definition.application(), with); - } + Map bodyParameters = new HashMap<>(parameters); + for (Parameter parameter : operation.getParameters()) { + switch (parameter.getIn()) { + case "header": + param(parameter.getName(), bodyParameters, headersMap); + break; + case "path": + param(parameter.getName(), bodyParameters, pathParameters); + break; + case "query": + param(parameter.getName(), bodyParameters, queryMap); + break; + } + } - private HttpCallAdapter getHttpCallAdapter( - OperationDefinition operation, - WorkflowContext workflowContext, - TaskContext taskContext, - WorkflowModel input) { - OperationPathResolver pathResolver = - new OperationPathResolver( - operation.getPath(), - workflowContext.definition().application(), - with.getParameters().getAdditionalProperties()); + builder + .withMethod(operation.getMethod()) + .withPath(new OperationPathResolver(operation.getPath(), application, pathParameters)) + .withBody(bodyParameters) + .withQueryMap(queryMap) + .withHeaders(headersMap); + } - return new HttpCallAdapter() - .auth(with.getAuthentication()) - .body(operation.getBody()) - .contentType(operation.getContentType()) - .headers( - operation.getParameters().stream() - .filter(p -> "header".equals(p.getIn())) - .collect(Collectors.toUnmodifiableSet())) - .method(operation.getMethod()) - .query( - operation.getParameters().stream() - .filter(p -> "query".equals(p.getIn())) - .collect(Collectors.toUnmodifiableSet())) - .redirect(with.isRedirect()) - .target(pathResolver.resolve(workflowContext, taskContext, input)) - .workflowParams(with.getParameters().getAdditionalProperties()); + private void param(String name, Map origMap, Map collectorMap) { + Object value = origMap.remove(name); + if (value != null) { + collectorMap.put(name, value); + } } } diff --git a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationDefinitionSupplier.java b/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationDefinitionSupplier.java deleted file mode 100644 index 5254fdd8..00000000 --- a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationDefinitionSupplier.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.openapi; - -import io.serverlessworkflow.api.types.ExternalResource; -import io.serverlessworkflow.api.types.OpenAPIArguments; -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowContext; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.resources.ResourceLoaderUtils; - -class OperationDefinitionSupplier { - - private final OpenAPIProcessor processor; - private final ExternalResource resource; - - OperationDefinitionSupplier(WorkflowApplication application, OpenAPIArguments with) { - this.processor = new OpenAPIProcessor(with.getOperationId()); - this.resource = with.getDocument(); - } - - OperationDefinition get( - WorkflowContext workflowContext, TaskContext taskContext, WorkflowModel input) { - return workflowContext - .definition() - .resourceLoader() - .load( - resource, - r -> processor.parse(ResourceLoaderUtils.readString(r)), - workflowContext, - taskContext, - input); - } -} diff --git a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationPathResolver.java b/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationPathResolver.java index d9c808e4..5ca95d31 100644 --- a/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationPathResolver.java +++ b/impl/openapi/src/main/java/io/serverlessworkflow/impl/executors/openapi/OperationPathResolver.java @@ -25,21 +25,17 @@ import java.net.URI; import java.util.Map; -class OperationPathResolver { - - private final Map args; +class OperationPathResolver implements WorkflowValueResolver { private final String path; - private WorkflowApplication application; + private final WorkflowValueResolver> asMap; OperationPathResolver(String path, WorkflowApplication application, Map args) { this.path = path; - this.args = args; - this.application = application; + this.asMap = application.expressionFactory().resolveMap(ExpressionDescriptor.object(args)); } - URI resolve(WorkflowContext workflow, TaskContext task, WorkflowModel model) { - WorkflowValueResolver> asMap = - application.expressionFactory().resolveMap(ExpressionDescriptor.object(args)); + @Override + public URI apply(WorkflowContext workflow, TaskContext task, WorkflowModel model) { return UriBuilder.fromUri(path) .resolveTemplates(asMap.apply(workflow, task, model), false) .build();