Skip to content

Commit 14d92ea

Browse files
committed
states - unsupported AST kind *ast.InterfaceType
Fixes #144 Signed-off-by: Spolti <[email protected]>
1 parent 8994e2b commit 14d92ea

26 files changed

+1181
-542
lines changed

model/action.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type Action struct {
3333
// References a sub-workflow to be executed
3434
SubFlowRef *WorkflowRef `json:"subFlowRef,omitempty"`
3535
// Sleep Defines time period workflow execution should sleep before / after function execution
36-
Sleep Sleep `json:"sleep,omitempty"`
36+
Sleep *Sleep `json:"sleep,omitempty"`
3737
// RetryRef References a defined workflow retry definition. If not defined the default retry policy is assumed
3838
RetryRef string `json:"retryRef,omitempty"`
3939
// List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true`

model/callback_state.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,36 @@
1414

1515
package model
1616

17+
import (
18+
"encoding/json"
19+
)
20+
1721
// CallbackState executes a function and waits for callback event that indicates
1822
// completion of the task.
1923
type CallbackState struct {
20-
BaseState
2124
// Defines the action to be executed
2225
Action Action `json:"action" validate:"required"`
2326
// References a unique callback event name in the defined workflow events
2427
EventRef string `json:"eventRef" validate:"required"`
2528
// Time period to wait for incoming events (ISO 8601 format)
26-
Timeouts *CallbackStateTimeout `json:"timeouts" validate:"omitempty"`
29+
Timeouts *CallbackStateTimeout `json:"timeouts,omitempty"`
2730
// Event data filter
28-
EventDataFilter EventDataFilter `json:"eventDataFilter,omitempty"`
31+
EventDataFilter *EventDataFilter `json:"eventDataFilter,omitempty"`
2932
}
3033

31-
func (in *CallbackState) DeepCopyState() State {
32-
return in
34+
func (c *CallbackState) MarshalJSON() ([]byte, error) {
35+
type Alias CallbackState
36+
custom, err := json.Marshal(&struct {
37+
*Alias
38+
// TODO verify if only th e alias is enough
39+
Action Action `json:"action" validate:"required"`
40+
Timeouts *CallbackStateTimeout `json:"timeouts,omitempty"`
41+
}{
42+
Alias: (*Alias)(c),
43+
Action: c.Action,
44+
Timeouts: c.Timeouts,
45+
})
46+
return custom, err
3347
}
3448

3549
// CallbackStateTimeout defines timeout settings for callback state

model/callback_state_test.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2022 The Serverless Workflow Specification Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"testing"
19+
20+
"github.com/stretchr/testify/assert"
21+
22+
val "github.com/serverlessworkflow/sdk-go/v2/validator"
23+
)
24+
25+
func TestCallbackStateStructLevelValidation(t *testing.T) {
26+
type testCase struct {
27+
desp string
28+
callbackStateObj State
29+
err string
30+
}
31+
testCases := []testCase{
32+
{
33+
desp: "normal",
34+
callbackStateObj: State{
35+
BaseState: BaseState{
36+
Name: "callbackTest",
37+
Type: StateTypeCallback,
38+
},
39+
CallbackState: &CallbackState{
40+
Action: Action{
41+
ID: "1",
42+
Name: "action1",
43+
},
44+
EventRef: "refExample",
45+
},
46+
},
47+
err: ``,
48+
},
49+
{
50+
desp: "missing required EventRef",
51+
callbackStateObj: State{
52+
BaseState: BaseState{
53+
Name: "callbackTest",
54+
Type: StateTypeCallback,
55+
},
56+
CallbackState: &CallbackState{
57+
Action: Action{
58+
ID: "1",
59+
Name: "action1",
60+
},
61+
},
62+
},
63+
err: `Key: 'State.CallbackState.EventRef' Error:Field validation for 'EventRef' failed on the 'required' tag`,
64+
},
65+
// TODO need to register custom types
66+
//{
67+
// desp: "missing required Action",
68+
// callbackStateObj: State{
69+
// BaseState: BaseState{
70+
// Name: "callbackTest",
71+
// Type: StateTypeCallback,
72+
// },
73+
// CallbackState: &CallbackState{
74+
// EventRef: "refExample",
75+
// },
76+
// },
77+
// err: `Key: 'State.CallbackState.Action' Error:Field validation for 'Action' failed on the 'required' tag`,
78+
//},
79+
}
80+
for _, tc := range testCases {
81+
t.Run(tc.desp, func(t *testing.T) {
82+
err := val.GetValidator().Struct(&tc.callbackStateObj)
83+
84+
if tc.err != "" {
85+
assert.Error(t, err)
86+
assert.Regexp(t, tc.err, err)
87+
return
88+
}
89+
90+
assert.NoError(t, err)
91+
})
92+
}
93+
}

model/delay_state.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414

1515
package model
1616

17+
import "encoding/json"
18+
1719
// DelayState Causes the workflow execution to delay for a specified duration
1820
type DelayState struct {
19-
BaseState
2021
// Amount of time (ISO 8601 format) to delay
2122
TimeDelay string `json:"timeDelay" validate:"required,iso8601duration"`
2223
}
2324

24-
func (in *DelayState) DeepCopyState() State {
25-
return in
25+
func (a *DelayState) MarshalJSON() ([]byte, error) {
26+
custom, err := json.Marshal(&struct {
27+
TimeDelay string `json:"timeDelay" validate:"required,iso8601duration"`
28+
}{
29+
TimeDelay: a.TimeDelay,
30+
})
31+
return custom, err
2632
}

model/delay_state_test.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,42 +25,48 @@ import (
2525
func TestDelayStateStructLevelValidation(t *testing.T) {
2626
type testCase struct {
2727
desp string
28-
delayStateObj DelayState
28+
delayStateObj State
2929
err string
3030
}
3131
testCases := []testCase{
3232
{
3333
desp: "normal",
34-
delayStateObj: DelayState{
34+
delayStateObj: State{
3535
BaseState: BaseState{
3636
Name: "1",
3737
Type: "delay",
3838
},
39-
TimeDelay: "PT5S",
39+
DelayState: &DelayState{
40+
TimeDelay: "PT5S",
41+
},
4042
},
4143
err: ``,
4244
},
4345
{
4446
desp: "missing required timeDelay",
45-
delayStateObj: DelayState{
47+
delayStateObj: State{
4648
BaseState: BaseState{
4749
Name: "1",
4850
Type: "delay",
4951
},
50-
TimeDelay: "",
52+
DelayState: &DelayState{
53+
TimeDelay: "",
54+
},
5155
},
52-
err: `Key: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'required' tag`,
56+
err: `Key: 'State.DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'required' tag`,
5357
},
5458
{
5559
desp: "invalid timeDelay duration",
56-
delayStateObj: DelayState{
60+
delayStateObj: State{
5761
BaseState: BaseState{
5862
Name: "1",
5963
Type: "delay",
6064
},
61-
TimeDelay: "P5S",
65+
DelayState: &DelayState{
66+
TimeDelay: "P5S",
67+
},
6268
},
63-
err: `Key: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'iso8601duration' tag`,
69+
err: `Key: 'State.DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'iso8601duration' tag`,
6470
},
6571
}
6672
for _, tc := range testCases {

model/event.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ type EventRef struct {
100100
ResultEventTimeout string `json:"resultEventTimeout,omitempty" validate:"omitempty,iso8601duration"`
101101
// If string type, an expression which selects parts of the states data output to become the data (payload) of the event referenced by 'triggerEventRef'.
102102
// If object type, a custom object to become the data (payload) of the event referenced by 'triggerEventRef'.
103-
Data Object `json:"data,omitempty"`
103+
Data *Object `json:"data,omitempty"`
104104
// Add additional extension context attributes to the produced event
105105
ContextAttributes map[string]Object `json:"contextAttributes,omitempty"`
106106
// Invoke specifies if the subflow should be invoked sync or async.

model/event_data_filter.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ import (
2222

2323
// EventDataFilter used to filter consumed event payloads.
2424
type EventDataFilter struct {
25-
// UseData represent where event payload is added/merged to state data. If it's false, data & toStateData should be ignored.
26-
// Defaults to true.
25+
// UseData represent where event payload is added/merged to state data. If it's false, data & toStateData
26+
// should be ignored. Defaults to true.
2727
UseData bool `json:"useData,omitempty"`
28-
2928
// Workflow expression that filters of the event data (payload)
3029
Data string `json:"data,omitempty"`
31-
// Workflow expression that selects a state data element to which the event payload should be added/merged into. If not specified, denotes, the top-level state data element.
30+
// Workflow expression that selects a state data element to which the event payload should be added/merged into.
31+
// If not specified, denotes, the top-level state data element.
3232
ToStateData string `json:"toStateData,omitempty"`
3333
}
3434

model/event_state.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
// EventState used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel
2323
type EventState struct {
2424
// TODO: EventState doesn't have usedForCompensation field.
25-
BaseState
2625

2726
// If true consuming one of the defined events causes its associated actions to be performed.
2827
// If false all the defined events must be consumed in order for actions to be performed
@@ -34,8 +33,17 @@ type EventState struct {
3433
Timeouts *EventStateTimeout `json:"timeouts,omitempty"`
3534
}
3635

37-
func (e *EventState) DeepCopyState() State {
38-
return e
36+
func (e *EventState) MarshalJSON() ([]byte, error) {
37+
type Alias EventState
38+
custom, err := json.Marshal(&struct {
39+
*Alias
40+
// TODO verify if only th e alias is enough
41+
Timeouts *EventStateTimeout `json:"timeouts,omitempty"`
42+
}{
43+
Alias: (*Alias)(e),
44+
Timeouts: e.Timeouts,
45+
})
46+
return custom, err
3947
}
4048

4149
type eventStateForUnmarshal EventState
@@ -81,6 +89,7 @@ func (o *OnEvents) UnmarshalJSON(data []byte) error {
8189
}
8290

8391
*o = OnEvents(v)
92+
8493
return nil
8594
}
8695

model/event_state_test.go

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,55 +25,59 @@ func TestEventStateUnmarshalJSON(t *testing.T) {
2525
type testCase struct {
2626
desp string
2727
data string
28-
expect EventState
28+
expect State
2929
err string
3030
}
3131
testCases := []testCase{
3232
{
3333
desp: "all fields set",
34-
data: `{"name": "1", "Type": "event", "exclusive": false, "onEvents": [{"eventRefs": ["E1", "E2"], "actionMode": "parallel"}], "timeouts": {"actionExecTimeout": "PT5M", "eventTimeout": "PT5M", "stateExecTimeout": "PT5M"}}`,
35-
expect: EventState{
34+
data: `{"name": "1", "type": "event", "exclusive": false, "onEvents": [{"eventRefs": ["E1", "E2"], "actionMode": "parallel"}], "timeouts": {"actionExecTimeout": "PT5M", "eventTimeout": "PT5M", "stateExecTimeout": "PT5M"}}`,
35+
expect: State{
3636
BaseState: BaseState{
3737
Name: "1",
3838
Type: StateTypeEvent,
3939
},
40-
Exclusive: false,
41-
OnEvents: []OnEvents{
42-
{
43-
EventRefs: []string{"E1", "E2"},
44-
ActionMode: "parallel",
40+
EventState: &EventState{
41+
Exclusive: false,
42+
OnEvents: []OnEvents{
43+
{
44+
EventRefs: []string{"E1", "E2"},
45+
ActionMode: "parallel",
46+
},
4547
},
46-
},
47-
Timeouts: &EventStateTimeout{
48-
EventTimeout: "PT5M",
49-
ActionExecTimeout: "PT5M",
50-
StateExecTimeout: &StateExecTimeout{
51-
Total: "PT5M",
48+
Timeouts: &EventStateTimeout{
49+
EventTimeout: "PT5M",
50+
ActionExecTimeout: "PT5M",
51+
StateExecTimeout: &StateExecTimeout{
52+
Total: "PT5M",
53+
},
5254
},
5355
},
5456
},
5557
err: ``,
5658
},
5759
{
5860
desp: "default exclusive",
59-
data: `{"name": "1", "Type": "event", "onEvents": [{"eventRefs": ["E1", "E2"], "actionMode": "parallel"}], "timeouts": {"actionExecTimeout": "PT5M", "eventTimeout": "PT5M", "stateExecTimeout": "PT5M"}}`,
60-
expect: EventState{
61+
data: `{"name": "1", "type": "event", "onEvents": [{"eventRefs": ["E1", "E2"], "actionMode": "parallel"}], "timeouts": {"actionExecTimeout": "PT5M", "eventTimeout": "PT5M", "stateExecTimeout": "PT5M"}}`,
62+
expect: State{
6163
BaseState: BaseState{
6264
Name: "1",
6365
Type: StateTypeEvent,
6466
},
65-
Exclusive: true,
66-
OnEvents: []OnEvents{
67-
{
68-
EventRefs: []string{"E1", "E2"},
69-
ActionMode: "parallel",
67+
EventState: &EventState{
68+
Exclusive: true,
69+
OnEvents: []OnEvents{
70+
{
71+
EventRefs: []string{"E1", "E2"},
72+
ActionMode: "parallel",
73+
},
7074
},
71-
},
72-
Timeouts: &EventStateTimeout{
73-
EventTimeout: "PT5M",
74-
ActionExecTimeout: "PT5M",
75-
StateExecTimeout: &StateExecTimeout{
76-
Total: "PT5M",
75+
Timeouts: &EventStateTimeout{
76+
EventTimeout: "PT5M",
77+
ActionExecTimeout: "PT5M",
78+
StateExecTimeout: &StateExecTimeout{
79+
Total: "PT5M",
80+
},
7781
},
7882
},
7983
},
@@ -82,7 +86,7 @@ func TestEventStateUnmarshalJSON(t *testing.T) {
8286
}
8387
for _, tc := range testCases {
8488
t.Run(tc.desp, func(t *testing.T) {
85-
v := EventState{}
89+
v := State{}
8690
err := json.Unmarshal([]byte(tc.data), &v)
8791

8892
if tc.err != "" {

0 commit comments

Comments
 (0)