From 95bc8909c295f9af5ab1c049949f1549315f323b Mon Sep 17 00:00:00 2001 From: Zike Yang Date: Fri, 16 Feb 2024 20:42:05 +0800 Subject: [PATCH 1/2] feat: add sink, source and runtime config to function config Signed-off-by: Zike Yang --- common/constants.go | 2 + common/errors.go | 6 +- common/model/function.go | 32 +++++-- common/model/function_serde_test.go | 126 +++++++++++++++++++++++++ common/utils.go | 21 +++++ fs/api/instance.go | 2 +- fs/contube/contube.go | 21 ++++- fs/instance_impl.go | 41 ++++---- fs/manager.go | 51 +++++++++- fs/runtime/grpc/grpc_func.go | 4 +- fs/runtime/grpc/grpc_func_test.go | 23 +++-- fs/runtime/grpc/mock_grpc_func_test.go | 9 +- fs/runtime/wazero/wazero_runtime.go | 13 ++- go.mod | 4 +- server/server.go | 12 ++- server/server_test.go | 6 +- 16 files changed, 319 insertions(+), 54 deletions(-) create mode 100644 common/model/function_serde_test.go create mode 100644 common/utils.go diff --git a/common/constants.go b/common/constants.go index 26e941e5..2003e0a4 100644 --- a/common/constants.go +++ b/common/constants.go @@ -23,4 +23,6 @@ const ( DefaultAddr = "localhost:7300" DefaultPulsarURL = "pulsar://localhost:6650" DefaultTubeType = PulsarTubeType + + RuntimeArchiveConfigKey = "archive" ) diff --git a/common/errors.go b/common/errors.go index 502e6189..ec03f70e 100644 --- a/common/errors.go +++ b/common/errors.go @@ -19,6 +19,8 @@ package common import "errors" var ( - ErrorFunctionNotFound = errors.New("function not found") - ErrorFunctionExists = errors.New("function already exists") + ErrorFunctionNotFound = errors.New("function not found") + ErrorFunctionExists = errors.New("function already exists") + ErrorTubeFactoryNotFound = errors.New("tube factory not found") + ErrorRuntimeFactoryNotFound = errors.New("runtime factory not found") ) diff --git a/common/model/function.go b/common/model/function.go index 69546584..799cd17a 100644 --- a/common/model/function.go +++ b/common/model/function.go @@ -16,15 +16,27 @@ package model +import "github.com/functionstream/functionstream/fs/contube" + +type TubeConfig struct { + Config contube.ConfigMap `json:"config,omitempty" yaml:"config,omitempty"` + Type *string `json:"type,omitempty" yaml:"type,omitempty"` // Default to `default` +} + +type ConfigMap map[string]interface{} + +type RuntimeConfig struct { + Config ConfigMap `json:"config,omitempty" yaml:"config,omitempty"` + Type *string `json:"type,omitempty" yaml:"type,omitempty"` +} + type Function struct { - Name string - Archive string - Source map[string]any - Sink map[string]any - // Deprecate - Inputs []string - // Deprecate - Output string - Config map[string]string - Replicas int32 + Name string `json:"name" yaml:"name"` + Runtime *RuntimeConfig `json:"runtime" yaml:"runtime"` + Source *TubeConfig `json:"source" yaml:"source"` + Sink *TubeConfig `json:"sink" yaml:"sink"` + Inputs []string `json:"inputs" yaml:"inputs"` + Output string `json:"output" yaml:"output"` + Config map[string]string `json:"config" yaml:"config"` + Replicas int32 `json:"replicas" yaml:"replicas"` } diff --git a/common/model/function_serde_test.go b/common/model/function_serde_test.go new file mode 100644 index 00000000..94044aa2 --- /dev/null +++ b/common/model/function_serde_test.go @@ -0,0 +1,126 @@ +/* + * Copyright 2024 Function Stream Org. + * + * 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 model + +import ( + "encoding/json" + "fmt" + "github.com/functionstream/functionstream/common" + "gopkg.in/yaml.v3" + "reflect" + "testing" +) + +func TestFunctionSerde(t *testing.T) { + f := Function{ + Name: "TestFunction", + Runtime: &RuntimeConfig{Type: common.OptionalStr("runtime"), Config: map[string]interface{}{"key": "value"}}, + Source: &TubeConfig{Type: common.OptionalStr("source"), Config: map[string]interface{}{"key": "value"}}, + Sink: &TubeConfig{Type: common.OptionalStr("sink"), Config: map[string]interface{}{"key": "value"}}, + Inputs: []string{"input1", "input2"}, + Output: "output", + Config: map[string]string{"key": "value"}, + Replicas: 2, + } + + // JSON Serialization + data, err := json.Marshal(f) + if err != nil { + t.Fatal("JSON Serialization error:", err) + } + + fmt.Println(string(data)) + + // JSON Deserialization + var f2 Function + err = json.Unmarshal(data, &f2) + if err != nil { + t.Fatal("JSON Deserialization error:", err) + } + + if !reflect.DeepEqual(f, f2) { + t.Error("JSON Deserialization does not match original") + } + + // YAML Serialization + data, err = yaml.Marshal(f) + if err != nil { + t.Fatal("YAML Serialization error:", err) + } + + fmt.Println(string(data)) + + // YAML Deserialization + err = yaml.Unmarshal(data, &f2) + if err != nil { + t.Fatal("YAML Deserialization error:", err) + } + + if !reflect.DeepEqual(f, f2) { + t.Error("YAML Deserialization does not match original") + } +} + +func TestFunctionSerdeWithNil(t *testing.T) { + f := Function{ + Name: "TestFunction", + Runtime: nil, + Source: nil, + Sink: nil, + Inputs: []string{"input1", "input2"}, + Output: "output", + Config: map[string]string{"key": "value"}, + Replicas: 2, + } + + // JSON Serialization + data, err := json.Marshal(f) + if err != nil { + t.Fatal("JSON Serialization error:", err) + } + + fmt.Println(string(data)) + + // JSON Deserialization + var f2 Function + err = json.Unmarshal(data, &f2) + if err != nil { + t.Fatal("JSON Deserialization error:", err) + } + + if !reflect.DeepEqual(f, f2) { + t.Error("JSON Deserialization does not match original") + } + + // YAML Serialization + data, err = yaml.Marshal(f) + if err != nil { + t.Fatal("YAML Serialization error:", err) + } + + fmt.Println(string(data)) + + // YAML Deserialization + err = yaml.Unmarshal(data, &f2) + if err != nil { + t.Fatal("YAML Deserialization error:", err) + } + + if !reflect.DeepEqual(f, f2) { + t.Error("YAML Deserialization does not match original") + } +} diff --git a/common/utils.go b/common/utils.go new file mode 100644 index 00000000..a5b5b13c --- /dev/null +++ b/common/utils.go @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Function Stream Org. + * + * 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 common + +func OptionalStr(s string) *string { + return &s +} diff --git a/fs/api/instance.go b/fs/api/instance.go index a2c83bb6..e2d6d544 100644 --- a/fs/api/instance.go +++ b/fs/api/instance.go @@ -31,5 +31,5 @@ type FunctionInstance interface { } type FunctionInstanceFactory interface { - NewFunctionInstance(f *model.Function, queueFactory contube.TubeFactory, i int32) FunctionInstance + NewFunctionInstance(f *model.Function, sourceFactory contube.SourceTubeFactory, sinkFactory contube.SinkTubeFactory, i int32) FunctionInstance } diff --git a/fs/contube/contube.go b/fs/contube/contube.go index 775caa1d..8119b392 100644 --- a/fs/contube/contube.go +++ b/fs/contube/contube.go @@ -74,16 +74,35 @@ func (c *SinkQueueConfig) ToConfigMap() ConfigMap { type ConfigMap map[string]interface{} -type TubeFactory interface { +// Merge merges multiple ConfigMap into one +func Merge(configs ...ConfigMap) ConfigMap { + result := ConfigMap{} + for _, config := range configs { + for k, v := range config { + result[k] = v + } + } + return result +} + +type SourceTubeFactory interface { // NewSourceTube returns a new channel that can be used to receive events // The channel would be closed when the context is done NewSourceTube(ctx context.Context, config ConfigMap) (<-chan Record, error) +} + +type SinkTubeFactory interface { // NewSinkTube returns a new channel that can be used to sink events // The event.Commit() would be invoked after the event is sunk successfully // The caller should close the channel when it is done NewSinkTube(ctx context.Context, config ConfigMap) (chan<- Record, error) } +type TubeFactory interface { + SourceTubeFactory + SinkTubeFactory +} + type RecordImpl struct { payload []byte commitFunc func() diff --git a/fs/instance_impl.go b/fs/instance_impl.go index 2c108716..f71f4b84 100644 --- a/fs/instance_impl.go +++ b/fs/instance_impl.go @@ -28,12 +28,13 @@ import ( ) type FunctionInstanceImpl struct { - ctx context.Context - cancelFunc context.CancelFunc - definition *model.Function - tubeFactory contube.TubeFactory - readyCh chan error - index int32 + ctx context.Context + cancelFunc context.CancelFunc + definition *model.Function + sourceFactory contube.SourceTubeFactory + sinkFactory contube.SinkTubeFactory + readyCh chan error + index int32 } type DefaultInstanceFactory struct{} @@ -42,19 +43,20 @@ func NewDefaultInstanceFactory() api.FunctionInstanceFactory { return &DefaultInstanceFactory{} } -func (f *DefaultInstanceFactory) NewFunctionInstance(definition *model.Function, queueFactory contube.TubeFactory, index int32) api.FunctionInstance { +func (f *DefaultInstanceFactory) NewFunctionInstance(definition *model.Function, sourceFactory contube.SourceTubeFactory, sinkFactory contube.SinkTubeFactory, index int32) api.FunctionInstance { ctx, cancelFunc := context.WithCancel(context.Background()) ctx.Value(logrus.Fields{ "function-name": definition.Name, "function-index": index, }) return &FunctionInstanceImpl{ - ctx: ctx, - cancelFunc: cancelFunc, - definition: definition, - tubeFactory: queueFactory, - readyCh: make(chan error), - index: index, + ctx: ctx, + cancelFunc: cancelFunc, + definition: definition, + sourceFactory: sourceFactory, + sinkFactory: sinkFactory, + readyCh: make(chan error), + index: index, } } @@ -73,13 +75,20 @@ func (instance *FunctionInstanceImpl) Run(runtimeFactory api.FunctionRuntimeFact instance.readyCh <- errors.Wrap(err, "Error creating runtime") return } - - sourceChan, err := instance.tubeFactory.NewSourceTube(instance.ctx, (&contube.SourceQueueConfig{Topics: instance.definition.Inputs, SubName: fmt.Sprintf("function-stream-%s", instance.definition.Name)}).ToConfigMap()) + getTubeConfig := func(config contube.ConfigMap, tubeConfig *model.TubeConfig) contube.ConfigMap { + if tubeConfig != nil && tubeConfig.Config != nil { + return contube.Merge(config, tubeConfig.Config) + } + return config + } + sourceConfig := (&contube.SourceQueueConfig{Topics: instance.definition.Inputs, SubName: fmt.Sprintf("function-stream-%s", instance.definition.Name)}).ToConfigMap() + sourceChan, err := instance.sourceFactory.NewSourceTube(instance.ctx, getTubeConfig(sourceConfig, instance.definition.Source)) if err != nil { instance.readyCh <- errors.Wrap(err, "Error creating source event queue") return } - sinkChan, err := instance.tubeFactory.NewSinkTube(instance.ctx, (&contube.SinkQueueConfig{Topic: instance.definition.Output}).ToConfigMap()) + sinkConfig := (&contube.SinkQueueConfig{Topic: instance.definition.Output}).ToConfigMap() + sinkChan, err := instance.sinkFactory.NewSinkTube(instance.ctx, getTubeConfig(sinkConfig, instance.definition.Sink)) if err != nil { instance.readyCh <- errors.Wrap(err, "Error creating sink event queue") return diff --git a/fs/manager.go b/fs/manager.go index d4ca46d4..435750ce 100644 --- a/fs/manager.go +++ b/fs/manager.go @@ -100,6 +100,38 @@ func NewFunctionManager(opts ...ManagerOption) (*FunctionManager, error) { }, nil } +func (fm *FunctionManager) getTubeFactory(tubeConfig *model.TubeConfig) (contube.TubeFactory, error) { + get := func(t string) (contube.TubeFactory, error) { + factory, exist := fm.options.tubeFactoryMap[t] + if !exist { + slog.ErrorContext(context.Background(), "tube factory not found", "type", t) + return nil, common.ErrorTubeFactoryNotFound + } + return factory, nil + + } + if tubeConfig == nil || tubeConfig.Type == nil { + return get("default") + } + return get(*tubeConfig.Type) +} + +func (fm *FunctionManager) getRuntimeFactory(runtimeConfig *model.RuntimeConfig) (api.FunctionRuntimeFactory, error) { + get := func(t string) (api.FunctionRuntimeFactory, error) { + factory, exist := fm.options.runtimeFactoryMap[t] + if !exist { + slog.ErrorContext(context.Background(), "runtime factory not found", "type", t) + return nil, common.ErrorRuntimeFactoryNotFound + } + return factory, nil + + } + if runtimeConfig == nil || runtimeConfig.Type == nil { + return get("default") + } + return get(*runtimeConfig.Type) +} + func (fm *FunctionManager) StartFunction(f *model.Function) error { fm.functionsLock.Lock() defer fm.functionsLock.Unlock() // TODO: narrow the lock scope @@ -108,12 +140,25 @@ func (fm *FunctionManager) StartFunction(f *model.Function) error { } fm.functions[f.Name] = make([]api.FunctionInstance, f.Replicas) for i := int32(0); i < f.Replicas; i++ { - instance := fm.options.instanceFactory.NewFunctionInstance(f, fm.options.tubeFactoryMap["default"], i) + sourceFactory, err := fm.getTubeFactory(f.Source) + if err != nil { + return err + } + sinkFactory, err := fm.getTubeFactory(f.Sink) + if err != nil { + return err + } + + instance := fm.options.instanceFactory.NewFunctionInstance(f, sourceFactory, sinkFactory, i) fm.functions[f.Name][i] = instance - go instance.Run(fm.options.runtimeFactoryMap["default"]) + runtimeFactory, err := fm.getRuntimeFactory(f.Runtime) + if err != nil { + return err + } + go instance.Run(runtimeFactory) if err := <-instance.WaitForReady(); err != nil { if err != nil { - slog.ErrorContext(instance.Context(), "Error starting function instance", err) + slog.ErrorContext(instance.Context(), "Error starting function instance", slog.Any("error", err.Error())) } instance.Stop() return err diff --git a/fs/runtime/grpc/grpc_func.go b/fs/runtime/grpc/grpc_func.go index 23235f67..fa01e71f 100644 --- a/fs/runtime/grpc/grpc_func.go +++ b/fs/runtime/grpc/grpc_func.go @@ -245,8 +245,8 @@ func (f *FunctionServerImpl) Process(stream proto.Function_ProcessServer) error } } -func StartGRPCServer(f *FSSReconcileServer, port int) (*grpc.Server, error) { - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) +func StartGRPCServer(f *FSSReconcileServer, addr string) (*grpc.Server, error) { + lis, err := net.Listen("tcp", addr) if err != nil { return nil, err } diff --git a/fs/runtime/grpc/grpc_func_test.go b/fs/runtime/grpc/grpc_func_test.go index 5049dcd3..36c1ed92 100644 --- a/fs/runtime/grpc/grpc_func_test.go +++ b/fs/runtime/grpc/grpc_func_test.go @@ -18,6 +18,7 @@ package grpc import ( "context" + "github.com/functionstream/functionstream/common" "github.com/functionstream/functionstream/common/model" "github.com/functionstream/functionstream/fs" "github.com/functionstream/functionstream/fs/api" @@ -55,15 +56,15 @@ func (m *mockInstance) WaitForReady() <-chan error { func TestGRPCFunc(t *testing.T) { ctx, closeFSReconcile := context.WithCancel(context.Background()) fsService := NewFSReconcile(ctx) - port := 17400 - s, err := StartGRPCServer(fsService, port) // The test may running in parallel with other tests, so we need to specify the port + addr := "localhost:17400" + s, err := StartGRPCServer(fsService, addr) // The test may running in parallel with other tests, so we need to specify the port if err != nil { t.Fatal(err) return } defer s.Stop() - go StartMockGRPCFunc(t, port) + go StartMockGRPCFunc(t, addr) select { case <-fsService.WaitForReady(): @@ -119,14 +120,14 @@ func TestGRPCFunc(t *testing.T) { func TestFMWithGRPCRuntime(t *testing.T) { ctx, closeFSReconcile := context.WithCancel(context.Background()) fsService := NewFSReconcile(ctx) - port := 17401 - s, err := StartGRPCServer(fsService, port) + addr := "localhost:17401" + s, err := StartGRPCServer(fsService, addr) if err != nil { t.Fatal(err) return } defer s.Stop() - go StartMockGRPCFunc(t, port) + go StartMockGRPCFunc(t, addr) select { case <-fsService.WaitForReady(): t.Logf("ready") @@ -136,14 +137,20 @@ func TestFMWithGRPCRuntime(t *testing.T) { } fm, err := fs.NewFunctionManager( - fs.WithDefaultRuntimeFactory(fsService), + fs.WithRuntimeFactory("grpc", fsService), fs.WithDefaultTubeFactory(contube.NewMemoryQueueFactory(ctx))) if err != nil { t.Fatal(err) } f := &model.Function{ - Name: "test", + Name: "test", + Runtime: &model.RuntimeConfig{ + Type: common.OptionalStr("grpc"), + Config: map[string]interface{}{ + "addr": addr, + }, + }, Inputs: []string{"input"}, Output: "output", Replicas: 1, diff --git a/fs/runtime/grpc/mock_grpc_func_test.go b/fs/runtime/grpc/mock_grpc_func_test.go index ce90e31c..d2dabd55 100644 --- a/fs/runtime/grpc/mock_grpc_func_test.go +++ b/fs/runtime/grpc/mock_grpc_func_test.go @@ -17,7 +17,6 @@ package grpc import ( - "fmt" "github.com/functionstream/functionstream/fs/runtime/grpc/proto" "golang.org/x/net/context" "google.golang.org/grpc" @@ -30,8 +29,7 @@ import ( "testing" ) -func StartMockGRPCFunc(t *testing.T, port int) { - addr := fmt.Sprintf("localhost:%d", port) +func StartMockGRPCFunc(t *testing.T, addr string) { // Set up a connection to the server. conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { @@ -97,6 +95,11 @@ func StartMockGRPCFunc(t *testing.T, port int) { return } if err != nil { + s, ok := status.FromError(err) + if ok && s.Code() == codes.Unavailable { + slog.Info("server disconnected") + return + } t.Errorf("failed to receive event: %v", err) return } diff --git a/fs/runtime/wazero/wazero_runtime.go b/fs/runtime/wazero/wazero_runtime.go index 6e5df931..f75ae617 100644 --- a/fs/runtime/wazero/wazero_runtime.go +++ b/fs/runtime/wazero/wazero_runtime.go @@ -54,7 +54,18 @@ func (f *WazeroFunctionRuntimeFactory) NewFunctionRuntime(instance api.FunctionI wasi_snapshot_preview1.MustInstantiate(instance.Context(), r) - wasmBytes, err := os.ReadFile(instance.Definition().Archive) + if instance.Definition().Runtime == nil || instance.Definition().Runtime.Config == nil { + return nil, errors.New("No runtime config found") + } + path, exist := instance.Definition().Runtime.Config["archive"] + if !exist { + return nil, errors.New("No wasm archive found") + } + pathStr := path.(string) + if pathStr == "" { + return nil, errors.New("Empty wasm archive found") + } + wasmBytes, err := os.ReadFile(pathStr) if err != nil { return nil, errors.Wrap(err, "Error reading wasm file") } diff --git a/go.mod b/go.mod index 4438cc55..8364986c 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,11 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/tetratelabs/wazero v1.6.0 + golang.org/x/net v0.21.0 golang.org/x/time v0.5.0 google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -56,7 +58,6 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.19.0 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.21.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/term v0.17.0 // indirect @@ -66,7 +67,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apimachinery v0.29.1 // indirect k8s.io/client-go v0.29.1 // indirect k8s.io/klog/v2 v2.120.1 // indirect diff --git a/server/server.go b/server/server.go index 4ecdf0a4..51f2535f 100644 --- a/server/server.go +++ b/server/server.go @@ -292,10 +292,14 @@ func constructFunction(function *restclient.Function) (*model.Function, error) { return nil, errors.New("function name is required") } f := &model.Function{ - Name: *function.Name, - Archive: function.Archive, - Inputs: function.Inputs, - Output: function.Output, + Name: *function.Name, + Runtime: &model.RuntimeConfig{ + Config: map[string]interface{}{ + common.RuntimeArchiveConfigKey: function.Archive, + }, + }, + Inputs: function.Inputs, + Output: function.Output, } if function.Replicas != nil { f.Replicas = *function.Replicas diff --git a/server/server_test.go b/server/server_test.go index dcfabbb3..defe27d4 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -48,7 +48,11 @@ func TestStandaloneBasicFunction(t *testing.T) { outputTopic := "test-output-" + strconv.Itoa(rand.Int()) funcConf := &model.Function{ - Archive: "../bin/example_basic.wasm", + Runtime: &model.RuntimeConfig{ + Config: map[string]interface{}{ + common.RuntimeArchiveConfigKey: "../bin/example_basic.wasm", + }, + }, Inputs: []string{inputTopic}, Output: outputTopic, Name: "test-func", From 453cbd65861125484dd9960b53fbb1148a31e2bd Mon Sep 17 00:00:00 2001 From: Zike Yang Date: Fri, 16 Feb 2024 21:22:02 +0800 Subject: [PATCH 2/2] feat: update function config in rest Signed-off-by: Zike Yang --- benchmark/bench_test.go | 16 ++- cmd/client/create/cmd.go | 11 +- common/model/function.go | 6 +- fs/manager.go | 4 + openapi.yaml | 48 ++++++-- perf/perf.go | 10 +- restclient/README.md | 33 +++--- restclient/docs/Function.md | 130 +++++++++++++------- restclient/docs/FunctionRuntime.md | 92 ++++++++++++++ restclient/docs/FunctionSource.md | 92 ++++++++++++++ restclient/docs/RuntimeConfig.md | 92 ++++++++++++++ restclient/docs/TubeConfig.md | 92 ++++++++++++++ restclient/model_function.go | 158 +++++++++++++++++-------- restclient/model_function_runtime.go | 171 +++++++++++++++++++++++++++ restclient/model_function_source.go | 171 +++++++++++++++++++++++++++ restclient/model_runtime_config.go | 171 +++++++++++++++++++++++++++ restclient/model_tube_config.go | 171 +++++++++++++++++++++++++++ server/server.go | 25 ++-- tests/integration_test.go | 24 +++- 19 files changed, 1366 insertions(+), 151 deletions(-) create mode 100644 restclient/docs/FunctionRuntime.md create mode 100644 restclient/docs/FunctionSource.md create mode 100644 restclient/docs/RuntimeConfig.md create mode 100644 restclient/docs/TubeConfig.md create mode 100644 restclient/model_function_runtime.go create mode 100644 restclient/model_function_source.go create mode 100644 restclient/model_runtime_config.go create mode 100644 restclient/model_tube_config.go diff --git a/benchmark/bench_test.go b/benchmark/bench_test.go index 8ac8d36d..ade2ea41 100644 --- a/benchmark/bench_test.go +++ b/benchmark/bench_test.go @@ -71,10 +71,14 @@ func BenchmarkStressForBasicFunc(b *testing.B) { PulsarURL: "pulsar://localhost:6650", RequestRate: 200000.0, Func: &restclient.Function{ - Archive: "../bin/example_basic.wasm", + Runtime: &restclient.FunctionRuntime{ + Config: map[string]interface{}{ + common.RuntimeArchiveConfigKey: "../bin/example_basic.wasm", + }, + }, Inputs: []string{inputTopic}, Output: outputTopic, - Replicas: &replicas, + Replicas: replicas, }, } @@ -132,10 +136,14 @@ func BenchmarkStressForBasicFuncWithMemoryQueue(b *testing.B) { pConfig := &perf.Config{ RequestRate: 200000.0, Func: &restclient.Function{ - Archive: "../bin/example_basic.wasm", + Runtime: &restclient.FunctionRuntime{ + Config: map[string]interface{}{ + common.RuntimeArchiveConfigKey: "../bin/example_basic.wasm", + }, + }, Inputs: []string{inputTopic}, Output: outputTopic, - Replicas: &replicas, + Replicas: replicas, }, QueueBuilder: func(ctx context.Context, c *common.Config) (contube.TubeFactory, error) { return memoryQueueFactory, nil diff --git a/cmd/client/create/cmd.go b/cmd/client/create/cmd.go index ded4f5fd..69b692ae 100644 --- a/cmd/client/create/cmd.go +++ b/cmd/client/create/cmd.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "github.com/functionstream/functionstream/cmd/client/common" + fs_cmmon "github.com/functionstream/functionstream/common" "github.com/functionstream/functionstream/restclient" "github.com/spf13/cobra" "io" @@ -63,10 +64,12 @@ func exec(_ *cobra.Command, _ []string) { }} cli := restclient.NewAPIClient(cfg) f := restclient.Function{ - Name: &config.name, - Archive: config.archive, - Inputs: config.inputs, - Output: config.output, + Name: &config.name, + Runtime: &restclient.FunctionRuntime{Config: map[string]interface{}{ + fs_cmmon.RuntimeArchiveConfigKey: config.archive, + }}, + Inputs: config.inputs, + Output: config.output, } res, err := cli.DefaultAPI.ApiV1FunctionFunctionNamePost(context.Background(), config.name).Function(f).Execute() diff --git a/common/model/function.go b/common/model/function.go index 799cd17a..f6d1c2f2 100644 --- a/common/model/function.go +++ b/common/model/function.go @@ -33,10 +33,10 @@ type RuntimeConfig struct { type Function struct { Name string `json:"name" yaml:"name"` Runtime *RuntimeConfig `json:"runtime" yaml:"runtime"` - Source *TubeConfig `json:"source" yaml:"source"` - Sink *TubeConfig `json:"sink" yaml:"sink"` + Source *TubeConfig `json:"source,omitempty" yaml:"source,omitempty"` + Sink *TubeConfig `json:"sink,omitempty" yaml:"sink,omitempty"` Inputs []string `json:"inputs" yaml:"inputs"` Output string `json:"output" yaml:"output"` - Config map[string]string `json:"config" yaml:"config"` + Config map[string]string `json:"config,omitempty" yaml:"config,omitempty"` Replicas int32 `json:"replicas" yaml:"replicas"` } diff --git a/fs/manager.go b/fs/manager.go index 435750ce..de2475d3 100644 --- a/fs/manager.go +++ b/fs/manager.go @@ -23,6 +23,7 @@ import ( "github.com/functionstream/functionstream/fs/api" "github.com/functionstream/functionstream/fs/contube" "github.com/functionstream/functionstream/fs/runtime/wazero" + "github.com/pkg/errors" "log/slog" "math/rand" "strconv" @@ -139,6 +140,9 @@ func (fm *FunctionManager) StartFunction(f *model.Function) error { return common.ErrorFunctionExists } fm.functions[f.Name] = make([]api.FunctionInstance, f.Replicas) + if f.Replicas <= 0 { + return errors.New("replicas should be greater than 0") + } for i := int32(0); i < f.Replicas; i++ { sourceFactory, err := fm.getTubeFactory(f.Source) if err != nil { diff --git a/openapi.yaml b/openapi.yaml index b526a2bd..e29a8787 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -118,32 +118,58 @@ paths: type: string components: schemas: + ConfigMap: + type: object + additionalProperties: true + RuntimeConfig: + type: object + properties: + config: + $ref: '#/components/schemas/ConfigMap' + type: + type: string + nullable: true + TubeConfig: + type: object + properties: + config: + $ref: '#/components/schemas/ConfigMap' + type: + type: string + nullable: true Function: type: object properties: name: type: string - archive: - type: string + runtime: + allOf: + - $ref: '#/components/schemas/RuntimeConfig' + - nullable: true + source: + allOf: + - $ref: '#/components/schemas/TubeConfig' + - nullable: true + sink: + allOf: + - $ref: '#/components/schemas/TubeConfig' + - nullable: true inputs: type: array items: type: string output: type: string - replicas: - type: integer config: type: object additionalProperties: type: string + replicas: + type: integer + format: int32 required: - - archive + - source + - sink - inputs - output - example: - name: "test-func" - archive: "/path/to/func.wasm" - inputs: [ "input1", "input2" ] - output: "output" - config: { "key": "value" } + - replicas \ No newline at end of file diff --git a/perf/perf.go b/perf/perf.go index 35f16561..a0641ae3 100644 --- a/perf/perf.go +++ b/perf/perf.go @@ -87,9 +87,13 @@ func (p *perf) Run(ctx context.Context) { f = *p.config.Func } else { f = restclient.Function{ - Archive: "./bin/example_basic.wasm", - Inputs: []string{"test-input-" + strconv.Itoa(rand.Int())}, - Output: "test-output-" + strconv.Itoa(rand.Int()), + Runtime: &restclient.FunctionRuntime{ + Config: map[string]interface{}{ + common.RuntimeArchiveConfigKey: "./bin/example_basic.wasm", + }, + }, + Inputs: []string{"test-input-" + strconv.Itoa(rand.Int())}, + Output: "test-output-" + strconv.Itoa(rand.Int()), } } diff --git a/restclient/README.md b/restclient/README.md index 636fb63e..7c5ded4e 100644 --- a/restclient/README.md +++ b/restclient/README.md @@ -3,9 +3,7 @@ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) ## Overview - -This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using -the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client. +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client. - API version: 0.1.0 - Package version: 1.0.0 @@ -46,8 +44,7 @@ ctx := context.WithValue(context.Background(), restclient.ContextServerIndex, 1) ### Templated Server URL -Templated server URL is formatted using default variables from configuration or from context -value `restclient.ContextServerVariables` of type `map[string]string`. +Templated server URL is formatted using default variables from configuration or from context value `restclient.ContextServerVariables` of type `map[string]string`. ```go ctx := context.WithValue(context.Background(), restclient.ContextServerVariables, map[string]string{ @@ -61,8 +58,7 @@ Note, enum values are always validated and all unused variables are silently ign Each operation can use different server URL defined using `OperationServers` map in the `Configuration`. An operation is uniquely identified by `"{classname}Service.{nickname}"` string. -Similar rules for overriding default operation server index and variables applies by -using `restclient.ContextOperationServerIndices` and `restclient.ContextOperationServerVariables` context maps. +Similar rules for overriding default operation server index and variables applies by using `restclient.ContextOperationServerIndices` and `restclient.ContextOperationServerVariables` context maps. ```go ctx := context.WithValue(context.Background(), restclient.ContextOperationServerIndices, map[string]int{ @@ -79,22 +75,29 @@ ctx = context.WithValue(context.Background(), restclient.ContextOperationServerV All URIs are relative to *http://localhost:7300* - Class | Method | HTTP request | Description ---------------|-------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------- - *DefaultAPI* | [**ApiV1ConsumeQueueNameGet**](docs/DefaultAPI.md#apiv1consumequeuenameget) | **Get** /api/v1/consume/{queue_name} | Consumes an event from a queue - *DefaultAPI* | [**ApiV1FunctionFunctionNameDelete**](docs/DefaultAPI.md#apiv1functionfunctionnamedelete) | **Delete** /api/v1/function/{function_name} | Deletes a function - *DefaultAPI* | [**ApiV1FunctionFunctionNamePost**](docs/DefaultAPI.md#apiv1functionfunctionnamepost) | **Post** /api/v1/function/{function_name} | Starts a function - *DefaultAPI* | [**ApiV1FunctionsGet**](docs/DefaultAPI.md#apiv1functionsget) | **Get** /api/v1/functions | Returns a list of functions - *DefaultAPI* | [**ApiV1ProduceQueueNamePut**](docs/DefaultAPI.md#apiv1producequeuenameput) | **Put** /api/v1/produce/{queue_name} | Produces an event to a queue +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*DefaultAPI* | [**ApiV1ConsumeQueueNameGet**](docs/DefaultAPI.md#apiv1consumequeuenameget) | **Get** /api/v1/consume/{queue_name} | Consumes an event from a queue +*DefaultAPI* | [**ApiV1FunctionFunctionNameDelete**](docs/DefaultAPI.md#apiv1functionfunctionnamedelete) | **Delete** /api/v1/function/{function_name} | Deletes a function +*DefaultAPI* | [**ApiV1FunctionFunctionNamePost**](docs/DefaultAPI.md#apiv1functionfunctionnamepost) | **Post** /api/v1/function/{function_name} | Starts a function +*DefaultAPI* | [**ApiV1FunctionsGet**](docs/DefaultAPI.md#apiv1functionsget) | **Get** /api/v1/functions | Returns a list of functions +*DefaultAPI* | [**ApiV1ProduceQueueNamePut**](docs/DefaultAPI.md#apiv1producequeuenameput) | **Put** /api/v1/produce/{queue_name} | Produces an event to a queue + ## Documentation For Models -- [Function](docs/Function.md) + - [Function](docs/Function.md) + - [FunctionRuntime](docs/FunctionRuntime.md) + - [FunctionSource](docs/FunctionSource.md) + - [RuntimeConfig](docs/RuntimeConfig.md) + - [TubeConfig](docs/TubeConfig.md) + ## Documentation For Authorization Endpoints do not require authorization. + ## Documentation for Utility Methods Due to the fact that model structure members are all pointers, this package contains diff --git a/restclient/docs/Function.md b/restclient/docs/Function.md index 8632d438..9bc14b11 100644 --- a/restclient/docs/Function.md +++ b/restclient/docs/Function.md @@ -2,20 +2,22 @@ ## Properties - Name | Type | Description | Notes ---------------|----------------------------------|-------------|------------ - **Name** | Pointer to **string** | | [optional] - **Archive** | **string** | | - **Inputs** | **[]string** | | - **Output** | **string** | | - **Replicas** | Pointer to **int32** | | [optional] - **Config** | Pointer to **map[string]string** | | [optional] +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | Pointer to **string** | | [optional] +**Runtime** | Pointer to [**FunctionRuntime**](FunctionRuntime.md) | | [optional] +**Source** | [**FunctionSource**](FunctionSource.md) | | +**Sink** | [**FunctionSource**](FunctionSource.md) | | +**Inputs** | **[]string** | | +**Output** | **string** | | +**Config** | Pointer to **map[string]string** | | [optional] +**Replicas** | **int32** | | ## Methods ### NewFunction -`func NewFunction(archive string, inputs []string, output string, ) *Function` +`func NewFunction(source FunctionSource, sink FunctionSource, inputs []string, output string, replicas int32, ) *Function` NewFunction instantiates a new Function object This constructor will assign default values to properties that have it defined, @@ -55,24 +57,70 @@ SetName sets Name field to given value. HasName returns a boolean if a field has been set. -### GetArchive +### GetRuntime -`func (o *Function) GetArchive() string` +`func (o *Function) GetRuntime() FunctionRuntime` -GetArchive returns the Archive field if non-nil, zero value otherwise. +GetRuntime returns the Runtime field if non-nil, zero value otherwise. -### GetArchiveOk +### GetRuntimeOk -`func (o *Function) GetArchiveOk() (*string, bool)` +`func (o *Function) GetRuntimeOk() (*FunctionRuntime, bool)` -GetArchiveOk returns a tuple with the Archive field if it's non-nil, zero value otherwise +GetRuntimeOk returns a tuple with the Runtime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetArchive +### SetRuntime -`func (o *Function) SetArchive(v string)` +`func (o *Function) SetRuntime(v FunctionRuntime)` + +SetRuntime sets Runtime field to given value. + +### HasRuntime + +`func (o *Function) HasRuntime() bool` + +HasRuntime returns a boolean if a field has been set. + +### GetSource + +`func (o *Function) GetSource() FunctionSource` + +GetSource returns the Source field if non-nil, zero value otherwise. + +### GetSourceOk + +`func (o *Function) GetSourceOk() (*FunctionSource, bool)` + +GetSourceOk returns a tuple with the Source field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSource + +`func (o *Function) SetSource(v FunctionSource)` + +SetSource sets Source field to given value. + + +### GetSink + +`func (o *Function) GetSink() FunctionSource` + +GetSink returns the Sink field if non-nil, zero value otherwise. + +### GetSinkOk + +`func (o *Function) GetSinkOk() (*FunctionSource, bool)` + +GetSinkOk returns a tuple with the Sink field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetSink + +`func (o *Function) SetSink(v FunctionSource)` + +SetSink sets Sink field to given value. -SetArchive sets Archive field to given value. ### GetInputs @@ -93,6 +141,7 @@ and a boolean to check if the value has been set. SetInputs sets Inputs field to given value. + ### GetOutput `func (o *Function) GetOutput() string` @@ -112,30 +161,6 @@ and a boolean to check if the value has been set. SetOutput sets Output field to given value. -### GetReplicas - -`func (o *Function) GetReplicas() int32` - -GetReplicas returns the Replicas field if non-nil, zero value otherwise. - -### GetReplicasOk - -`func (o *Function) GetReplicasOk() (*int32, bool)` - -GetReplicasOk returns a tuple with the Replicas field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetReplicas - -`func (o *Function) SetReplicas(v int32)` - -SetReplicas sets Replicas field to given value. - -### HasReplicas - -`func (o *Function) HasReplicas() bool` - -HasReplicas returns a boolean if a field has been set. ### GetConfig @@ -162,6 +187,27 @@ SetConfig sets Config field to given value. HasConfig returns a boolean if a field has been set. +### GetReplicas + +`func (o *Function) GetReplicas() int32` + +GetReplicas returns the Replicas field if non-nil, zero value otherwise. + +### GetReplicasOk + +`func (o *Function) GetReplicasOk() (*int32, bool)` + +GetReplicasOk returns a tuple with the Replicas field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetReplicas + +`func (o *Function) SetReplicas(v int32)` + +SetReplicas sets Replicas field to given value. + + + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/restclient/docs/FunctionRuntime.md b/restclient/docs/FunctionRuntime.md new file mode 100644 index 00000000..304c6a18 --- /dev/null +++ b/restclient/docs/FunctionRuntime.md @@ -0,0 +1,92 @@ +# FunctionRuntime + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Config** | Pointer to **map[string]interface{}** | | [optional] +**Type** | Pointer to **NullableString** | | [optional] + +## Methods + +### NewFunctionRuntime + +`func NewFunctionRuntime() *FunctionRuntime` + +NewFunctionRuntime instantiates a new FunctionRuntime object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewFunctionRuntimeWithDefaults + +`func NewFunctionRuntimeWithDefaults() *FunctionRuntime` + +NewFunctionRuntimeWithDefaults instantiates a new FunctionRuntime object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetConfig + +`func (o *FunctionRuntime) GetConfig() map[string]interface{}` + +GetConfig returns the Config field if non-nil, zero value otherwise. + +### GetConfigOk + +`func (o *FunctionRuntime) GetConfigOk() (*map[string]interface{}, bool)` + +GetConfigOk returns a tuple with the Config field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetConfig + +`func (o *FunctionRuntime) SetConfig(v map[string]interface{})` + +SetConfig sets Config field to given value. + +### HasConfig + +`func (o *FunctionRuntime) HasConfig() bool` + +HasConfig returns a boolean if a field has been set. + +### GetType + +`func (o *FunctionRuntime) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *FunctionRuntime) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *FunctionRuntime) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *FunctionRuntime) HasType() bool` + +HasType returns a boolean if a field has been set. + +### SetTypeNil + +`func (o *FunctionRuntime) SetTypeNil(b bool)` + + SetTypeNil sets the value for Type to be an explicit nil + +### UnsetType +`func (o *FunctionRuntime) UnsetType()` + +UnsetType ensures that no value is present for Type, not even an explicit nil + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/restclient/docs/FunctionSource.md b/restclient/docs/FunctionSource.md new file mode 100644 index 00000000..806c3b55 --- /dev/null +++ b/restclient/docs/FunctionSource.md @@ -0,0 +1,92 @@ +# FunctionSource + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Config** | Pointer to **map[string]interface{}** | | [optional] +**Type** | Pointer to **NullableString** | | [optional] + +## Methods + +### NewFunctionSource + +`func NewFunctionSource() *FunctionSource` + +NewFunctionSource instantiates a new FunctionSource object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewFunctionSourceWithDefaults + +`func NewFunctionSourceWithDefaults() *FunctionSource` + +NewFunctionSourceWithDefaults instantiates a new FunctionSource object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetConfig + +`func (o *FunctionSource) GetConfig() map[string]interface{}` + +GetConfig returns the Config field if non-nil, zero value otherwise. + +### GetConfigOk + +`func (o *FunctionSource) GetConfigOk() (*map[string]interface{}, bool)` + +GetConfigOk returns a tuple with the Config field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetConfig + +`func (o *FunctionSource) SetConfig(v map[string]interface{})` + +SetConfig sets Config field to given value. + +### HasConfig + +`func (o *FunctionSource) HasConfig() bool` + +HasConfig returns a boolean if a field has been set. + +### GetType + +`func (o *FunctionSource) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *FunctionSource) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *FunctionSource) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *FunctionSource) HasType() bool` + +HasType returns a boolean if a field has been set. + +### SetTypeNil + +`func (o *FunctionSource) SetTypeNil(b bool)` + + SetTypeNil sets the value for Type to be an explicit nil + +### UnsetType +`func (o *FunctionSource) UnsetType()` + +UnsetType ensures that no value is present for Type, not even an explicit nil + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/restclient/docs/RuntimeConfig.md b/restclient/docs/RuntimeConfig.md new file mode 100644 index 00000000..c3fc641e --- /dev/null +++ b/restclient/docs/RuntimeConfig.md @@ -0,0 +1,92 @@ +# RuntimeConfig + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Config** | Pointer to **map[string]interface{}** | | [optional] +**Type** | Pointer to **NullableString** | | [optional] + +## Methods + +### NewRuntimeConfig + +`func NewRuntimeConfig() *RuntimeConfig` + +NewRuntimeConfig instantiates a new RuntimeConfig object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewRuntimeConfigWithDefaults + +`func NewRuntimeConfigWithDefaults() *RuntimeConfig` + +NewRuntimeConfigWithDefaults instantiates a new RuntimeConfig object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetConfig + +`func (o *RuntimeConfig) GetConfig() map[string]interface{}` + +GetConfig returns the Config field if non-nil, zero value otherwise. + +### GetConfigOk + +`func (o *RuntimeConfig) GetConfigOk() (*map[string]interface{}, bool)` + +GetConfigOk returns a tuple with the Config field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetConfig + +`func (o *RuntimeConfig) SetConfig(v map[string]interface{})` + +SetConfig sets Config field to given value. + +### HasConfig + +`func (o *RuntimeConfig) HasConfig() bool` + +HasConfig returns a boolean if a field has been set. + +### GetType + +`func (o *RuntimeConfig) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *RuntimeConfig) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *RuntimeConfig) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *RuntimeConfig) HasType() bool` + +HasType returns a boolean if a field has been set. + +### SetTypeNil + +`func (o *RuntimeConfig) SetTypeNil(b bool)` + + SetTypeNil sets the value for Type to be an explicit nil + +### UnsetType +`func (o *RuntimeConfig) UnsetType()` + +UnsetType ensures that no value is present for Type, not even an explicit nil + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/restclient/docs/TubeConfig.md b/restclient/docs/TubeConfig.md new file mode 100644 index 00000000..2c303c95 --- /dev/null +++ b/restclient/docs/TubeConfig.md @@ -0,0 +1,92 @@ +# TubeConfig + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Config** | Pointer to **map[string]interface{}** | | [optional] +**Type** | Pointer to **NullableString** | | [optional] + +## Methods + +### NewTubeConfig + +`func NewTubeConfig() *TubeConfig` + +NewTubeConfig instantiates a new TubeConfig object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewTubeConfigWithDefaults + +`func NewTubeConfigWithDefaults() *TubeConfig` + +NewTubeConfigWithDefaults instantiates a new TubeConfig object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetConfig + +`func (o *TubeConfig) GetConfig() map[string]interface{}` + +GetConfig returns the Config field if non-nil, zero value otherwise. + +### GetConfigOk + +`func (o *TubeConfig) GetConfigOk() (*map[string]interface{}, bool)` + +GetConfigOk returns a tuple with the Config field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetConfig + +`func (o *TubeConfig) SetConfig(v map[string]interface{})` + +SetConfig sets Config field to given value. + +### HasConfig + +`func (o *TubeConfig) HasConfig() bool` + +HasConfig returns a boolean if a field has been set. + +### GetType + +`func (o *TubeConfig) GetType() string` + +GetType returns the Type field if non-nil, zero value otherwise. + +### GetTypeOk + +`func (o *TubeConfig) GetTypeOk() (*string, bool)` + +GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetType + +`func (o *TubeConfig) SetType(v string)` + +SetType sets Type field to given value. + +### HasType + +`func (o *TubeConfig) HasType() bool` + +HasType returns a boolean if a field has been set. + +### SetTypeNil + +`func (o *TubeConfig) SetTypeNil(b bool)` + + SetTypeNil sets the value for Type to be an explicit nil + +### UnsetType +`func (o *TubeConfig) UnsetType()` + +UnsetType ensures that no value is present for Type, not even an explicit nil + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/restclient/model_function.go b/restclient/model_function.go index 86aa6237..1f35864b 100644 --- a/restclient/model_function.go +++ b/restclient/model_function.go @@ -22,11 +22,13 @@ var _ MappedNullable = &Function{} // Function struct for Function type Function struct { Name *string `json:"name,omitempty"` - Archive string `json:"archive"` + Runtime *FunctionRuntime `json:"runtime,omitempty"` + Source FunctionSource `json:"source"` + Sink FunctionSource `json:"sink"` Inputs []string `json:"inputs"` Output string `json:"output"` - Replicas *int32 `json:"replicas,omitempty"` Config *map[string]string `json:"config,omitempty"` + Replicas int32 `json:"replicas"` } type _Function Function @@ -35,11 +37,13 @@ type _Function Function // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewFunction(archive string, inputs []string, output string) *Function { +func NewFunction(source FunctionSource, sink FunctionSource, inputs []string, output string, replicas int32) *Function { this := Function{} - this.Archive = archive + this.Source = source + this.Sink = sink this.Inputs = inputs this.Output = output + this.Replicas = replicas return &this } @@ -83,28 +87,84 @@ func (o *Function) SetName(v string) { o.Name = &v } -// GetArchive returns the Archive field value -func (o *Function) GetArchive() string { +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *Function) GetRuntime() FunctionRuntime { + if o == nil || IsNil(o.Runtime) { + var ret FunctionRuntime + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Function) GetRuntimeOk() (*FunctionRuntime, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *Function) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given FunctionRuntime and assigns it to the Runtime field. +func (o *Function) SetRuntime(v FunctionRuntime) { + o.Runtime = &v +} + +// GetSource returns the Source field value +func (o *Function) GetSource() FunctionSource { if o == nil { - var ret string + var ret FunctionSource return ret } - return o.Archive + return o.Source } -// GetArchiveOk returns a tuple with the Archive field value +// GetSourceOk returns a tuple with the Source field value // and a boolean to check if the value has been set. -func (o *Function) GetArchiveOk() (*string, bool) { +func (o *Function) GetSourceOk() (*FunctionSource, bool) { if o == nil { return nil, false } - return &o.Archive, true + return &o.Source, true } -// SetArchive sets field value -func (o *Function) SetArchive(v string) { - o.Archive = v +// SetSource sets field value +func (o *Function) SetSource(v FunctionSource) { + o.Source = v +} + +// GetSink returns the Sink field value +func (o *Function) GetSink() FunctionSource { + if o == nil { + var ret FunctionSource + return ret + } + + return o.Sink +} + +// GetSinkOk returns a tuple with the Sink field value +// and a boolean to check if the value has been set. +func (o *Function) GetSinkOk() (*FunctionSource, bool) { + if o == nil { + return nil, false + } + return &o.Sink, true +} + +// SetSink sets field value +func (o *Function) SetSink(v FunctionSource) { + o.Sink = v } // GetInputs returns the Inputs field value @@ -155,38 +215,6 @@ func (o *Function) SetOutput(v string) { o.Output = v } -// GetReplicas returns the Replicas field value if set, zero value otherwise. -func (o *Function) GetReplicas() int32 { - if o == nil || IsNil(o.Replicas) { - var ret int32 - return ret - } - return *o.Replicas -} - -// GetReplicasOk returns a tuple with the Replicas field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *Function) GetReplicasOk() (*int32, bool) { - if o == nil || IsNil(o.Replicas) { - return nil, false - } - return o.Replicas, true -} - -// HasReplicas returns a boolean if a field has been set. -func (o *Function) HasReplicas() bool { - if o != nil && !IsNil(o.Replicas) { - return true - } - - return false -} - -// SetReplicas gets a reference to the given int32 and assigns it to the Replicas field. -func (o *Function) SetReplicas(v int32) { - o.Replicas = &v -} - // GetConfig returns the Config field value if set, zero value otherwise. func (o *Function) GetConfig() map[string]string { if o == nil || IsNil(o.Config) { @@ -219,6 +247,30 @@ func (o *Function) SetConfig(v map[string]string) { o.Config = &v } +// GetReplicas returns the Replicas field value +func (o *Function) GetReplicas() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Replicas +} + +// GetReplicasOk returns a tuple with the Replicas field value +// and a boolean to check if the value has been set. +func (o *Function) GetReplicasOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Replicas, true +} + +// SetReplicas sets field value +func (o *Function) SetReplicas(v int32) { + o.Replicas = v +} + func (o Function) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -232,15 +284,17 @@ func (o Function) ToMap() (map[string]interface{}, error) { if !IsNil(o.Name) { toSerialize["name"] = o.Name } - toSerialize["archive"] = o.Archive + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } + toSerialize["source"] = o.Source + toSerialize["sink"] = o.Sink toSerialize["inputs"] = o.Inputs toSerialize["output"] = o.Output - if !IsNil(o.Replicas) { - toSerialize["replicas"] = o.Replicas - } if !IsNil(o.Config) { toSerialize["config"] = o.Config } + toSerialize["replicas"] = o.Replicas return toSerialize, nil } @@ -249,9 +303,11 @@ func (o *Function) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ - "archive", + "source", + "sink", "inputs", "output", + "replicas", } allProperties := make(map[string]interface{}) diff --git a/restclient/model_function_runtime.go b/restclient/model_function_runtime.go new file mode 100644 index 00000000..a06a888b --- /dev/null +++ b/restclient/model_function_runtime.go @@ -0,0 +1,171 @@ +/* +Function Stream API + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +API version: 0.1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package restclient + +import ( + "encoding/json" +) + +// checks if the FunctionRuntime type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &FunctionRuntime{} + +// FunctionRuntime struct for FunctionRuntime +type FunctionRuntime struct { + Config map[string]interface{} `json:"config,omitempty"` + Type NullableString `json:"type,omitempty"` +} + +// NewFunctionRuntime instantiates a new FunctionRuntime object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewFunctionRuntime() *FunctionRuntime { + this := FunctionRuntime{} + return &this +} + +// NewFunctionRuntimeWithDefaults instantiates a new FunctionRuntime object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewFunctionRuntimeWithDefaults() *FunctionRuntime { + this := FunctionRuntime{} + return &this +} + +// GetConfig returns the Config field value if set, zero value otherwise. +func (o *FunctionRuntime) GetConfig() map[string]interface{} { + if o == nil || IsNil(o.Config) { + var ret map[string]interface{} + return ret + } + return o.Config +} + +// GetConfigOk returns a tuple with the Config field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *FunctionRuntime) GetConfigOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.Config) { + return map[string]interface{}{}, false + } + return o.Config, true +} + +// HasConfig returns a boolean if a field has been set. +func (o *FunctionRuntime) HasConfig() bool { + if o != nil && !IsNil(o.Config) { + return true + } + + return false +} + +// SetConfig gets a reference to the given map[string]interface{} and assigns it to the Config field. +func (o *FunctionRuntime) SetConfig(v map[string]interface{}) { + o.Config = v +} + +// GetType returns the Type field value if set, zero value otherwise (both if not set or set to explicit null). +func (o *FunctionRuntime) GetType() string { + if o == nil || IsNil(o.Type.Get()) { + var ret string + return ret + } + return *o.Type.Get() +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +// NOTE: If the value is an explicit nil, `nil, true` will be returned +func (o *FunctionRuntime) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return o.Type.Get(), o.Type.IsSet() +} + +// HasType returns a boolean if a field has been set. +func (o *FunctionRuntime) HasType() bool { + if o != nil && o.Type.IsSet() { + return true + } + + return false +} + +// SetType gets a reference to the given NullableString and assigns it to the Type field. +func (o *FunctionRuntime) SetType(v string) { + o.Type.Set(&v) +} + +// SetTypeNil sets the value for Type to be an explicit nil +func (o *FunctionRuntime) SetTypeNil() { + o.Type.Set(nil) +} + +// UnsetType ensures that no value is present for Type, not even an explicit nil +func (o *FunctionRuntime) UnsetType() { + o.Type.Unset() +} + +func (o FunctionRuntime) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o FunctionRuntime) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Config) { + toSerialize["config"] = o.Config + } + if o.Type.IsSet() { + toSerialize["type"] = o.Type.Get() + } + return toSerialize, nil +} + +type NullableFunctionRuntime struct { + value *FunctionRuntime + isSet bool +} + +func (v NullableFunctionRuntime) Get() *FunctionRuntime { + return v.value +} + +func (v *NullableFunctionRuntime) Set(val *FunctionRuntime) { + v.value = val + v.isSet = true +} + +func (v NullableFunctionRuntime) IsSet() bool { + return v.isSet +} + +func (v *NullableFunctionRuntime) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFunctionRuntime(val *FunctionRuntime) *NullableFunctionRuntime { + return &NullableFunctionRuntime{value: val, isSet: true} +} + +func (v NullableFunctionRuntime) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFunctionRuntime) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/restclient/model_function_source.go b/restclient/model_function_source.go new file mode 100644 index 00000000..64a809e9 --- /dev/null +++ b/restclient/model_function_source.go @@ -0,0 +1,171 @@ +/* +Function Stream API + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +API version: 0.1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package restclient + +import ( + "encoding/json" +) + +// checks if the FunctionSource type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &FunctionSource{} + +// FunctionSource struct for FunctionSource +type FunctionSource struct { + Config map[string]interface{} `json:"config,omitempty"` + Type NullableString `json:"type,omitempty"` +} + +// NewFunctionSource instantiates a new FunctionSource object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewFunctionSource() *FunctionSource { + this := FunctionSource{} + return &this +} + +// NewFunctionSourceWithDefaults instantiates a new FunctionSource object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewFunctionSourceWithDefaults() *FunctionSource { + this := FunctionSource{} + return &this +} + +// GetConfig returns the Config field value if set, zero value otherwise. +func (o *FunctionSource) GetConfig() map[string]interface{} { + if o == nil || IsNil(o.Config) { + var ret map[string]interface{} + return ret + } + return o.Config +} + +// GetConfigOk returns a tuple with the Config field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *FunctionSource) GetConfigOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.Config) { + return map[string]interface{}{}, false + } + return o.Config, true +} + +// HasConfig returns a boolean if a field has been set. +func (o *FunctionSource) HasConfig() bool { + if o != nil && !IsNil(o.Config) { + return true + } + + return false +} + +// SetConfig gets a reference to the given map[string]interface{} and assigns it to the Config field. +func (o *FunctionSource) SetConfig(v map[string]interface{}) { + o.Config = v +} + +// GetType returns the Type field value if set, zero value otherwise (both if not set or set to explicit null). +func (o *FunctionSource) GetType() string { + if o == nil || IsNil(o.Type.Get()) { + var ret string + return ret + } + return *o.Type.Get() +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +// NOTE: If the value is an explicit nil, `nil, true` will be returned +func (o *FunctionSource) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return o.Type.Get(), o.Type.IsSet() +} + +// HasType returns a boolean if a field has been set. +func (o *FunctionSource) HasType() bool { + if o != nil && o.Type.IsSet() { + return true + } + + return false +} + +// SetType gets a reference to the given NullableString and assigns it to the Type field. +func (o *FunctionSource) SetType(v string) { + o.Type.Set(&v) +} + +// SetTypeNil sets the value for Type to be an explicit nil +func (o *FunctionSource) SetTypeNil() { + o.Type.Set(nil) +} + +// UnsetType ensures that no value is present for Type, not even an explicit nil +func (o *FunctionSource) UnsetType() { + o.Type.Unset() +} + +func (o FunctionSource) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o FunctionSource) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Config) { + toSerialize["config"] = o.Config + } + if o.Type.IsSet() { + toSerialize["type"] = o.Type.Get() + } + return toSerialize, nil +} + +type NullableFunctionSource struct { + value *FunctionSource + isSet bool +} + +func (v NullableFunctionSource) Get() *FunctionSource { + return v.value +} + +func (v *NullableFunctionSource) Set(val *FunctionSource) { + v.value = val + v.isSet = true +} + +func (v NullableFunctionSource) IsSet() bool { + return v.isSet +} + +func (v *NullableFunctionSource) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFunctionSource(val *FunctionSource) *NullableFunctionSource { + return &NullableFunctionSource{value: val, isSet: true} +} + +func (v NullableFunctionSource) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFunctionSource) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/restclient/model_runtime_config.go b/restclient/model_runtime_config.go new file mode 100644 index 00000000..f3896cda --- /dev/null +++ b/restclient/model_runtime_config.go @@ -0,0 +1,171 @@ +/* +Function Stream API + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +API version: 0.1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package restclient + +import ( + "encoding/json" +) + +// checks if the RuntimeConfig type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RuntimeConfig{} + +// RuntimeConfig struct for RuntimeConfig +type RuntimeConfig struct { + Config map[string]interface{} `json:"config,omitempty"` + Type NullableString `json:"type,omitempty"` +} + +// NewRuntimeConfig instantiates a new RuntimeConfig object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRuntimeConfig() *RuntimeConfig { + this := RuntimeConfig{} + return &this +} + +// NewRuntimeConfigWithDefaults instantiates a new RuntimeConfig object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRuntimeConfigWithDefaults() *RuntimeConfig { + this := RuntimeConfig{} + return &this +} + +// GetConfig returns the Config field value if set, zero value otherwise. +func (o *RuntimeConfig) GetConfig() map[string]interface{} { + if o == nil || IsNil(o.Config) { + var ret map[string]interface{} + return ret + } + return o.Config +} + +// GetConfigOk returns a tuple with the Config field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RuntimeConfig) GetConfigOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.Config) { + return map[string]interface{}{}, false + } + return o.Config, true +} + +// HasConfig returns a boolean if a field has been set. +func (o *RuntimeConfig) HasConfig() bool { + if o != nil && !IsNil(o.Config) { + return true + } + + return false +} + +// SetConfig gets a reference to the given map[string]interface{} and assigns it to the Config field. +func (o *RuntimeConfig) SetConfig(v map[string]interface{}) { + o.Config = v +} + +// GetType returns the Type field value if set, zero value otherwise (both if not set or set to explicit null). +func (o *RuntimeConfig) GetType() string { + if o == nil || IsNil(o.Type.Get()) { + var ret string + return ret + } + return *o.Type.Get() +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +// NOTE: If the value is an explicit nil, `nil, true` will be returned +func (o *RuntimeConfig) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return o.Type.Get(), o.Type.IsSet() +} + +// HasType returns a boolean if a field has been set. +func (o *RuntimeConfig) HasType() bool { + if o != nil && o.Type.IsSet() { + return true + } + + return false +} + +// SetType gets a reference to the given NullableString and assigns it to the Type field. +func (o *RuntimeConfig) SetType(v string) { + o.Type.Set(&v) +} + +// SetTypeNil sets the value for Type to be an explicit nil +func (o *RuntimeConfig) SetTypeNil() { + o.Type.Set(nil) +} + +// UnsetType ensures that no value is present for Type, not even an explicit nil +func (o *RuntimeConfig) UnsetType() { + o.Type.Unset() +} + +func (o RuntimeConfig) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RuntimeConfig) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Config) { + toSerialize["config"] = o.Config + } + if o.Type.IsSet() { + toSerialize["type"] = o.Type.Get() + } + return toSerialize, nil +} + +type NullableRuntimeConfig struct { + value *RuntimeConfig + isSet bool +} + +func (v NullableRuntimeConfig) Get() *RuntimeConfig { + return v.value +} + +func (v *NullableRuntimeConfig) Set(val *RuntimeConfig) { + v.value = val + v.isSet = true +} + +func (v NullableRuntimeConfig) IsSet() bool { + return v.isSet +} + +func (v *NullableRuntimeConfig) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRuntimeConfig(val *RuntimeConfig) *NullableRuntimeConfig { + return &NullableRuntimeConfig{value: val, isSet: true} +} + +func (v NullableRuntimeConfig) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRuntimeConfig) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/restclient/model_tube_config.go b/restclient/model_tube_config.go new file mode 100644 index 00000000..8cec8048 --- /dev/null +++ b/restclient/model_tube_config.go @@ -0,0 +1,171 @@ +/* +Function Stream API + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +API version: 0.1.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package restclient + +import ( + "encoding/json" +) + +// checks if the TubeConfig type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TubeConfig{} + +// TubeConfig struct for TubeConfig +type TubeConfig struct { + Config map[string]interface{} `json:"config,omitempty"` + Type NullableString `json:"type,omitempty"` +} + +// NewTubeConfig instantiates a new TubeConfig object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewTubeConfig() *TubeConfig { + this := TubeConfig{} + return &this +} + +// NewTubeConfigWithDefaults instantiates a new TubeConfig object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewTubeConfigWithDefaults() *TubeConfig { + this := TubeConfig{} + return &this +} + +// GetConfig returns the Config field value if set, zero value otherwise. +func (o *TubeConfig) GetConfig() map[string]interface{} { + if o == nil || IsNil(o.Config) { + var ret map[string]interface{} + return ret + } + return o.Config +} + +// GetConfigOk returns a tuple with the Config field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TubeConfig) GetConfigOk() (map[string]interface{}, bool) { + if o == nil || IsNil(o.Config) { + return map[string]interface{}{}, false + } + return o.Config, true +} + +// HasConfig returns a boolean if a field has been set. +func (o *TubeConfig) HasConfig() bool { + if o != nil && !IsNil(o.Config) { + return true + } + + return false +} + +// SetConfig gets a reference to the given map[string]interface{} and assigns it to the Config field. +func (o *TubeConfig) SetConfig(v map[string]interface{}) { + o.Config = v +} + +// GetType returns the Type field value if set, zero value otherwise (both if not set or set to explicit null). +func (o *TubeConfig) GetType() string { + if o == nil || IsNil(o.Type.Get()) { + var ret string + return ret + } + return *o.Type.Get() +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +// NOTE: If the value is an explicit nil, `nil, true` will be returned +func (o *TubeConfig) GetTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return o.Type.Get(), o.Type.IsSet() +} + +// HasType returns a boolean if a field has been set. +func (o *TubeConfig) HasType() bool { + if o != nil && o.Type.IsSet() { + return true + } + + return false +} + +// SetType gets a reference to the given NullableString and assigns it to the Type field. +func (o *TubeConfig) SetType(v string) { + o.Type.Set(&v) +} + +// SetTypeNil sets the value for Type to be an explicit nil +func (o *TubeConfig) SetTypeNil() { + o.Type.Set(nil) +} + +// UnsetType ensures that no value is present for Type, not even an explicit nil +func (o *TubeConfig) UnsetType() { + o.Type.Unset() +} + +func (o TubeConfig) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o TubeConfig) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Config) { + toSerialize["config"] = o.Config + } + if o.Type.IsSet() { + toSerialize["type"] = o.Type.Get() + } + return toSerialize, nil +} + +type NullableTubeConfig struct { + value *TubeConfig + isSet bool +} + +func (v NullableTubeConfig) Get() *TubeConfig { + return v.value +} + +func (v *NullableTubeConfig) Set(val *TubeConfig) { + v.value = val + v.isSet = true +} + +func (v NullableTubeConfig) IsSet() bool { + return v.isSet +} + +func (v *NullableTubeConfig) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTubeConfig(val *TubeConfig) *NullableTubeConfig { + return &NullableTubeConfig{value: val, isSet: true} +} + +func (v NullableTubeConfig) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableTubeConfig) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/server/server.go b/server/server.go index 51f2535f..e4faaba3 100644 --- a/server/server.go +++ b/server/server.go @@ -153,7 +153,7 @@ func (s *Server) startRESTHandlers() error { } function.Name = &functionName - f, err := constructFunction(&function) + f, err := ConstructFunction(&function) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return @@ -287,24 +287,21 @@ func (s *Server) Close() error { return nil } -func constructFunction(function *restclient.Function) (*model.Function, error) { +func ConstructFunction(function *restclient.Function) (*model.Function, error) { if function.Name == nil { return nil, errors.New("function name is required") } f := &model.Function{ - Name: *function.Name, - Runtime: &model.RuntimeConfig{ - Config: map[string]interface{}{ - common.RuntimeArchiveConfigKey: function.Archive, - }, - }, - Inputs: function.Inputs, - Output: function.Output, + Name: *function.Name, + Inputs: function.Inputs, + Output: function.Output, + Replicas: function.Replicas, } - if function.Replicas != nil { - f.Replicas = *function.Replicas - } else { - f.Replicas = 1 + if function.Runtime != nil { + f.Runtime = &model.RuntimeConfig{ + Type: function.Runtime.Type.Get(), + Config: function.Runtime.Config, + } } if function.Config != nil { f.Config = *function.Config diff --git a/tests/integration_test.go b/tests/integration_test.go index 1639419b..4332782d 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -20,7 +20,10 @@ import ( "context" "encoding/json" "github.com/apache/pulsar-client-go/pulsar" + "github.com/functionstream/functionstream/common" "github.com/functionstream/functionstream/restclient" + "io" + "log/slog" "math/rand" "strconv" "testing" @@ -39,9 +42,14 @@ func TestBasicFunction(t *testing.T) { name := "func-" + strconv.Itoa(rand.Int()) f := restclient.Function{ - Archive: "./bin/example_basic.wasm", - Inputs: []string{"test-input-" + strconv.Itoa(rand.Int())}, - Output: "test-output-" + strconv.Itoa(rand.Int()), + Runtime: &restclient.FunctionRuntime{ + Config: map[string]interface{}{ + common.RuntimeArchiveConfigKey: "./bin/example_basic.wasm", + }, + }, + Inputs: []string{"test-input-" + strconv.Itoa(rand.Int())}, + Output: "test-output-" + strconv.Itoa(rand.Int()), + Replicas: 1, } producer, err := client.CreateProducer(pulsar.ProducerOptions{ @@ -61,10 +69,18 @@ func TestBasicFunction(t *testing.T) { res, err := cli.DefaultAPI.ApiV1FunctionFunctionNamePost(context.Background(), name).Function(f).Execute() if err != nil { - t.Fatalf(err.Error()) + body, err := io.ReadAll(res.Body) + if err != nil { + t.Fatalf(err.Error()) + return + } + slog.Error(string(body)) + t.Fatal("failed to create function") + return } if res.StatusCode != 200 { t.Fatalf("expected 200, got %d", res.StatusCode) + return } for i := 0; i < 10; i++ {