Skip to content

Commit 255b031

Browse files
authored
[Fix #881] Update to latest schema to support duration runtimeexpression (#895)
Signed-off-by: fjtirado <ftirados@redhat.com>
1 parent 231d058 commit 255b031

File tree

9 files changed

+115
-96
lines changed

9 files changed

+115
-96
lines changed

api/src/test/java/io/serverlessworkflow/api/ApiTest.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@
2323
import io.serverlessworkflow.api.types.CallHTTP;
2424
import io.serverlessworkflow.api.types.CallTask;
2525
import io.serverlessworkflow.api.types.HTTPArguments;
26-
import io.serverlessworkflow.api.types.OAuth2AuthenticationData;
2726
import io.serverlessworkflow.api.types.OAuth2AuthenticationData.OAuth2AuthenticationDataGrant;
2827
import io.serverlessworkflow.api.types.OAuth2AuthenticationPolicy;
29-
import io.serverlessworkflow.api.types.OAuth2AuthenticationPolicyConfiguration;
3028
import io.serverlessworkflow.api.types.OAuth2AuthenticationPropertiesEndpoints;
29+
import io.serverlessworkflow.api.types.OAuth2ConnectAuthenticationProperties;
3130
import io.serverlessworkflow.api.types.Task;
3231
import io.serverlessworkflow.api.types.Workflow;
3332
import java.io.IOException;
@@ -99,20 +98,18 @@ void testOauth2Auth() throws IOException {
9998
.getAuthenticationPolicy()
10099
.getOAuth2AuthenticationPolicy();
101100
assertThat(oauthPolicy).isNotNull();
102-
OAuth2AuthenticationPolicyConfiguration oauth2Props =
101+
OAuth2ConnectAuthenticationProperties oauth2Props =
103102
oauthPolicy.getOauth2().getOAuth2ConnectAuthenticationProperties();
104103
assertThat(oauth2Props).isNotNull();
105-
OAuth2AuthenticationPropertiesEndpoints endpoints =
106-
oauth2Props.getOAuth2ConnectAuthenticationProperties().getEndpoints();
104+
OAuth2AuthenticationPropertiesEndpoints endpoints = oauth2Props.getEndpoints();
107105
assertThat(endpoints.getToken()).isEqualTo("/auth/token");
108106
assertThat(endpoints.getIntrospection()).isEqualTo("/auth/introspect");
109107

110-
OAuth2AuthenticationData oauth2Data = oauth2Props.getOAuth2AuthenticationData();
111-
assertThat(oauth2Data.getAuthority().getLiteralUri())
108+
assertThat(oauth2Props.getAuthority().getLiteralUri())
112109
.isEqualTo(URI.create("http://keycloak/realms/fake-authority"));
113-
assertThat(oauth2Data.getGrant()).isEqualTo(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
114-
assertThat(oauth2Data.getClient().getId()).isEqualTo("workflow-runtime-id");
115-
assertThat(oauth2Data.getClient().getSecret()).isEqualTo("workflow-runtime-secret");
110+
assertThat(oauth2Props.getGrant()).isEqualTo(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
111+
assertThat(oauth2Props.getClient().getId()).isEqualTo("workflow-runtime-id");
112+
assertThat(oauth2Props.getClient().getSecret()).isEqualTo("workflow-runtime-secret");
116113
}
117114

118115
@Test

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/OAuth2AuthenticationPolicyBuilder.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,30 @@
1717

1818
import io.serverlessworkflow.api.types.OAuth2AuthenticationPolicy;
1919
import io.serverlessworkflow.api.types.OAuth2AuthenticationPolicyConfiguration;
20-
import io.serverlessworkflow.api.types.OAuth2ConnectAuthenticationProperties;
21-
import io.serverlessworkflow.api.types.Oauth2;
2220
import java.util.function.Consumer;
2321

2422
public final class OAuth2AuthenticationPolicyBuilder
2523
extends OIDCBuilder<OAuth2AuthenticationPolicy> {
2624

27-
private final OAuth2ConnectAuthenticationProperties properties;
28-
2925
OAuth2AuthenticationPolicyBuilder() {
3026
super();
31-
this.properties = new OAuth2ConnectAuthenticationProperties();
3227
}
3328

3429
public OAuth2AuthenticationPolicyBuilder endpoints(
3530
Consumer<OAuth2AuthenticationPropertiesEndpointsBuilder> endpointsConsumer) {
3631
final OAuth2AuthenticationPropertiesEndpointsBuilder builder =
3732
new OAuth2AuthenticationPropertiesEndpointsBuilder();
3833
endpointsConsumer.accept(builder);
39-
this.properties.setEndpoints(builder.build());
34+
this.authenticationData.setEndpoints(builder.build());
4035
return this;
4136
}
4237

4338
public OAuth2AuthenticationPolicy build() {
4439
final OAuth2AuthenticationPolicyConfiguration configuration =
4540
new OAuth2AuthenticationPolicyConfiguration();
46-
configuration.setOAuth2AuthenticationData(this.getAuthenticationData());
47-
configuration.setOAuth2ConnectAuthenticationProperties(this.properties);
48-
49-
final Oauth2 oauth2 = new Oauth2();
50-
oauth2.setOAuth2ConnectAuthenticationProperties(configuration);
51-
41+
configuration.setOAuth2ConnectAuthenticationProperties(this.authenticationData);
5242
final OAuth2AuthenticationPolicy policy = new OAuth2AuthenticationPolicy();
53-
policy.setOauth2(oauth2);
54-
43+
policy.setOauth2(configuration);
5544
return policy;
5645
}
5746
}

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/OIDCBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@
1919
import io.serverlessworkflow.api.types.OAuth2AuthenticationData;
2020
import io.serverlessworkflow.api.types.OAuth2AuthenticationDataClient;
2121
import io.serverlessworkflow.api.types.OAuth2AuthenticationPropertiesEndpoints;
22+
import io.serverlessworkflow.api.types.OAuth2ConnectAuthenticationProperties;
2223
import io.serverlessworkflow.api.types.OAuth2TokenDefinition;
2324
import io.serverlessworkflow.api.types.OAuth2TokenRequest;
2425
import java.util.List;
2526
import java.util.function.Consumer;
2627

2728
public abstract class OIDCBuilder<T extends AuthenticationPolicy> {
28-
private final OAuth2AuthenticationData authenticationData;
29+
protected final OAuth2ConnectAuthenticationProperties authenticationData;
2930

3031
OIDCBuilder() {
31-
this.authenticationData = new OAuth2AuthenticationData();
32+
this.authenticationData = new OAuth2ConnectAuthenticationProperties();
3233
this.authenticationData.setRequest(new OAuth2TokenRequest());
3334
}
3435

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

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,15 @@ public static boolean whenExceptTest(
170170
public static WorkflowValueResolver<Duration> fromTimeoutAfter(
171171
WorkflowApplication application, TimeoutAfter timeout) {
172172
if (timeout.getDurationExpression() != null) {
173-
if (ExpressionUtils.isExpr(timeout.getDurationExpression())) {
174-
return (w, f, t) ->
175-
Duration.parse(
176-
application
177-
.expressionFactory()
178-
.resolveString(ExpressionDescriptor.from(timeout.getDurationExpression()))
179-
.apply(w, f, t));
180-
} else {
181-
Duration duration = Duration.parse(timeout.getDurationExpression());
182-
return (w, f, t) -> duration;
183-
}
173+
return (w, f, t) ->
174+
Duration.parse(
175+
application
176+
.expressionFactory()
177+
.resolveString(ExpressionDescriptor.from(timeout.getDurationExpression()))
178+
.apply(w, f, t));
179+
} else if (timeout.getDurationLiteral() != null) {
180+
Duration duration = Duration.parse(timeout.getDurationLiteral());
181+
return (w, f, t) -> duration;
184182
} else if (timeout.getDurationInline() != null) {
185183
DurationInline inlineDuration = timeout.getDurationInline();
186184
return (w, t, f) ->

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

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

1818
import io.serverlessworkflow.api.types.OAuth2AuthenticationPolicy;
19-
import io.serverlessworkflow.api.types.Oauth2;
19+
import io.serverlessworkflow.api.types.OAuth2AuthenticationPolicyConfiguration;
2020
import io.serverlessworkflow.api.types.Workflow;
2121
import io.serverlessworkflow.impl.TaskContext;
2222
import io.serverlessworkflow.impl.WorkflowApplication;
@@ -36,9 +36,10 @@ public class OAuth2AuthProvider implements AuthProvider {
3636

3737
public OAuth2AuthProvider(
3838
WorkflowApplication application, Workflow workflow, OAuth2AuthenticationPolicy authPolicy) {
39-
Oauth2 oauth2 = authPolicy.getOauth2();
39+
OAuth2AuthenticationPolicyConfiguration oauth2 = authPolicy.getOauth2();
4040
if (oauth2.getOAuth2ConnectAuthenticationProperties() != null) {
41-
this.requestBuilder = new OAuthRequestBuilder(application, oauth2);
41+
this.requestBuilder =
42+
new OAuthRequestBuilder(application, oauth2.getOAuth2ConnectAuthenticationProperties());
4243
} else if (oauth2.getOAuth2AuthenticationPolicySecret() != null) {
4344
throw new UnsupportedOperationException("Secrets are still not supported");
4445
}

impl/http/src/main/java/io/serverlessworkflow/impl/executors/http/auth/requestbuilder/OAuthRequestBuilder.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,29 @@
1616
package io.serverlessworkflow.impl.executors.http.auth.requestbuilder;
1717

1818
import io.serverlessworkflow.api.types.OAuth2AuthenticationPropertiesEndpoints;
19-
import io.serverlessworkflow.api.types.Oauth2;
19+
import io.serverlessworkflow.api.types.OAuth2ConnectAuthenticationProperties;
2020
import io.serverlessworkflow.impl.WorkflowApplication;
2121
import java.net.URI;
2222
import java.util.Map;
2323

2424
public class OAuthRequestBuilder extends AbstractAuthRequestBuilder {
2525

26-
private final Oauth2 oauth2;
27-
2826
private final Map<String, String> defaults =
2927
Map.of(
3028
"endpoints.token", "oauth2/token",
3129
"endpoints.revocation", "oauth2/revoke",
3230
"endpoints.introspection", "oauth2/introspect");
3331

34-
public OAuthRequestBuilder(WorkflowApplication application, Oauth2 oauth2) {
35-
super(
36-
oauth2.getOAuth2ConnectAuthenticationProperties().getOAuth2AuthenticationData(),
37-
application);
38-
this.oauth2 = oauth2;
32+
public OAuthRequestBuilder(
33+
WorkflowApplication application,
34+
OAuth2ConnectAuthenticationProperties oAuth2ConnectAuthenticationProperties) {
35+
super(oAuth2ConnectAuthenticationProperties, application);
3936
}
4037

4138
@Override
4239
protected void authenticationURI(HttpRequestBuilder requestBuilder) {
4340
OAuth2AuthenticationPropertiesEndpoints endpoints =
44-
oauth2
45-
.getOAuth2ConnectAuthenticationProperties()
46-
.getOAuth2ConnectAuthenticationProperties()
47-
.getEndpoints();
41+
((OAuth2ConnectAuthenticationProperties) authenticationData).getEndpoints();
4842

4943
String baseUri =
5044
authenticationData.getAuthority().getLiteralUri().toString().replaceAll("/$", "");

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ void testRetry(String path) throws IOException {
7777
.setHeader("Content-Type", "application/json")
7878
.setBody(JsonUtils.mapper().writeValueAsString(result)));
7979
CompletableFuture<WorkflowModel> future =
80-
app.workflowDefinition(readWorkflowFromClasspath(path)).instance(Map.of()).start();
80+
app.workflowDefinition(readWorkflowFromClasspath(path))
81+
.instance(Map.of("delay", 0.01))
82+
.start();
8183
Awaitility.await()
82-
.atMost(Duration.ofSeconds(1))
84+
.atMost(Duration.ofSeconds(100))
8385
.until(() -> future.join().as(JsonNode.class).orElseThrow().equals(result));
8486
}
8587
}

impl/test/src/test/resources/workflows-samples/try-catch-retry-inline.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ do:
1717
type: https://serverlessworkflow.io/spec/1.0.0/errors/communication
1818
status: 404
1919
retry:
20-
delay: "PT0.01S"
20+
delay: ${"PT\(.delay)S"}
2121
backoff:
2222
exponential: {}
2323
limit:

types/src/main/resources/schema/workflow.yaml

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,10 @@ $defs:
312312
type: string
313313
title: WithGRPCServiceHost
314314
description: The hostname of the GRPC service to call.
315-
pattern: ^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$
315+
pattern: ^[a-zA-Z0-9](?:[a-zA-Z0-9-.]{0,61}[a-zA-Z0-9])?$
316316
port:
317317
type: integer
318-
title: WithGRPCServicePost
318+
title: WithGRPCServicePort
319319
description: The port number of the GRPC service to call.
320320
minimum: 0
321321
maximum: 65535
@@ -434,6 +434,45 @@ $defs:
434434
description: Specifies whether redirection status codes (`300–399`) should be treated as errors.
435435
required: [ document, operationId ]
436436
unevaluatedProperties: false
437+
- title: CallA2A
438+
description: Defines the A2A call to perform.
439+
type: object
440+
unevaluatedProperties: false
441+
required: [ call, with ]
442+
allOf:
443+
- $ref: '#/$defs/taskBase'
444+
- properties:
445+
call:
446+
type: string
447+
const: a2a
448+
with:
449+
type: object
450+
title: A2AArguments
451+
description: The A2A call arguments.
452+
properties:
453+
agentCard:
454+
$ref: '#/$defs/externalResource'
455+
title: WithA2AAgentCard
456+
description: The Agent Card that defines the agent to call.
457+
server:
458+
title: A2AServer
459+
description: The server endpoint to send the request to.
460+
$ref: '#/$defs/endpoint'
461+
method:
462+
type: string
463+
title: WithA2AMethod
464+
description: The A2A method to send.
465+
enum: [ 'message/send', 'message/stream', 'tasks/get', 'tasks/list', 'tasks/cancel', 'tasks/resubscribe', 'tasks/pushNotificationConfig/set', 'tasks/pushNotificationConfig/get', 'tasks/pushNotificationConfig/list', 'tasks/pushNotificationConfig/delete', 'agent/getAuthenticatedExtendedCard' ]
466+
parameters:
467+
oneOf:
468+
- type: object
469+
minProperties: 1
470+
additionalProperties: true
471+
- type: string
472+
title: WithA2AParameters
473+
description: The parameters object to send with the A2A method.
474+
required: [ method ]
475+
unevaluatedProperties: false
437476
- title: CallFunction
438477
description: Defines the function call to perform.
439478
type: object
@@ -445,7 +484,7 @@ $defs:
445484
call:
446485
type: string
447486
not:
448-
enum: ["asyncapi", "grpc", "http", "openapi"]
487+
enum: ["asyncapi", "grpc", "http", "openapi", "a2a"]
449488
description: The name of the function to call.
450489
with:
451490
type: object
@@ -1001,37 +1040,35 @@ $defs:
10011040
description: The configuration of the OAuth2 authentication policy.
10021041
unevaluatedProperties: false
10031042
oneOf:
1004-
- type: object
1043+
- $ref: '#/$defs/oauth2AuthenticationProperties'
1044+
type: object
10051045
title: OAuth2ConnectAuthenticationProperties
10061046
description: The inline configuration of the OAuth2 authentication policy.
10071047
unevaluatedProperties: false
1008-
allOf:
1009-
- $ref: '#/$defs/oauth2AuthenticationProperties'
1010-
- type: object
1048+
properties:
1049+
endpoints:
1050+
type: object
1051+
title: OAuth2AuthenticationPropertiesEndpoints
1052+
description: The endpoint configurations for OAuth2.
10111053
properties:
1012-
endpoints:
1013-
type: object
1014-
title: OAuth2AuthenticationPropertiesEndpoints
1015-
description: The endpoint configurations for OAuth2.
1016-
properties:
1017-
token:
1018-
type: string
1019-
format: uri-template
1020-
default: /oauth2/token
1021-
title: OAuth2TokenEndpoint
1022-
description: The relative path to the token endpoint. Defaults to `/oauth2/token`.
1023-
revocation:
1024-
type: string
1025-
format: uri-template
1026-
default: /oauth2/revoke
1027-
title: OAuth2RevocationEndpoint
1028-
description: The relative path to the revocation endpoint. Defaults to `/oauth2/revoke`.
1029-
introspection:
1030-
type: string
1031-
format: uri-template
1032-
default: /oauth2/introspect
1033-
title: OAuth2IntrospectionEndpoint
1034-
description: The relative path to the introspection endpoint. Defaults to `/oauth2/introspect`.
1054+
token:
1055+
type: string
1056+
format: uri-template
1057+
default: /oauth2/token
1058+
title: OAuth2TokenEndpoint
1059+
description: The relative path to the token endpoint. Defaults to `/oauth2/token`.
1060+
revocation:
1061+
type: string
1062+
format: uri-template
1063+
default: /oauth2/revoke
1064+
title: OAuth2RevocationEndpoint
1065+
description: The relative path to the revocation endpoint. Defaults to `/oauth2/revoke`.
1066+
introspection:
1067+
type: string
1068+
format: uri-template
1069+
default: /oauth2/introspect
1070+
title: OAuth2IntrospectionEndpoint
1071+
description: The relative path to the introspection endpoint. Defaults to `/oauth2/introspect`.
10351072
- $ref: '#/$defs/secretBasedAuthenticationPolicy'
10361073
title: OAuth2AuthenticationPolicySecret
10371074
description: Secret based configuration of the OAuth2 authentication policy.
@@ -1178,10 +1215,13 @@ $defs:
11781215
description: Number of milliseconds, if any.
11791216
title: DurationInline
11801217
description: The inline definition of a duration.
1218+
- $ref: '#/$defs/runtimeExpression'
1219+
title: DurationExpression
1220+
description: Runtime expression that generates an ISO 8601
11811221
- type: string
11821222
pattern: '^P(?!$)(\d+(?:\.\d+)?Y)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?W)?(\d+(?:\.\d+)?D)?(T(?=\d)(\d+(?:\.\d+)?H)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?S)?)?$'
1183-
title: DurationExpression
1184-
description: The ISO 8601 expression of a duration.
1223+
title: DurationLiteral
1224+
description: The Literal ISO 8601 representation of a duration.
11851225
error:
11861226
type: object
11871227
title: Error
@@ -1697,23 +1737,20 @@ $defs:
16971737
type: object
16981738
title: AsyncApiMessagePayload
16991739
description: The message's payload, if any.
1700-
additionalProperties: true
17011740
headers:
17021741
type: object
17031742
title: AsyncApiMessageHeaders
17041743
description: The message's headers, if any.
1705-
additionalProperties: true
17061744
asyncApiInboundMessage:
1707-
type: object
17081745
title: AsyncApiInboundMessage
17091746
description: Represents a message counsumed by an AsyncAPI subscription.
17101747
allOf:
1711-
- $ref: '#/$defs/asyncApiOutboundMessage'
1712-
properties:
1713-
correlationId:
1714-
type: string
1715-
title: AsyncApiMessageCorrelationId
1716-
description: The message's correlation id, if any.
1748+
- $ref: '#/$defs/asyncApiOutboundMessage'
1749+
- properties:
1750+
correlationId:
1751+
type: string
1752+
title: AsyncApiMessageCorrelationId
1753+
description: The message's correlation id, if any.
17171754
asyncApiSubscription:
17181755
type: object
17191756
title: AsyncApiSubscription

0 commit comments

Comments
 (0)