Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public class WorkflowApplication implements AutoCloseable {
private final WorkflowLifeCycleCloudEventFactory lifeCycleCloudEventFactory;
private final ScheduledExecutorService schedulerExecutorService;
private final Set<String> allowedCommands;
private final Map<Class<?>, List<?>> serviceLoadedClasses = new ConcurrentHashMap<>();

private WorkflowApplication(Builder builder) {
this.taskFactory = builder.taskFactory;
Expand Down Expand Up @@ -708,4 +709,24 @@ public WorkflowLifeCycleCloudEventFactory lifeCycleCloudEventFactory() {
public Set<String> allowedCommands() {
return allowedCommands;
}

@SuppressWarnings("unchecked")
public <T extends Comparable<?>> List<T> serviceLoadedClasses(Class<T> clazz) {
return (List<T>)
serviceLoadedClasses.computeIfAbsent(
clazz,
c ->
ServiceLoader.load(clazz).stream()
.map(ServiceLoader.Provider::get)
.sorted()
.toList());
Comment thread
fjtirado marked this conversation as resolved.
}
Comment thread
fjtirado marked this conversation as resolved.
Comment thread
fjtirado marked this conversation as resolved.

public <T extends Comparable<?>> T serviceLoadedClass(Class<T> serviceClass) {
List<T> list = serviceLoadedClasses(serviceClass);
if (list.isEmpty()) {
throw new IllegalStateException("No " + serviceClass + " implementation found");
}
return list.get(0);
}
Comment thread
fjtirado marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
package io.serverlessworkflow.impl.auth;

import static io.serverlessworkflow.impl.WorkflowUtils.checkSecret;
import static io.serverlessworkflow.impl.WorkflowUtils.loadFirst;
import static io.serverlessworkflow.impl.WorkflowUtils.secret;

import io.serverlessworkflow.api.types.OAuth2AuthenticationData;
import io.serverlessworkflow.api.types.SecretBasedAuthenticationPolicy;
import io.serverlessworkflow.api.types.Workflow;
import io.serverlessworkflow.impl.TaskContext;
import io.serverlessworkflow.impl.WorkflowApplication;
import io.serverlessworkflow.impl.WorkflowContext;
import io.serverlessworkflow.impl.WorkflowModel;
import io.serverlessworkflow.impl.WorkflowValueResolver;
Expand All @@ -35,14 +35,6 @@ public abstract class CommonOAuthProvider implements AuthProvider {

private final WorkflowValueResolver<AccessTokenProvider> tokenProvider;

private static JWTConverter jwtConverter =
loadFirst(JWTConverter.class)
.orElseThrow(() -> new IllegalStateException("No JWTConverter implementation found"));

private static AccessTokenProviderFactory accessTokenProviderFactory =
loadFirst(AccessTokenProviderFactory.class)
.orElseThrow(() -> new IllegalStateException("No JWTConverter implementation found"));

protected CommonOAuthProvider(WorkflowValueResolver<AccessTokenProvider> tokenProvider) {
this.tokenProvider = tokenProvider;
}
Expand All @@ -67,35 +59,42 @@ protected static OAuth2AuthenticationData fillFromMap(
}

protected static WorkflowValueResolver<AccessTokenProvider> accessToken(
WorkflowApplication app,
Workflow workflow,
OAuth2AuthenticationData authenticationData,
SecretBasedAuthenticationPolicy secret,
AuthRequestBuilder<?> builder) {
if (authenticationData != null) {
return build(authenticationData, builder);
return build(authenticationData, builder, app);
} else if (secret != null) {
return build(checkSecret(workflow, secret), builder);
return build(checkSecret(workflow, secret), builder, app);
}
throw new IllegalStateException("Both policy and secret are null");
}

private static WorkflowValueResolver<AccessTokenProvider> build(
OAuth2AuthenticationData authenticationData, AuthRequestBuilder authBuilder) {
OAuth2AuthenticationData authenticationData,
AuthRequestBuilder authBuilder,
WorkflowApplication app) {
AccessTokenProvider tokenProvider =
accessTokenProviderFactory.build(
authBuilder.apply(authenticationData), authenticationData.getIssuers(), jwtConverter);
app.serviceLoadedClass(AccessTokenProviderFactory.class)
.build(
authBuilder.apply(authenticationData),
authenticationData.getIssuers(),
app.serviceLoadedClass(JWTConverter.class));
return (w, t, m) -> tokenProvider;
}

private static WorkflowValueResolver<AccessTokenProvider> build(
String secretName, AuthRequestBuilder authBuilder) {
String secretName, AuthRequestBuilder authBuilder, WorkflowApplication app) {
return (w, t, m) -> {
Map<String, Object> secret = secret(w, secretName);
String issuers = (String) secret.get("issuers");
return accessTokenProviderFactory.build(
authBuilder.apply(secret),
issuers != null ? Arrays.asList(issuers.split(",")) : null,
jwtConverter);
return app.serviceLoadedClass(AccessTokenProviderFactory.class)
.build(
authBuilder.apply(secret),
issuers != null ? Arrays.asList(issuers.split(",")) : null,
app.serviceLoadedClass(JWTConverter.class));
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public OAuth2AuthProvider(
WorkflowApplication application, Workflow workflow, OAuthPolicyData policyData) {
super(
accessToken(
application,
workflow,
policyData.data(),
policyData.secret(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public OpenIdAuthProvider(
WorkflowApplication application, Workflow workflow, OAuthPolicyData policyData) {
super(
accessToken(
application,
workflow,
policyData.data(),
policyData.secret(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,10 @@
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.concurrent.CompletableFuture;

public class EmitExecutor extends RegularTaskExecutor<EmitTask> {

private static final Collection<EmittedEventDecorator> emittedDecorators =
ServiceLoader.load(EmittedEventDecorator.class).stream()
.map(ServiceLoader.Provider::get)
.sorted()
.toList();
private final EventPropertiesBuilder props;

public static class EmitExecutorBuilder
Expand Down Expand Up @@ -139,7 +133,11 @@ private CloudEvent buildCloudEvent(WorkflowContext workflow, TaskContext taskCon
.additionalFilter()
.map(filter -> filter.apply(workflow, taskContext, taskContext.input()))
.ifPresent(value -> value.forEach((k, v) -> addExtension(ceBuilder, k, v)));
emittedDecorators.forEach(d -> d.decorate(ceBuilder, workflow, taskContext));
workflow
.definition()
.application()
.serviceLoadedClasses(EmittedEventDecorator.class)
.forEach(d -> d.decorate(ceBuilder, workflow, taskContext));
return ceBuilder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import io.serverlessworkflow.impl.scripts.ScriptRunner;
import java.util.Objects;
import java.util.Optional;
import java.util.ServiceLoader;

public class RunScriptExecutorBuilder implements RunnableTaskBuilder<RunScript> {

Expand Down Expand Up @@ -65,10 +64,8 @@ public CallableTask build(RunScript taskConfiguration, WorkflowDefinition defini
m),
taskConfiguration.isAwait(),
taskConfiguration.getReturn(),
ServiceLoader.load(ScriptRunner.class).stream()
.map(ServiceLoader.Provider::get)
application.serviceLoadedClasses(ScriptRunner.class).stream()
.filter(s -> s.identifier().equals(language))
.sorted()
.findFirst()
.orElseThrow(
() ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,12 @@
import io.serverlessworkflow.impl.WorkflowDefinition;
import io.serverlessworkflow.impl.WorkflowModel;
import io.serverlessworkflow.impl.WorkflowMutablePosition;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.concurrent.CompletableFuture;

public class RunTaskExecutor extends RegularTaskExecutor<RunTask> {

private final CallableTask runnable;

private static final ServiceLoader<RunnableTaskBuilder> runnables =
ServiceLoader.load(RunnableTaskBuilder.class);

public static class RunTaskExecutorBuilder
extends RegularTaskExecutorBuilder<RunTask, RunTaskExecutor> {
private CallableTask runnable;
Expand All @@ -42,10 +37,8 @@ protected RunTaskExecutorBuilder(
super(position, task, definition);
RunTaskConfiguration config = task.getRun().get();
this.runnable =
runnables.stream()
.map(Provider::get)
definition.application().serviceLoadedClasses(RunnableTaskBuilder.class).stream()
.filter(r -> r.accept(config.getClass()))
.sorted()
.findFirst()
.map(r -> r.build(config, definition))
.orElseThrow(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;

public class HttpExecutorBuilder {

public static final String HTTP_REQUEST_DECORATOR_KEY = "HttpRequestDecorators";
private final WorkflowDefinition definition;
private final List<HttpRequestDecorator> requestDecorators;
private List<HttpRequestDecorator> requestDecorators;
private WorkflowValueResolver<URI> pathSupplier;
private Object body;
private String method = HttpMethod.GET;
Expand All @@ -47,13 +46,13 @@ public class HttpExecutorBuilder {

private HttpExecutorBuilder(WorkflowDefinition definition) {
this.definition = definition;
this.requestDecorators = new ArrayList<>();
this.requestDecorators =
new ArrayList<>(definition.application().serviceLoadedClasses(HttpRequestDecorator.class));
requestDecorators.addAll(
definition
.application()
.<Collection<HttpRequestDecorator>>additionalObject(HTTP_REQUEST_DECORATOR_KEY)
.orElse(List.of()));
ServiceLoader.load(HttpRequestDecorator.class).forEach(requestDecorators::add);
Collections.sort(requestDecorators);
}

Expand Down
Loading