Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.80.2-0.20221028030830-9ae4992afb54 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
Expand All @@ -81,8 +81,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -96,8 +96,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
Expand Down
2 changes: 2 additions & 0 deletions model/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package model
import "github.com/serverlessworkflow/sdk-go/v2/util"

// Action specify invocations of services or other workflows during workflow execution.
// +builder-gen:new-call=ApplyDefault
type Action struct {
// Defines Unique action identifier.
// +optional
Expand Down Expand Up @@ -72,6 +73,7 @@ func (a *Action) ApplyDefault() {
}

// FunctionRef defines the reference to a reusable function definition
// +builder-gen:new-call=ApplyDefault
type FunctionRef struct {
// Name of the referenced function.
// +kubebuilder:validation:Required
Expand Down
3 changes: 1 addition & 2 deletions model/action_data_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ import "github.com/serverlessworkflow/sdk-go/v2/util"

// ActionDataFilter used to filter action data results.
// +optional
// +optional
// +builder-gen:new-call=ApplyDefault
type ActionDataFilter struct {
// Workflow expression that filters state data that can be used by the action.
// +optional
// +optional
FromStateData string `json:"fromStateData,omitempty"`
// If set to false, action data results are not added/merged to state data. In this case 'results'
// and 'toStateData' should be ignored. Default is true.
Expand Down
46 changes: 46 additions & 0 deletions model/builder/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2023 The Serverless Workflow Specification Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package builder

import (
"encoding/json"

"sigs.k8s.io/yaml"

"github.com/serverlessworkflow/sdk-go/v2/model"
)

func New() *model.WorkflowBuilder {
return model.NewWorkflowBuilder()
}

func AsObject(builder *model.WorkflowBuilder) *model.Workflow {
workflow := builder.Build()
return &workflow
}

func AsJson(builder *model.WorkflowBuilder) ([]byte, error) {
workflow := builder.Build()
return json.Marshal(workflow)
}

func AsYaml(builder *model.WorkflowBuilder) ([]byte, error) {
data, err := AsJson(builder)
if err != nil {
return nil, err
}

return yaml.JSONToYAML(data)
}
88 changes: 88 additions & 0 deletions model/builder/builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2023 The Serverless Workflow Specification Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package builder

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestBuild(t *testing.T) {
builder := New()
builder.BaseWorkflow().Key("key test")
builder.BaseWorkflow().ID("id test")

function := builder.AddFunction()
function.Name("function name")
function2 := builder.AddFunction()
function2.Name("function name2")

workflow := AsObject(builder)

assert.Equal(t, "key test", workflow.Key)
assert.Equal(t, "id test", workflow.ID)
assert.Equal(t, "0.8", workflow.SpecVersion)
assert.Equal(t, "jq", workflow.ExpressionLang.String())
assert.Equal(t, 2, len(workflow.Functions))

assert.Equal(t, "function name", workflow.Functions[0].Name)
assert.Equal(t, "function name2", workflow.Functions[1].Name)
}

func TestAsJson(t *testing.T) {
builder := New()
builder.BaseWorkflow().Key("key test")
builder.BaseWorkflow().ID("id test")
function := builder.AddFunction()
function.Name("function name")
function2 := builder.AddFunction()
function2.Name("function name2")

data, err := AsJson(builder)
if assert.NoError(t, err) {
d := `{"id":"id test","key":"key test","version":"","specVersion":"0.8","expressionLang":"jq","states":[],"functions":[{"name":"function name","operation":"","type":"rest"},{"name":"function name2","operation":"","type":"rest"}]}`
assert.Equal(t, d, string(data))
}
}

func TestAsYaml(t *testing.T) {
builder := New()
builder.BaseWorkflow().Key("key test")
builder.BaseWorkflow().ID("id test")
function := builder.AddFunction()
function.Name("function name")
function2 := builder.AddFunction()
function2.Name("function name2")

data, err := AsYaml(builder)
if assert.NoError(t, err) {
d := `expressionLang: jq
functions:
- name: function name
operation: ""
type: rest
- name: function name2
operation: ""
type: rest
id: id test
key: key test
specVersion: "0.8"
states: []
version: ""
`
assert.Equal(t, d, string(data))
}
}
3 changes: 3 additions & 0 deletions model/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (
)

// Event used to define events and their correlations
// +builder-gen:new-call=ApplyDefault
type Event struct {
Common `json:",inline"`
// Unique event name.
Expand All @@ -56,6 +57,7 @@ type Event struct {
Kind EventKind `json:"kind,omitempty" validate:"required,oneofkind"`
// If `true`, only the Event payload is accessible to consuming Workflow states. If `false`, both event payload
// and context attributes should be accessible. Defaults to true.
// +kubebuilder:default=true
// +optional
DataOnly bool `json:"dataOnly,omitempty"`
// Define event correlation rules for this event. Only used for consumed events.
Expand Down Expand Up @@ -88,6 +90,7 @@ type Correlation struct {
}

// EventRef defining invocation of a function via event
// +builder-gen:new-call=ApplyDefault
type EventRef struct {
// Reference to the unique name of a 'produced' event definition,
// +kubebuilder:validation:Required
Expand Down
1 change: 1 addition & 0 deletions model/event_data_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package model
import "github.com/serverlessworkflow/sdk-go/v2/util"

// EventDataFilter used to filter consumed event payloads.
// +builder-gen:new-call=ApplyDefault
type EventDataFilter struct {
// If set to false, event payload is not added/merged to state data. In this case 'data' and 'toStateData'
// should be ignored. Default is true.
Expand Down
2 changes: 2 additions & 0 deletions model/event_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

// EventState await one or more events and perform actions when they are received. If defined as the
// workflow starting state, the event state definition controls when the workflow instances should be created.
// +builder-gen:new-call=ApplyDefault
type EventState struct {
// TODO: EventState doesn't have usedForCompensation field.

Expand Down Expand Up @@ -64,6 +65,7 @@ func (e *EventState) ApplyDefault() {
}

// OnEvents define which actions are be performed for the one or more events.
// +builder-gen:new-call=ApplyDefault
type OnEvents struct {
// References one or more unique event names in the defined workflow events.
// +kubebuilder:validation:MinItems=1
Expand Down
1 change: 1 addition & 0 deletions model/foreach_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
)

// ForEachState used to execute actions for each element of a data set.
// +builder-gen:new-call=ApplyDefault
type ForEachState struct {
// Workflow expression selecting an array element of the states' data.
// +kubebuilder:validation:Required
Expand Down
1 change: 1 addition & 0 deletions model/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func (i FunctionType) String() string {
}

// Function ...
// +builder-gen:new-call=ApplyDefault
type Function struct {
Common `json:",inline"`
// Unique function name
Expand Down
1 change: 1 addition & 0 deletions model/operation_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
)

// OperationState defines a set of actions to be performed in sequence or in parallel.
// +builder-gen:new-call=ApplyDefault
type OperationState struct {
// Specifies whether actions are performed in sequence or in parallel, defaults to sequential.
// +kubebuilder:validation:Enum=sequential;parallel
Expand Down
1 change: 1 addition & 0 deletions model/parallel_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
)

// ParallelState Consists of a number of states that are executed in parallel
// +builder-gen:new-call=ApplyDefault
type ParallelState struct {
// List of branches for this parallel state.
// +kubebuilder:validation:MinItems=1
Expand Down
1 change: 1 addition & 0 deletions model/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
)

// Retry ...
// +builder-gen:new-call=ApplyDefault
type Retry struct {
// Unique retry strategy name
// +kubebuilder:validation:Required
Expand Down
14 changes: 9 additions & 5 deletions model/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const (

// BaseWorkflow describes the partial Workflow definition that does not rely on generic interfaces
// to make it easy for custom unmarshalers implementations to unmarshal the common data structure.
// +builder-gen:new-call=ApplyDefault
type BaseWorkflow struct {
// Workflow unique identifier
// +optional
Expand Down Expand Up @@ -167,6 +168,12 @@ type BaseWorkflow struct {
Auth Auths `json:"auth,omitempty" validate:"unique=Name,dive"`
}

// ApplyDefault set the default values for Workflow
func (w *BaseWorkflow) ApplyDefault() {
w.SpecVersion = "0.8"
w.ExpressionLang = JqExpressionLang
}

type Auths []Auth

type authsUnmarshal Auths
Expand Down Expand Up @@ -217,11 +224,6 @@ func (w *Workflow) UnmarshalJSON(data []byte) error {
return nil
}

// ApplyDefault set the default values for Workflow
func (w *Workflow) ApplyDefault() {
w.ExpressionLang = JqExpressionLang
}

// +kubebuilder:validation:MinItems=1
type States []State

Expand Down Expand Up @@ -288,6 +290,7 @@ func (t *Timeouts) UnmarshalJSON(data []byte) error {

// WorkflowExecTimeout property defines the workflow execution timeout. It is defined using the ISO 8601 duration
// format. If not defined, the workflow execution should be given "unlimited" amount of time to complete.
// +builder-gen:new-call=ApplyDefault
type WorkflowExecTimeout struct {
// Workflow execution timeout duration (ISO 8601 duration format). If not specified should be 'unlimited'.
// +kubebuilder:default=unlimited
Expand Down Expand Up @@ -503,6 +506,7 @@ type StateDataFilter struct {
}

// DataInputSchema Used to validate the workflow data input against a defined JSON Schema
// +builder-gen:new-call=ApplyDefault
type DataInputSchema struct {
// +kubebuilder:validation:Required
Schema string `json:"schema" validate:"required"`
Expand Down
1 change: 1 addition & 0 deletions model/workflow_ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const (
)

// WorkflowRef holds a reference for a workflow definition
// +builder-gen:new-call=ApplyDefault
type WorkflowRef struct {
// Sub-workflow unique id
// +kubebuilder:validation:Required
Expand Down
4 changes: 3 additions & 1 deletion model/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func TestWorkflowStartUnmarshalJSON(t *testing.T) {
data: `{"states": [{"name": "start state name", "type": "operation"}]}`,
expect: Workflow{
BaseWorkflow: BaseWorkflow{
SpecVersion: "0.8",
ExpressionLang: "jq",
Start: &Start{
StateName: "start state name",
Expand All @@ -72,10 +73,11 @@ func TestWorkflowStartUnmarshalJSON(t *testing.T) {
err: ``,
},
{
desp: "start empty, and states empty",
desp: "start empty and states empty",
data: `{"states": []}`,
expect: Workflow{
BaseWorkflow: BaseWorkflow{
SpecVersion: "0.8",
ExpressionLang: "jq",
},
States: []State{},
Expand Down
1 change: 1 addition & 0 deletions model/workflow_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func ValidationWrap(fnCtx WorkflowValidator) validator.StructLevelFuncCtx {
}
}

// +builder-gen:ignore=true
type ValidatorContext struct {
States map[string]State
Functions map[string]Function
Expand Down
Loading