Skip to content

Commit 1293519

Browse files
authored
refactor(*): add iso8601duration validate tag (#78)
Signed-off-by: lsytj0413 <511121939@qq.com> Signed-off-by: lsytj0413 <511121939@qq.com>
1 parent e72f6db commit 1293519

13 files changed

+127
-154
lines changed

model/delay_state.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package model
1616

1717
import (
18-
"reflect"
19-
2018
"github.com/go-playground/validator/v10"
2119

2220
val "github.com/serverlessworkflow/sdk-go/v2/validator"
@@ -33,15 +31,10 @@ func init() {
3331
type DelayState struct {
3432
BaseState
3533
// Amount of time (ISO 8601 format) to delay
36-
TimeDelay string `json:"timeDelay" validate:"required"`
34+
TimeDelay string `json:"timeDelay" validate:"required,iso8601duration"`
3735
}
3836

3937
// DelayStateStructLevelValidation custom validator for DelayState Struct
4038
func DelayStateStructLevelValidation(structLevel validator.StructLevel) {
41-
delayStateObj := structLevel.Current().Interface().(DelayState)
42-
43-
err := validateISO8601TimeDuration(delayStateObj.TimeDelay)
44-
if err != nil {
45-
structLevel.ReportError(reflect.ValueOf(delayStateObj.TimeDelay), "TimeDelay", "timeDelay", "reqiso8601duration", "")
46-
}
39+
// TODO
4740
}

model/delay_state_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestDelayStateStructLevelValidation(t *testing.T) {
4949
},
5050
TimeDelay: "",
5151
},
52-
err: `Key: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'required' tag\nKey: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'reqiso8601duration' tag`,
52+
err: `Key: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'required' tag`,
5353
},
5454
{
5555
desp: "invalid timeDelay duration",
@@ -60,7 +60,7 @@ func TestDelayStateStructLevelValidation(t *testing.T) {
6060
},
6161
TimeDelay: "P5S",
6262
},
63-
err: `Key: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'reqiso8601duration' tag`,
63+
err: `Key: 'DelayState.TimeDelay' Error:Field validation for 'TimeDelay' failed on the 'iso8601duration' tag`,
6464
},
6565
}
6666
for _, tc := range testCases {

model/retry.go

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,48 +36,29 @@ type Retry struct {
3636
// Unique retry strategy name
3737
Name string `json:"name" validate:"required"`
3838
// Time delay between retry attempts (ISO 8601 duration format)
39-
Delay string `json:"delay,omitempty"`
39+
Delay string `json:"delay,omitempty" validate:"omitempty,iso8601duration"`
4040
// Maximum time delay between retry attempts (ISO 8601 duration format)
41-
MaxDelay string `json:"maxDelay,omitempty"`
41+
MaxDelay string `json:"maxDelay,omitempty" validate:"omitempty,iso8601duration"`
4242
// Static value by which the delay increases during each attempt (ISO 8601 time format)
43-
Increment string `json:"increment,omitempty"`
43+
Increment string `json:"increment,omitempty" validate:"omitempty,iso8601duration"`
4444
// Numeric value, if specified the delay between retries is multiplied by this value.
4545
Multiplier *floatstr.Float32OrString `json:"multiplier,omitempty" validate:"omitempty,min=1"`
4646
// Maximum number of retry attempts.
4747
MaxAttempts intstr.IntOrString `json:"maxAttempts" validate:"required"`
48+
4849
// If float type, maximum amount of random time added or subtracted from the delay between each retry relative to total delay (between 0 and 1). If string type, absolute maximum amount of random time added or subtracted from the delay between each retry (ISO 8601 duration format)
50+
// TODO: make iso8601duration compatible this type
4951
Jitter floatstr.Float32OrString `json:"jitter,omitempty" validate:"omitempty,min=0,max=1"`
5052
}
5153

5254
// RetryStructLevelValidation custom validator for Retry Struct
5355
func RetryStructLevelValidation(structLevel validator.StructLevel) {
5456
retryObj := structLevel.Current().Interface().(Retry)
5557

56-
if retryObj.Delay != "" {
57-
err := validateISO8601TimeDuration(retryObj.Delay)
58-
if err != nil {
59-
structLevel.ReportError(reflect.ValueOf(retryObj.Delay), "Delay", "delay", "reqiso8601duration", "")
60-
}
61-
}
62-
63-
if retryObj.MaxDelay != "" {
64-
err := validateISO8601TimeDuration(retryObj.MaxDelay)
65-
if err != nil {
66-
structLevel.ReportError(reflect.ValueOf(retryObj.MaxDelay), "MaxDelay", "maxDelay", "reqiso8601duration", "")
67-
}
68-
}
69-
70-
if retryObj.Increment != "" {
71-
err := validateISO8601TimeDuration(retryObj.Increment)
72-
if err != nil {
73-
structLevel.ReportError(reflect.ValueOf(retryObj.Increment), "Increment", "increment", "reqiso8601duration", "")
74-
}
75-
}
76-
7758
if retryObj.Jitter.Type == floatstr.String && retryObj.Jitter.StrVal != "" {
78-
err := validateISO8601TimeDuration(retryObj.Jitter.StrVal)
59+
err := val.ValidateISO8601TimeDuration(retryObj.Jitter.StrVal)
7960
if err != nil {
80-
structLevel.ReportError(reflect.ValueOf(retryObj.Jitter.StrVal), "Jitter", "jitter", "reqiso8601duration", "")
61+
structLevel.ReportError(reflect.ValueOf(retryObj.Jitter.StrVal), "Jitter", "jitter", "iso8601duration", "")
8162
}
8263
}
8364
}

model/retry_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ func TestRetryStructLevelValidation(t *testing.T) {
4141
},
4242
err: ``,
4343
},
44+
{
45+
desp: "normal with all optinal",
46+
retryObj: Retry{
47+
Name: "1",
48+
},
49+
err: ``,
50+
},
4451
{
4552
desp: "missing required name",
4653
retryObj: Retry{
@@ -61,7 +68,7 @@ func TestRetryStructLevelValidation(t *testing.T) {
6168
Increment: "PT5S",
6269
Jitter: floatstr.FromString("PT5S"),
6370
},
64-
err: `Key: 'Retry.Delay' Error:Field validation for 'Delay' failed on the 'reqiso8601duration' tag`,
71+
err: `Key: 'Retry.Delay' Error:Field validation for 'Delay' failed on the 'iso8601duration' tag`,
6572
},
6673
{
6774
desp: "invdalid max delay duration",
@@ -72,7 +79,7 @@ func TestRetryStructLevelValidation(t *testing.T) {
7279
Increment: "PT5S",
7380
Jitter: floatstr.FromString("PT5S"),
7481
},
75-
err: `Key: 'Retry.MaxDelay' Error:Field validation for 'MaxDelay' failed on the 'reqiso8601duration' tag`,
82+
err: `Key: 'Retry.MaxDelay' Error:Field validation for 'MaxDelay' failed on the 'iso8601duration' tag`,
7683
},
7784
{
7885
desp: "invalid increment duration",
@@ -83,7 +90,7 @@ func TestRetryStructLevelValidation(t *testing.T) {
8390
Increment: "P5S",
8491
Jitter: floatstr.FromString("PT5S"),
8592
},
86-
err: `Key: 'Retry.Increment' Error:Field validation for 'Increment' failed on the 'reqiso8601duration' tag`,
93+
err: `Key: 'Retry.Increment' Error:Field validation for 'Increment' failed on the 'iso8601duration' tag`,
8794
},
8895
{
8996
desp: "invalid jitter duration",
@@ -94,7 +101,7 @@ func TestRetryStructLevelValidation(t *testing.T) {
94101
Increment: "PT5S",
95102
Jitter: floatstr.FromString("P5S"),
96103
},
97-
err: `Key: 'Retry.Jitter' Error:Field validation for 'Jitter' failed on the 'reqiso8601duration' tag`,
104+
err: `Key: 'Retry.Jitter' Error:Field validation for 'Jitter' failed on the 'iso8601duration' tag`,
98105
},
99106
}
100107

model/sleep_state.go

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,12 @@
1414

1515
package model
1616

17-
import (
18-
"context"
19-
"reflect"
20-
21-
validator "github.com/go-playground/validator/v10"
22-
val "github.com/serverlessworkflow/sdk-go/v2/validator"
23-
)
24-
2517
// SleepState suspends workflow execution for a given time duration.
2618
type SleepState struct {
2719
BaseState
2820

2921
// Duration (ISO 8601 duration format) to sleep
30-
Duration string `json:"duration" validate:"required"`
22+
Duration string `json:"duration" validate:"required,iso8601duration"`
3123
// Timeouts State specific timeouts
3224
Timeouts *SleepStateTimeout `json:"timeouts,omitempty"`
3325
}
@@ -36,20 +28,3 @@ type SleepState struct {
3628
type SleepStateTimeout struct {
3729
StateExecTimeout StateExecTimeout `json:"stateExecTimeout,omitempty"`
3830
}
39-
40-
// SleepStateStructLevelValidation custom validator for SleepState
41-
func SleepStateStructLevelValidation(_ context.Context, structLevel validator.StructLevel) {
42-
sleepState := structLevel.Current().Interface().(SleepState)
43-
44-
err := validateISO8601TimeDuration(sleepState.Duration)
45-
if err != nil {
46-
structLevel.ReportError(reflect.ValueOf(sleepState.Duration), "Duration", "duration", "reqiso8601duration", "")
47-
}
48-
}
49-
50-
func init() {
51-
val.GetValidator().RegisterStructValidationCtx(
52-
SleepStateStructLevelValidation,
53-
SleepState{},
54-
)
55-
}

model/sleep_state_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestSleepStateStructLevelValidation(t *testing.T) {
4949
},
5050
Duration: "T10S",
5151
},
52-
err: `Key: 'SleepState.Duration' Error:Field validation for 'Duration' failed on the 'reqiso8601duration' tag`,
52+
err: `Key: 'SleepState.Duration' Error:Field validation for 'Duration' failed on the 'iso8601duration' tag`,
5353
},
5454
}
5555

model/state_exec_timeout.go

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,16 @@ package model
1616

1717
import (
1818
"bytes"
19-
"context"
2019
"encoding/json"
2120
"fmt"
22-
"reflect"
23-
24-
validator "github.com/go-playground/validator/v10"
25-
val "github.com/serverlessworkflow/sdk-go/v2/validator"
2621
)
2722

2823
// StateExecTimeout defines workflow state execution timeout
2924
type StateExecTimeout struct {
3025
// Single state execution timeout, not including retries (ISO 8601 duration format)
31-
Single string `json:"single,omitempty"`
26+
Single string `json:"single,omitempty" validate:"omitempty,iso8601duration"`
3227
// Total state execution timeout, including retries (ISO 8601 duration format)
33-
Total string `json:"total" validate:"required"`
28+
Total string `json:"total" validate:"required,iso8601duration"`
3429
}
3530

3631
// just define another type to unmarshal object, so the UnmarshalJSON will not called recursively
@@ -64,28 +59,3 @@ func (s *StateExecTimeout) UnmarshalJSON(data []byte) error {
6459

6560
return fmt.Errorf("stateExecTimeout value '%s' not support, it must be an object or string", string(data))
6661
}
67-
68-
// StateExecTimeoutStructLevelValidation custom validator for StateExecTimeout
69-
func StateExecTimeoutStructLevelValidation(_ context.Context, structLevel validator.StructLevel) {
70-
timeoutObj := structLevel.Current().Interface().(StateExecTimeout)
71-
72-
// TODO: use Custom Validation Functions tags for iso8601duration
73-
err := validateISO8601TimeDuration(timeoutObj.Total)
74-
if err != nil {
75-
structLevel.ReportError(reflect.ValueOf(timeoutObj.Total), "Total", "total", "reqiso8601duration", "")
76-
}
77-
78-
if timeoutObj.Single != "" {
79-
err = validateISO8601TimeDuration(timeoutObj.Single)
80-
if err != nil {
81-
structLevel.ReportError(reflect.ValueOf(timeoutObj.Single), "Single", "single", "reqiso8601duration", "")
82-
}
83-
}
84-
}
85-
86-
func init() {
87-
val.GetValidator().RegisterStructValidationCtx(
88-
StateExecTimeoutStructLevelValidation,
89-
StateExecTimeout{},
90-
)
91-
}

model/state_exec_timeout_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,23 +142,23 @@ func TestStateExecTimeoutStructLevelValidation(t *testing.T) {
142142
Single: "PT10S",
143143
Total: "",
144144
},
145-
err: `Key: 'StateExecTimeout.Total' Error:Field validation for 'Total' failed on the 'required' tag\nKey: 'StateExecTimeout.Total' Error:Field validation for 'Total' failed on the 'reqiso8601duration' tag`,
145+
err: `Key: 'StateExecTimeout.Total' Error:Field validation for 'Total' failed on the 'required' tag`,
146146
},
147147
{
148148
desp: "invalid total duration",
149149
timeout: StateExecTimeout{
150150
Single: "PT10S",
151151
Total: "T10S",
152152
},
153-
err: `Key: 'StateExecTimeout.Total' Error:Field validation for 'Total' failed on the 'reqiso8601duration' tag`,
153+
err: `Key: 'StateExecTimeout.Total' Error:Field validation for 'Total' failed on the 'iso8601duration' tag`,
154154
},
155155
{
156156
desp: "invalid single duration",
157157
timeout: StateExecTimeout{
158158
Single: "T10S",
159159
Total: "PT10S",
160160
},
161-
err: `Key: 'StateExecTimeout.Single' Error:Field validation for 'Single' failed on the 'reqiso8601duration' tag`,
161+
err: `Key: 'StateExecTimeout.Single' Error:Field validation for 'Single' failed on the 'iso8601duration' tag`,
162162
},
163163
}
164164
for _, tc := range testCases {

model/util.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ import (
2121
"os"
2222
"path/filepath"
2323
"strings"
24-
25-
"github.com/senseyeio/duration"
2624
)
2725

2826
const prefix = "file:/"
@@ -92,8 +90,3 @@ func unmarshalFile(data []byte) (b []byte, err error) {
9290
}
9391
return file, nil
9492
}
95-
96-
func validateISO8601TimeDuration(s string) error {
97-
_, err := duration.ParseISO8601(s)
98-
return err
99-
}

model/util_test.go

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,3 @@
1313
// limitations under the License.
1414

1515
package model
16-
17-
import (
18-
"testing"
19-
20-
"github.com/stretchr/testify/assert"
21-
)
22-
23-
func TestValidateISO8601TimeDuration(t *testing.T) {
24-
type testCase struct {
25-
desp string
26-
s string
27-
err string
28-
}
29-
testCases := []testCase{
30-
{
31-
desp: "normal_all_designator",
32-
s: "P3Y6M4DT12H30M5S",
33-
err: ``,
34-
},
35-
{
36-
desp: "normal_second_designator",
37-
s: "PT5S",
38-
err: ``,
39-
},
40-
{
41-
desp: "empty value",
42-
s: "",
43-
err: `could not parse duration string`,
44-
},
45-
}
46-
for _, tc := range testCases {
47-
t.Run(tc.desp, func(t *testing.T) {
48-
err := validateISO8601TimeDuration(tc.s)
49-
50-
if tc.err != "" {
51-
assert.Error(t, err)
52-
assert.Regexp(t, tc.err, err)
53-
return
54-
}
55-
56-
assert.NoError(t, err)
57-
})
58-
}
59-
}

0 commit comments

Comments
 (0)