Skip to content

Commit 2a4b372

Browse files
committed
[Fix #1611] Allow reloading by checking when application is created
Signed-off-by: Francisco Javier Tirado Sarti <ftirados@ibm.com>
1 parent a7f0d13 commit 2a4b372

8 files changed

Lines changed: 50 additions & 61 deletions

File tree

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public class WorkflowApplication implements AutoCloseable {
114114
private final WorkflowLifeCycleCloudEventFactory lifeCycleCloudEventFactory;
115115
private final ScheduledExecutorService schedulerExecutorService;
116116
private final Set<String> allowedCommands;
117+
private final Map<Class<?>, List<?>> serviceLoadedClasses = new ConcurrentHashMap<>();
117118

118119
private WorkflowApplication(Builder builder) {
119120
this.taskFactory = builder.taskFactory;
@@ -708,4 +709,16 @@ public WorkflowLifeCycleCloudEventFactory lifeCycleCloudEventFactory() {
708709
public Set<String> allowedCommands() {
709710
return allowedCommands;
710711
}
712+
713+
@SuppressWarnings("unchecked")
714+
public <T> List<T> getServiceLoadedClasses(Class<T> clazz) {
715+
return (List<T>)
716+
serviceLoadedClasses.computeIfAbsent(
717+
clazz,
718+
c ->
719+
ServiceLoader.load(clazz).stream()
720+
.map(ServiceLoader.Provider::get)
721+
.sorted()
722+
.toList());
723+
}
711724
}

impl/core/src/main/java/io/serverlessworkflow/impl/auth/CommonOAuthProvider.java

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
package io.serverlessworkflow.impl.auth;
1717

1818
import static io.serverlessworkflow.impl.WorkflowUtils.checkSecret;
19-
import static io.serverlessworkflow.impl.WorkflowUtils.loadFirst;
2019
import static io.serverlessworkflow.impl.WorkflowUtils.secret;
2120

2221
import io.serverlessworkflow.api.types.OAuth2AuthenticationData;
2322
import io.serverlessworkflow.api.types.SecretBasedAuthenticationPolicy;
2423
import io.serverlessworkflow.api.types.Workflow;
2524
import io.serverlessworkflow.impl.TaskContext;
25+
import io.serverlessworkflow.impl.WorkflowApplication;
2626
import io.serverlessworkflow.impl.WorkflowContext;
2727
import io.serverlessworkflow.impl.WorkflowModel;
2828
import io.serverlessworkflow.impl.WorkflowValueResolver;
@@ -35,14 +35,6 @@ public abstract class CommonOAuthProvider implements AuthProvider {
3535

3636
private final WorkflowValueResolver<AccessTokenProvider> tokenProvider;
3737

38-
private static JWTConverter jwtConverter =
39-
loadFirst(JWTConverter.class)
40-
.orElseThrow(() -> new IllegalStateException("No JWTConverter implementation found"));
41-
42-
private static AccessTokenProviderFactory accessTokenProviderFactory =
43-
loadFirst(AccessTokenProviderFactory.class)
44-
.orElseThrow(() -> new IllegalStateException("No JWTConverter implementation found"));
45-
4638
protected CommonOAuthProvider(WorkflowValueResolver<AccessTokenProvider> tokenProvider) {
4739
this.tokenProvider = tokenProvider;
4840
}
@@ -67,35 +59,44 @@ protected static OAuth2AuthenticationData fillFromMap(
6759
}
6860

6961
protected static WorkflowValueResolver<AccessTokenProvider> accessToken(
62+
WorkflowApplication app,
7063
Workflow workflow,
7164
OAuth2AuthenticationData authenticationData,
7265
SecretBasedAuthenticationPolicy secret,
7366
AuthRequestBuilder<?> builder) {
7467
if (authenticationData != null) {
75-
return build(authenticationData, builder);
68+
return build(authenticationData, builder, app);
7669
} else if (secret != null) {
77-
return build(checkSecret(workflow, secret), builder);
70+
return build(checkSecret(workflow, secret), builder, app);
7871
}
7972
throw new IllegalStateException("Both policy and secret are null");
8073
}
8174

8275
private static WorkflowValueResolver<AccessTokenProvider> build(
83-
OAuth2AuthenticationData authenticationData, AuthRequestBuilder authBuilder) {
76+
OAuth2AuthenticationData authenticationData,
77+
AuthRequestBuilder authBuilder,
78+
WorkflowApplication app) {
8479
AccessTokenProvider tokenProvider =
85-
accessTokenProviderFactory.build(
86-
authBuilder.apply(authenticationData), authenticationData.getIssuers(), jwtConverter);
80+
app.getServiceLoadedClasses(AccessTokenProviderFactory.class)
81+
.get(0)
82+
.build(
83+
authBuilder.apply(authenticationData),
84+
authenticationData.getIssuers(),
85+
app.getServiceLoadedClasses(JWTConverter.class).get(0));
8786
return (w, t, m) -> tokenProvider;
8887
}
8988

9089
private static WorkflowValueResolver<AccessTokenProvider> build(
91-
String secretName, AuthRequestBuilder authBuilder) {
90+
String secretName, AuthRequestBuilder authBuilder, WorkflowApplication app) {
9291
return (w, t, m) -> {
9392
Map<String, Object> secret = secret(w, secretName);
9493
String issuers = (String) secret.get("issuers");
95-
return accessTokenProviderFactory.build(
96-
authBuilder.apply(secret),
97-
issuers != null ? Arrays.asList(issuers.split(",")) : null,
98-
jwtConverter);
94+
return app.getServiceLoadedClasses(AccessTokenProviderFactory.class)
95+
.get(0)
96+
.build(
97+
authBuilder.apply(secret),
98+
issuers != null ? Arrays.asList(issuers.split(",")) : null,
99+
app.getServiceLoadedClasses(JWTConverter.class).get(0));
99100
};
100101
}
101102
}

impl/core/src/main/java/io/serverlessworkflow/impl/auth/OAuth2AuthProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public OAuth2AuthProvider(
2424
WorkflowApplication application, Workflow workflow, OAuthPolicyData policyData) {
2525
super(
2626
accessToken(
27+
application,
2728
workflow,
2829
policyData.data(),
2930
policyData.secret(),

impl/core/src/main/java/io/serverlessworkflow/impl/auth/OpenIdAuthProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public OpenIdAuthProvider(
2424
WorkflowApplication application, Workflow workflow, OAuthPolicyData policyData) {
2525
super(
2626
accessToken(
27+
application,
2728
workflow,
2829
policyData.data(),
2930
policyData.secret(),

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,10 @@
4141
import java.util.Collection;
4242
import java.util.Map;
4343
import java.util.Optional;
44-
import java.util.ServiceLoader;
4544
import java.util.concurrent.CompletableFuture;
4645

4746
public class EmitExecutor extends RegularTaskExecutor<EmitTask> {
4847

49-
private static final Collection<EmittedEventDecorator> emittedDecorators =
50-
ServiceLoader.load(EmittedEventDecorator.class).stream()
51-
.map(ServiceLoader.Provider::get)
52-
.sorted()
53-
.toList();
5448
private final EventPropertiesBuilder props;
5549

5650
public static class EmitExecutorBuilder
@@ -139,7 +133,11 @@ private CloudEvent buildCloudEvent(WorkflowContext workflow, TaskContext taskCon
139133
.additionalFilter()
140134
.map(filter -> filter.apply(workflow, taskContext, taskContext.input()))
141135
.ifPresent(value -> value.forEach((k, v) -> addExtension(ceBuilder, k, v)));
142-
emittedDecorators.forEach(d -> d.decorate(ceBuilder, workflow, taskContext));
136+
workflow
137+
.definition()
138+
.application()
139+
.getServiceLoadedClasses(EmittedEventDecorator.class)
140+
.forEach(d -> d.decorate(ceBuilder, workflow, taskContext));
143141
return ceBuilder.build();
144142
}
145143

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,11 @@
2525
import io.serverlessworkflow.impl.resources.ResourceLoaderUtils;
2626
import io.serverlessworkflow.impl.scripts.ScriptLanguageId;
2727
import io.serverlessworkflow.impl.scripts.ScriptRunner;
28-
import java.util.Collection;
2928
import java.util.Objects;
3029
import java.util.Optional;
31-
import java.util.ServiceLoader;
3230

3331
public class RunScriptExecutorBuilder implements RunnableTaskBuilder<RunScript> {
3432

35-
private static Collection<ScriptRunner> scriptRunners =
36-
ServiceLoader.load(ScriptRunner.class).stream()
37-
.map(ServiceLoader.Provider::get)
38-
.sorted()
39-
.toList();
40-
4133
@Override
4234
public CallableTask build(RunScript taskConfiguration, WorkflowDefinition definition) {
4335
ScriptUnion scriptUnion = taskConfiguration.getScript();
@@ -72,7 +64,7 @@ public CallableTask build(RunScript taskConfiguration, WorkflowDefinition defini
7264
m),
7365
taskConfiguration.isAwait(),
7466
taskConfiguration.getReturn(),
75-
scriptRunners.stream()
67+
application.getServiceLoadedClasses(ScriptRunner.class).stream()
7668
.filter(s -> s.identifier().equals(language))
7769
.findFirst()
7870
.orElseThrow(

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,12 @@
2222
import io.serverlessworkflow.impl.WorkflowDefinition;
2323
import io.serverlessworkflow.impl.WorkflowModel;
2424
import io.serverlessworkflow.impl.WorkflowMutablePosition;
25-
import java.util.Collection;
26-
import java.util.ServiceLoader;
27-
import java.util.ServiceLoader.Provider;
2825
import java.util.concurrent.CompletableFuture;
2926

3027
public class RunTaskExecutor extends RegularTaskExecutor<RunTask> {
3128

3229
private final CallableTask runnable;
3330

34-
private static final Collection<RunnableTaskBuilder> runnables =
35-
ServiceLoader.load(RunnableTaskBuilder.class).stream().map(Provider::get).sorted().toList();
36-
;
37-
3831
public static class RunTaskExecutorBuilder
3932
extends RegularTaskExecutorBuilder<RunTask, RunTaskExecutor> {
4033
private CallableTask runnable;
@@ -44,7 +37,7 @@ protected RunTaskExecutorBuilder(
4437
super(position, task, definition);
4538
RunTaskConfiguration config = task.getRun().get();
4639
this.runnable =
47-
runnables.stream()
40+
definition.application().getServiceLoadedClasses(RunnableTaskBuilder.class).stream()
4841
.filter(r -> r.accept(config.getClass()))
4942
.findFirst()
5043
.map(r -> r.build(config, definition))

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

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,11 @@
3030
import java.util.List;
3131
import java.util.Map;
3232
import java.util.Optional;
33-
import java.util.ServiceLoader;
34-
import java.util.concurrent.ConcurrentHashMap;
3533

3634
public class HttpExecutorBuilder {
3735

3836
public static final String HTTP_REQUEST_DECORATOR_KEY = "HttpRequestDecorators";
3937
private final WorkflowDefinition definition;
40-
private static final Map<String, List<HttpRequestDecorator>> appRequestDecorators =
41-
new ConcurrentHashMap<>();
4238
private List<HttpRequestDecorator> requestDecorators;
4339
private WorkflowValueResolver<URI> pathSupplier;
4440
private Object body;
@@ -51,20 +47,14 @@ public class HttpExecutorBuilder {
5147
private HttpExecutorBuilder(WorkflowDefinition definition) {
5248
this.definition = definition;
5349
this.requestDecorators =
54-
appRequestDecorators.computeIfAbsent(
55-
definition.application().id(),
56-
__ -> {
57-
List<HttpRequestDecorator> result = new ArrayList<>();
58-
result.addAll(
59-
definition
60-
.application()
61-
.<Collection<HttpRequestDecorator>>additionalObject(
62-
HTTP_REQUEST_DECORATOR_KEY)
63-
.orElse(List.of()));
64-
ServiceLoader.load(HttpRequestDecorator.class).forEach(result::add);
65-
Collections.sort(result);
66-
return result;
67-
});
50+
new ArrayList<>(
51+
definition.application().getServiceLoadedClasses(HttpRequestDecorator.class));
52+
requestDecorators.addAll(
53+
definition
54+
.application()
55+
.<Collection<HttpRequestDecorator>>additionalObject(HTTP_REQUEST_DECORATOR_KEY)
56+
.orElse(List.of()));
57+
Collections.sort(requestDecorators);
6858
}
6959

7060
public HttpExecutorBuilder withAuth(ReferenceableAuthenticationPolicy policy) {

0 commit comments

Comments
 (0)