diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/demo/configuration/common/client.go b/demo/configuration/common/client.go index 7c3db10b86..b27934adf1 100644 --- a/demo/configuration/common/client.go +++ b/demo/configuration/common/client.go @@ -27,7 +27,8 @@ import ( "google.golang.org/grpc" - client "mosn.io/layotto/sdk/go-sdk/client" + client "github.com/layotto/go-sdk/client" + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" ) diff --git a/demo/go.mod b/demo/go.mod index fb03216079..a5a99c8bea 100644 --- a/demo/go.mod +++ b/demo/go.mod @@ -23,12 +23,11 @@ require ( google.golang.org/protobuf v1.27.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - mosn.io/layotto/sdk/go-sdk v0.0.0-20211020084508-6f5ee3cfeba0 - mosn.io/layotto/spec v0.0.0-20220413092851-55c58dbb1a23 + github.com/layotto/go-sdk v0.0.0-20241113124402-e55ee5816d2f // indirect + mosn.io/layotto/spec v0.0.0-20240927030843-b4fed4d06be4 ) replace ( - mosn.io/layotto/sdk/go-sdk => ../sdk/go-sdk mosn.io/layotto/spec => ../spec ) diff --git a/demo/go.sum b/demo/go.sum index 5b450d6414..84a77d3fb5 100644 --- a/demo/go.sum +++ b/demo/go.sum @@ -73,6 +73,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/layotto/go-sdk v0.0.0-20241113124402-e55ee5816d2f h1:xm1tsLV09M6if6AzHIb7PVMpGwNB9iEDwujcSNvxMtY= +github.com/layotto/go-sdk v0.0.0-20241113124402-e55ee5816d2f/go.mod h1:wsC0WVxh+E/n7WpsBL7KnHCfwWjcWLee9j73M4vtQ2c= github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/minio-go/v7 v7.0.15 h1:r9/NhjJ+nXYrIYvbObhvc1wPj3YH1iDpJzz61uRKLyY= @@ -231,3 +233,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +mosn.io/layotto/sdk/go-sdk v0.0.0-20211020084508-6f5ee3cfeba0 h1:7VrXO1rhre6jEi/AefiSAJKcBN2S1A4xyftGwQtplxo= +mosn.io/layotto/sdk/go-sdk v0.0.0-20211020084508-6f5ee3cfeba0/go.mod h1:8mz11AqaMK42eseRmD4LvCXM3THklAuuKklkQ3FYPpw= +mosn.io/layotto/sdk/go-sdk v0.0.0-20240927030843-b4fed4d06be4/go.mod h1:vfiOK6P29QD8Ti5NTeTfWamLN3EzrcCQD1tpldX4K3Y= diff --git a/demo/hello/common/client.go b/demo/hello/common/client.go index c661b5ffa1..665be75a61 100644 --- a/demo/hello/common/client.go +++ b/demo/hello/common/client.go @@ -19,7 +19,7 @@ import ( "fmt" "log" - "mosn.io/layotto/sdk/go-sdk/client" + "github.com/layotto/go-sdk/client" ) var storeName string diff --git a/demo/lock/common/client.go b/demo/lock/common/client.go index 914e177353..8cfa07bd65 100644 --- a/demo/lock/common/client.go +++ b/demo/lock/common/client.go @@ -8,7 +8,8 @@ import ( "github.com/google/uuid" - client "mosn.io/layotto/sdk/go-sdk/client" + client "github.com/layotto/go-sdk/client" + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" ) diff --git a/demo/pubsub/client/publish_client.go b/demo/pubsub/client/publish_client.go index 7cf7ba8866..b4116eb1b4 100644 --- a/demo/pubsub/client/publish_client.go +++ b/demo/pubsub/client/publish_client.go @@ -21,7 +21,7 @@ import ( "flag" "fmt" - client "mosn.io/layotto/sdk/go-sdk/client" + client "github.com/layotto/go-sdk/client" ) var storeName string diff --git a/demo/secret/common/client.go b/demo/secret/common/client.go index a96832a951..8181fac7e1 100644 --- a/demo/secret/common/client.go +++ b/demo/secret/common/client.go @@ -5,7 +5,8 @@ import ( "flag" "fmt" - "mosn.io/layotto/sdk/go-sdk/client" + "github.com/layotto/go-sdk/client" + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" ) diff --git a/demo/sequencer/common/client.go b/demo/sequencer/common/client.go index 1ef3c04c09..36ad367f00 100644 --- a/demo/sequencer/common/client.go +++ b/demo/sequencer/common/client.go @@ -21,7 +21,8 @@ import ( "flag" "fmt" - client "mosn.io/layotto/sdk/go-sdk/client" + client "github.com/layotto/go-sdk/client" + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" ) diff --git a/demo/state/common/client.go b/demo/state/common/client.go index 5eee627eae..30b6e48624 100755 --- a/demo/state/common/client.go +++ b/demo/state/common/client.go @@ -21,7 +21,7 @@ import ( "flag" "fmt" - client "mosn.io/layotto/sdk/go-sdk/client" + client "github.com/layotto/go-sdk/client" ) const ( diff --git a/demo/state/k8s/client.go b/demo/state/k8s/client.go index e5190ca536..88ae84ec16 100644 --- a/demo/state/k8s/client.go +++ b/demo/state/k8s/client.go @@ -25,7 +25,7 @@ import ( "github.com/avast/retry-go" - client "mosn.io/layotto/sdk/go-sdk/client" + client "github.com/layotto/go-sdk/client" ) const ( diff --git a/demo/state/k8s/go.mod b/demo/state/k8s/go.mod index 5d38e221ea..2a266e15cc 100644 --- a/demo/state/k8s/go.mod +++ b/demo/state/k8s/go.mod @@ -2,13 +2,11 @@ module client go 1.18 -require ( - github.com/avast/retry-go v3.0.0+incompatible - mosn.io/layotto/sdk/go-sdk v0.0.0-20230920030758-dbf443e27376 -) +require github.com/avast/retry-go v3.0.0+incompatible require ( github.com/golang/protobuf v1.5.0 // indirect + github.com/layotto/go-sdk v0.0.0-20241113124402-e55ee5816d2f github.com/pkg/errors v0.9.1 // indirect golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a // indirect @@ -16,5 +14,5 @@ require ( google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect google.golang.org/grpc v1.37.0 // indirect google.golang.org/protobuf v1.26.0-rc.1 // indirect - mosn.io/layotto/spec v0.0.0-20230920030758-dbf443e27376 // indirect + mosn.io/layotto/spec v0.0.0-20240927030843-b4fed4d06be4 // indirect ) diff --git a/demo/state/k8s/go.sum b/demo/state/k8s/go.sum index 4952fd1311..45760d5f17 100644 --- a/demo/state/k8s/go.sum +++ b/demo/state/k8s/go.sum @@ -32,6 +32,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/layotto/go-sdk v0.0.0-20241113124402-e55ee5816d2f h1:xm1tsLV09M6if6AzHIb7PVMpGwNB9iEDwujcSNvxMtY= +github.com/layotto/go-sdk v0.0.0-20241113124402-e55ee5816d2f/go.mod h1:wsC0WVxh+E/n7WpsBL7KnHCfwWjcWLee9j73M4vtQ2c= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -95,8 +97,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -mosn.io/layotto/sdk/go-sdk v0.0.0-20230920030758-dbf443e27376 h1:PXv6Ru2HC4Mqlj+KY5R1xqHPk8nwgJwiMxuHg1jMhZg= -mosn.io/layotto/sdk/go-sdk v0.0.0-20230920030758-dbf443e27376/go.mod h1:vfiOK6P29QD8Ti5NTeTfWamLN3EzrcCQD1tpldX4K3Y= +mosn.io/layotto/sdk/go-sdk v0.0.0-20240927030843-b4fed4d06be4/go.mod h1:vfiOK6P29QD8Ti5NTeTfWamLN3EzrcCQD1tpldX4K3Y= mosn.io/layotto/spec v0.0.0-20210707123820-584778d048d3/go.mod h1:ex31WL9Vx1PadpZmN4CZpw/57xzBeKIwqMI5fYXi7RY= -mosn.io/layotto/spec v0.0.0-20230920030758-dbf443e27376 h1:Hku8GOHjTzjjqnG+5ka6ZnDoKXXN+smWpyi1iU87x+U= -mosn.io/layotto/spec v0.0.0-20230920030758-dbf443e27376/go.mod h1:3ri6wotzCp2LTjrCZ3Pfre+u1tw2b4Sc+qZERM7apwU= +mosn.io/layotto/spec v0.0.0-20240927030843-b4fed4d06be4 h1:4ThNPnPfpPzk32hUIm/mRm4+Ch4MmFNFbnFhbuZ4Qms= +mosn.io/layotto/spec v0.0.0-20240927030843-b4fed4d06be4/go.mod h1:3ri6wotzCp2LTjrCZ3Pfre+u1tw2b4Sc+qZERM7apwU= diff --git a/etc/script/report.sh b/etc/script/report.sh index e779d51e9a..cfec269cd0 100644 --- a/etc/script/report.sh +++ b/etc/script/report.sh @@ -11,12 +11,4 @@ echo "" > cover.out echo "test components" go test -count=1 -failfast -timeout 120s ./... -coverprofile cover.out -covermode=atomic cat cover.out >> ../cover.out -cd .. - - -cd sdk/go-sdk -echo "" > cover.out -echo "test go-sdk" -go test -count=1 -failfast -timeout 120s $(go list ./... | grep -v runtime) -coverprofile cover.out -covermode=atomic -cat cover.out >> ../../cover.out cd ../.. diff --git a/make/common.mk b/make/common.mk index 365328cf22..b32037256c 100644 --- a/make/common.mk +++ b/make/common.mk @@ -57,9 +57,6 @@ endif ifeq ($(origin TEST_WASM_DIR),undefined) TEST_WASM_DIR := $(ROOT_DIR)/test endif -ifeq ($(origin TEST_RUNTIME_DIR),undefined) -TEST_RUNTIME_DIR := $(ROOT_DIR)/sdk/go-sdk/test -endif ifeq ($(origin DEMO_DIR),undefined) DEMO_DIR := $(ROOT_DIR)/demo endif diff --git a/make/golang.mk b/make/golang.mk index f9c2f65ea3..4896962971 100644 --- a/make/golang.mk +++ b/make/golang.mk @@ -140,8 +140,6 @@ go.lint: go.lint.verify go.unittest: @echo "===========> Run unit test in diagnostics" > $(UNITTEST_OUT) && \ $(GO) test -count=1 -timeout=10m -short -v `go list ./diagnostics/...` >> $(UNITTEST_OUT) && \ - echo "===========> Run unit test in sdk/go-sdk" >> $(UNITTEST_OUT) && \ - cd sdk/go-sdk && $(GO) test -count=1 -timeout=10m -short -v `go list ./... | grep -v runtime` >> $(UNITTEST_OUT) && \ echo "===========> Run unit test in components" >> $(UNITTEST_OUT) && \ cd ../../components && $(GO) test -count=1 -timeout=10m -short -v `go list ./...` >> $(UNITTEST_OUT) && \ echo "===========> Run unit test in pkg" >> $(UNITTEST_OUT) && \ @@ -199,5 +197,4 @@ go.format: go.format.verify $(GO) mod tidy cd components && $(GO) mod tidy cd demo && $(GO) mod tidy - cd sdk/go-sdk && $(GO) mod tidy cd spec && $(GO) mod tidy diff --git a/sdk/go-sdk/client/client.go b/sdk/go-sdk/client/client.go deleted file mode 100644 index f9aa7573dd..0000000000 --- a/sdk/go-sdk/client/client.go +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - "log" - "net" - "os" - "sync" - - "github.com/pkg/errors" - "google.golang.org/grpc" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -const ( - runtimePortDefault = "34904" - runtimePortEnvVarName = "runtime_GRPC_PORT" -) - -var ( - logger = log.New(os.Stdout, "", 0) - _ Client = (*GRPCClient)(nil) - defaultClient Client - doOnce sync.Once -) - -type runtimeAPI interface { - SayHello(ctx context.Context, in *SayHelloRequest) (*SayHelloResp, error) - - GetConfiguration(ctx context.Context, in *ConfigurationRequestItem) ([]*ConfigurationItem, error) - - // InvokeMethod invokes service without raw data - InvokeMethod(ctx context.Context, appID, methodName, verb string) (out []byte, err error) - - // InvokeMethodWithContent invokes service with content - InvokeMethodWithContent(ctx context.Context, appID, methodName, verb string, content *DataContent) (out []byte, err error) - - // InvokeMethodWithCustomContent invokes app with custom content (struct + content type). - InvokeMethodWithCustomContent(ctx context.Context, appID, methodName, verb string, contentType string, content interface{}) (out []byte, err error) - - // PublishEvent publishes data onto topic in specific pubsub component. - PublishEvent(ctx context.Context, pubsubName, topicName string, data []byte) error - - // Subscribe subscribes to a pubsub topic and streams messages to the returned Subscription. - // Subscription must be closed after finishing with subscribing. - Subscribe(ctx context.Context, request SubscriptionRequest) (*Subscription, error) - - // SubscribeWithHandler subscribes to a pubsub topic and calls the given handler on topic events. - // The returned cancel function must be called after finishing with subscribing. - SubscribeWithHandler(ctx context.Context, request SubscriptionRequest, handler SubscriptionHandleFunction) (func() error, error) - - // PublishEventfromCustomContent serializes an struct and publishes its contents as data (JSON) onto topic in specific pubsub component. - PublishEventfromCustomContent(ctx context.Context, pubsubName, topicName string, data interface{}) error - - // SaveConfiguration saves configuration into configuration store. - SaveConfiguration(ctx context.Context, in *SaveConfigurationRequest) error - - // DeleteConfiguration deletes configuration from configuration store. - DeleteConfiguration(ctx context.Context, in *ConfigurationRequestItem) error - - // SubscribeConfiguration gets configuration from configuration store and subscribe the updates. - SubscribeConfiguration(ctx context.Context, in *ConfigurationRequestItem) WatchChan - - // SaveState saves the raw data into store using default state options. - SaveState(ctx context.Context, storeName, key string, data []byte, so ...StateOption) error - - // SaveBulkState saves multiple state item to store with specified options. - SaveBulkState(ctx context.Context, storeName string, items ...*SetStateItem) error - - // GetState retrieves state from specific store using default consistency option. - GetState(ctx context.Context, storeName, key string) (item *StateItem, err error) - - // GetStateWithConsistency retrieves state from specific store using provided state consistency. - GetStateWithConsistency(ctx context.Context, storeName, key string, meta map[string]string, sc StateConsistency) (item *StateItem, err error) - - // GetBulkState retrieves state for multiple keys from specific store. - GetBulkState(ctx context.Context, storeName string, keys []string, meta map[string]string, parallelism int32) ([]*BulkStateItem, error) - - // DeleteState deletes content from store using default state options. - DeleteState(ctx context.Context, storeName, key string) error - - // DeleteStateWithETag deletes content from store using provided state options and etag. - DeleteStateWithETag(ctx context.Context, storeName, key string, etag *ETag, meta map[string]string, opts *StateOptions) error - - // ExecuteStateTransaction provides way to execute multiple operations on a specified store. - ExecuteStateTransaction(ctx context.Context, storeName string, meta map[string]string, ops []*StateOperation) error - - // DeleteBulkState deletes content for multiple keys from store. - DeleteBulkState(ctx context.Context, storeName string, keys []string) error - - // DeleteBulkState deletes content for multiple keys from store. - DeleteBulkStateItems(ctx context.Context, storeName string, items []*DeleteStateItem) error - - // Distributed Lock API - TryLock(context.Context, *runtimev1pb.TryLockRequest) (*runtimev1pb.TryLockResponse, error) - Unlock(context.Context, *runtimev1pb.UnlockRequest) (*runtimev1pb.UnlockResponse, error) - - // Sequencer API - // Get next unique id with some auto-increment guarantee - GetNextId(ctx context.Context, in *runtimev1pb.GetNextIdRequest) (*runtimev1pb.GetNextIdResponse, error) - - // Secret API - GetSecret(ctx context.Context, in *runtimev1pb.GetSecretRequest, opts ...grpc.CallOption) (*runtimev1pb.GetSecretResponse, error) - GetBulkSecret(ctx context.Context, in *runtimev1pb.GetBulkSecretRequest, opts ...grpc.CallOption) (*runtimev1pb.GetBulkSecretResponse, error) - - // Close cleans up all resources created by the client. - Close() -} - -// NewClient instantiates runtime client using runtime_GRPC_PORT environment variable as port. -// Note, this default factory function creates runtime client only once. All subsequent invocations -// will return the already created instance. To create multiple instances of the runtime client, -// use one of the parameterized factory functions: -// -// NewClientWithPort(port string) (client Client, err error) -// NewClientWithAddress(address string) (client Client, err error) -// NewClientWithConnection(conn *grpc.ClientConn) Client -func NewClient() (client Client, err error) { - port := os.Getenv(runtimePortEnvVarName) - if port == "" { - port = runtimePortDefault - } - var onceErr error - doOnce.Do(func() { - c, err := NewClientWithPort(port) - onceErr = errors.Wrap(err, "error creating default client") - defaultClient = c - }) - - return defaultClient, onceErr -} - -// NewClientWithPort instantiates runtime using specific port. -func NewClientWithPort(port string) (client Client, err error) { - if port == "" { - return nil, errors.New("nil port") - } - return NewClientWithAddress(net.JoinHostPort("127.0.0.1", port)) -} - -// NewClientWithAddress instantiates runtime using specific address (including port). -func NewClientWithAddress(address string) (client Client, err error) { - if address == "" { - return nil, errors.New("nil address") - } - logger.Printf("runtime client initializing for: %s", address) - conn, err := grpc.Dial(address, grpc.WithInsecure()) - if err != nil { - return nil, errors.Wrapf(err, "error creating connection to '%s': %v", address, err) - } - - return NewClientWithConnection(conn), nil -} - -// Close cleans up all resources created by the client. -func (c *GRPCClient) Close() { - if c.connection != nil { - c.connection.Close() - } -} diff --git a/sdk/go-sdk/client/client_generated.go b/sdk/go-sdk/client/client_generated.go deleted file mode 100644 index a663b60c7b..0000000000 --- a/sdk/go-sdk/client/client_generated.go +++ /dev/null @@ -1,95 +0,0 @@ -// Code generated by github.com/layotto/protoc-gen-p6 . - -// Copyright 2021 Layotto 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 client - -import ( - context "context" - - grpc "google.golang.org/grpc" - - cryption "mosn.io/layotto/spec/proto/extension/v1/cryption" - delay_queue "mosn.io/layotto/spec/proto/extension/v1/delay_queue" - email "mosn.io/layotto/spec/proto/extension/v1/email" - phone "mosn.io/layotto/spec/proto/extension/v1/phone" - s3 "mosn.io/layotto/spec/proto/extension/v1/s3" - sms "mosn.io/layotto/spec/proto/extension/v1/sms" - v1 "mosn.io/layotto/spec/proto/runtime/v1" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context - -// Client is the interface for runtime client implementation. -type Client interface { - runtimeAPI - - s3.ObjectStorageServiceClient - - // "mosn.io/layotto/spec/proto/extension/v1/cryption" - cryption.CryptionServiceClient - - // "mosn.io/layotto/spec/proto/extension/v1/delay_queue" - delay_queue.DelayQueueClient - - // "mosn.io/layotto/spec/proto/extension/v1/email" - email.EmailServiceClient - - // "mosn.io/layotto/spec/proto/extension/v1/phone" - phone.PhoneCallServiceClient - - // "mosn.io/layotto/spec/proto/extension/v1/sms" - sms.SmsServiceClient -} - -// NewClientWithConnection instantiates runtime client using specific connection. -func NewClientWithConnection(conn *grpc.ClientConn) Client { - return &GRPCClient{ - connection: conn, - protoClient: v1.NewRuntimeClient(conn), - ObjectStorageServiceClient: s3.NewObjectStorageServiceClient(conn), - // "mosn.io/layotto/spec/proto/extension/v1/cryption" - CryptionServiceClient: cryption.NewCryptionServiceClient(conn), - - // "mosn.io/layotto/spec/proto/extension/v1/delay_queue" - DelayQueueClient: delay_queue.NewDelayQueueClient(conn), - - // "mosn.io/layotto/spec/proto/extension/v1/email" - EmailServiceClient: email.NewEmailServiceClient(conn), - - // "mosn.io/layotto/spec/proto/extension/v1/phone" - PhoneCallServiceClient: phone.NewPhoneCallServiceClient(conn), - - // "mosn.io/layotto/spec/proto/extension/v1/sms" - SmsServiceClient: sms.NewSmsServiceClient(conn), - } -} - -// GRPCClient is the gRPC implementation of runtime client. -type GRPCClient struct { - connection *grpc.ClientConn - protoClient v1.RuntimeClient - s3.ObjectStorageServiceClient - // "mosn.io/layotto/spec/proto/extension/v1/cryption" - cryption.CryptionServiceClient - // "mosn.io/layotto/spec/proto/extension/v1/delay_queue" - delay_queue.DelayQueueClient - // "mosn.io/layotto/spec/proto/extension/v1/email" - email.EmailServiceClient - // "mosn.io/layotto/spec/proto/extension/v1/phone" - phone.PhoneCallServiceClient - // "mosn.io/layotto/spec/proto/extension/v1/sms" - sms.SmsServiceClient -} diff --git a/sdk/go-sdk/client/client_test.go b/sdk/go-sdk/client/client_test.go deleted file mode 100644 index 8f91d7449b..0000000000 --- a/sdk/go-sdk/client/client_test.go +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - "fmt" - - "net" - "os" - "testing" - - "github.com/stretchr/testify/assert" - "google.golang.org/grpc" - "google.golang.org/grpc/test/bufconn" - "google.golang.org/protobuf/types/known/anypb" - empty "google.golang.org/protobuf/types/known/emptypb" - - pb "mosn.io/layotto/spec/proto/runtime/v1" - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -const ( - testBufSize = 1024 * 1024 -) - -var ( - testClient Client -) - -func TestMain(m *testing.M) { - ctx := context.Background() - c, f := getTestClient(ctx) - testClient = c - RegisterRecoverLogger(debugIgnoreLogger) - r := m.Run() - f() - os.Exit(r) -} - -func TestNewClient(t *testing.T) { - t.Run("no arg for with port", func(t *testing.T) { - _, err := NewClientWithPort("") - assert.Error(t, err) - }) - - t.Run("no arg for with address", func(t *testing.T) { - _, err := NewClientWithAddress("") - assert.Error(t, err) - }) - - t.Run("new client closed with empty token", func(t *testing.T) { - c, err := NewClient() - assert.NoError(t, err) - defer c.Close() - }) - - t.Run("new client with trace ID", func(t *testing.T) { - c, err := NewClient() - assert.NoError(t, err) - defer c.Close() - }) -} - -func getTestClient(ctx context.Context) (client Client, closer func()) { - s := grpc.NewServer() - runtimev1pb.RegisterRuntimeServer(s, &testRuntimeServer{ - kv: make(map[string]string), - subscribed: make(map[string]bool), - state: make(map[string][]byte), - lock: make(map[string]string), - }) - - l := bufconn.Listen(testBufSize) - go func() { - if err := s.Serve(l); err != nil && err.Error() != "closed" { - logger.Fatalf("test server exited with error: %v", err) - } - }() - - d := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { - return l.Dial() - }) - - c, err := grpc.DialContext(ctx, "", d, grpc.WithInsecure()) - if err != nil { - logger.Fatalf("failed to dial test context: %v", err) - } - - closer = func() { - l.Close() - s.Stop() - } - - client = NewClientWithConnection(c) - return -} - -type testRuntimeServer struct { - runtimev1pb.UnimplementedRuntimeServer - kv map[string]string - subscribed map[string]bool - state map[string][]byte - lock map[string]string -} - -func (t *testRuntimeServer) InvokeService(ctx context.Context, req *runtimev1pb.InvokeServiceRequest) (*runtimev1pb.InvokeResponse, error) { - if req.Message == nil { - return &runtimev1pb.InvokeResponse{ - ContentType: "text/plain", - Data: &anypb.Any{ - Value: []byte("pong"), - }, - }, nil - } - return &runtimev1pb.InvokeResponse{ - ContentType: req.Message.ContentType, - Data: req.Message.Data, - }, nil -} - -func (t *testRuntimeServer) GetState(ctx context.Context, req *runtimev1pb.GetStateRequest) (*runtimev1pb.GetStateResponse, error) { - return &pb.GetStateResponse{ - Data: t.state[req.Key], - Etag: "1", - }, nil -} - -func (t *testRuntimeServer) GetBulkState(ctx context.Context, in *runtimev1pb.GetBulkStateRequest) (*runtimev1pb.GetBulkStateResponse, error) { - items := make([]*runtimev1pb.BulkStateItem, 0) - for _, k := range in.GetKeys() { - if v, found := t.state[k]; found { - item := &pb.BulkStateItem{ - Key: k, - Etag: "1", - Data: v, - } - items = append(items, item) - } - } - return &pb.GetBulkStateResponse{ - Items: items, - }, nil -} - -func (t *testRuntimeServer) SaveState(ctx context.Context, req *runtimev1pb.SaveStateRequest) (*empty.Empty, error) { - if req == nil { - return &empty.Empty{}, nil - } - for _, item := range req.States { - if item == nil { - continue - } - t.state[item.Key] = item.Value - } - return &empty.Empty{}, nil -} - -func (t *testRuntimeServer) DeleteState(ctx context.Context, req *runtimev1pb.DeleteStateRequest) (*empty.Empty, error) { - delete(t.state, req.Key) - return &empty.Empty{}, nil -} - -func (t *testRuntimeServer) DeleteBulkState(ctx context.Context, req *runtimev1pb.DeleteBulkStateRequest) (*empty.Empty, error) { - for _, item := range req.States { - delete(t.state, item.Key) - } - return &empty.Empty{}, nil -} - -func (t *testRuntimeServer) ExecuteStateTransaction(ctx context.Context, in *runtimev1pb.ExecuteStateTransactionRequest) (*empty.Empty, error) { - for _, op := range in.GetOperations() { - item := op.GetRequest() - switch opType := op.GetOperationType(); opType { - case "upsert": - t.state[item.Key] = item.Value - case "delete": - delete(t.state, item.Key) - default: - return &empty.Empty{}, fmt.Errorf("invalid operation type: %s", opType) - } - } - return &empty.Empty{}, nil -} - -func (t *testRuntimeServer) PublishEvent(ctx context.Context, req *runtimev1pb.PublishEventRequest) (*empty.Empty, error) { - return &empty.Empty{}, nil -} - -func (t *testRuntimeServer) GetConfiguration(ctx context.Context, req *runtimev1pb.GetConfigurationRequest) (*runtimev1pb.GetConfigurationResponse, error) { - resp := &runtimev1pb.GetConfigurationResponse{} - for _, v := range req.Keys { - if _, ok := t.kv[v]; ok { - item := &runtimev1pb.ConfigurationItem{Key: v, Content: t.kv[v]} - resp.Items = append(resp.Items, item) - } - } - return resp, nil -} -func (t *testRuntimeServer) SaveConfiguration(ctx context.Context, req *runtimev1pb.SaveConfigurationRequest) (*empty.Empty, error) { - for _, v := range req.Items { - t.kv[v.Key] = v.Content - } - return &empty.Empty{}, nil -} -func (t *testRuntimeServer) DeleteConfiguration(ctx context.Context, req *runtimev1pb.DeleteConfigurationRequest) (*empty.Empty, error) { - for _, v := range req.Keys { - delete(t.kv, v) - } - return &empty.Empty{}, nil -} -func (t *testRuntimeServer) SubscribeConfiguration(srv runtimev1pb.Runtime_SubscribeConfigurationServer) error { - req, err := srv.Recv() - if err != nil { - return err - } - for _, key := range req.Keys { - t.subscribed[key] = true - } - resp := &runtimev1pb.SubscribeConfigurationResponse{} - for key := range t.subscribed { - item := &runtimev1pb.ConfigurationItem{Key: key, Content: "Test"} - resp.Items = append(resp.Items, item) - } - err = srv.Send(resp) - return err -} - -func (*testRuntimeServer) SayHello(ctx context.Context, req *runtimev1pb.SayHelloRequest) (*runtimev1pb.SayHelloResponse, error) { - resp := &runtimev1pb.SayHelloResponse{Hello: "world"} - return resp, nil -} - -func (*testRuntimeServer) GetSecret(ctx context.Context, in *runtimev1pb.GetSecretRequest) (*runtimev1pb.GetSecretResponse, error) { - - secrets := make(map[string]string) - secrets[secretKey] = secretValue - resp := &runtimev1pb.GetSecretResponse{ - Data: secrets, - } - return resp, nil -} -func (*testRuntimeServer) GetBulkSecret(ctx context.Context, in *runtimev1pb.GetBulkSecretRequest) (*runtimev1pb.GetBulkSecretResponse, error) { - - secrets := make(map[string]string) - secrets[secretKey] = secretValue - data := make(map[string]*runtimev1pb.SecretResponse) - data[secretKey] = &runtimev1pb.SecretResponse{ - Secrets: secrets, - } - resp := &runtimev1pb.GetBulkSecretResponse{ - Data: data, - } - return resp, nil -} - -func (t *testRuntimeServer) TryLock(ctx context.Context, in *runtimev1pb.TryLockRequest) (*runtimev1pb.TryLockResponse, error) { - if len(t.lock[in.ResourceId]) == 0 { - t.lock[in.ResourceId] = in.LockOwner - return &runtimev1pb.TryLockResponse{ - Success: true, - }, nil - } - // lock exist - return &runtimev1pb.TryLockResponse{ - Success: false, - }, nil -} - -func (t *testRuntimeServer) Unlock(ctx context.Context, in *runtimev1pb.UnlockRequest) (*runtimev1pb.UnlockResponse, error) { - // LOCK_UNEXIST - if len(t.lock[in.ResourceId]) == 0 { - return &runtimev1pb.UnlockResponse{ - Status: pb.UnlockResponse_LOCK_UNEXIST, - }, nil - } - // SUCCESS - if t.lock[in.ResourceId] == in.LockOwner { - delete(t.lock, in.ResourceId) - return &runtimev1pb.UnlockResponse{ - Status: pb.UnlockResponse_SUCCESS, - }, nil - } - // LOCK_BELONG_TO_OTHERS - return &runtimev1pb.UnlockResponse{ - Status: pb.UnlockResponse_LOCK_BELONG_TO_OTHERS, - }, nil -} diff --git a/sdk/go-sdk/client/configuration.go b/sdk/go-sdk/client/configuration.go deleted file mode 100644 index e0d8b562bd..0000000000 --- a/sdk/go-sdk/client/configuration.go +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -type WatchChan <-chan WatchResponse - -// ConfigurationRequestItem used for GET,DEL,SUB request -type ConfigurationRequestItem struct { - // The name of configuration store. - StoreName string - // The application id which - // Only used for admin, Ignored and reset for normal client - AppId string - // The group of keys. - Group string - // The label for keys. - Label string - // The keys to get. - Keys []string - // The metadata which will be sent to configuration store components. - Metadata map[string]string -} - -type ConfigurationItem struct { - // Required. The key of configuration item - Key string - // The content of configuration item - // Empty if the configuration is not set, including the case that the configuration is changed from value-set to value-not-set. - Content string - // The group of configuration item. - Group string - // The label of configuration item. - Label string - // The tag list of configuration item. - Tags map[string]string - // The metadata which will be passed to configuration store component. - Metadata map[string]string -} - -type SaveConfigurationRequest struct { - // The name of configuration store. - StoreName string - // The application id which - // Only used for admin, ignored and reset for normal client - AppId string - // The list of configuration items to save. - // To delete a exist item, set the key (also label) and let content to be empty - Items []*ConfigurationItem - // The metadata which will be sent to configuration store components. - Metadata map[string]string -} - -type SubConfigurationResp struct { - // The name of configuration store. - StoreName string - // The application id which - // Only used for admin, ignored and reset for normal client - AppId string - // The list of configuration items to save. - // To delete a exist item, set the key (also label) and let content to be empty - Items []*ConfigurationItem -} - -type WatchResponse struct { - Item *SubConfigurationResp - Err error -} - -func (c *GRPCClient) GetConfiguration(ctx context.Context, in *ConfigurationRequestItem) ([]*ConfigurationItem, error) { - req := &runtimev1pb.GetConfigurationRequest{StoreName: in.StoreName, AppId: in.AppId, Group: in.Group, Label: in.Label, Keys: in.Keys, Metadata: in.Metadata} - resp, err := c.protoClient.GetConfiguration(ctx, req) - if err != nil { - return nil, err - } - items := make([]*ConfigurationItem, 0, len(resp.Items)) - for _, v := range resp.Items { - c := &ConfigurationItem{Group: v.Group, Label: v.Label, Key: v.Key, Content: v.Content, Tags: v.Tags, Metadata: v.Metadata} - items = append(items, c) - } - return items, nil -} - -// SaveConfiguration saves configuration into configuration store. -func (c *GRPCClient) SaveConfiguration(ctx context.Context, in *SaveConfigurationRequest) error { - req := &runtimev1pb.SaveConfigurationRequest{StoreName: in.StoreName, AppId: in.AppId, Metadata: in.Metadata} - for _, v := range in.Items { - c := &runtimev1pb.ConfigurationItem{Group: v.Group, Label: v.Label, Key: v.Key, Content: v.Content, Tags: v.Tags, Metadata: v.Metadata} - req.Items = append(req.Items, c) - } - _, err := c.protoClient.SaveConfiguration(ctx, req) - return err -} - -// DeleteConfiguration deletes configuration from configuration store. -func (c *GRPCClient) DeleteConfiguration(ctx context.Context, in *ConfigurationRequestItem) error { - req := &runtimev1pb.DeleteConfigurationRequest{StoreName: in.StoreName, AppId: in.AppId, Group: in.Group, Label: in.Label, Keys: in.Keys, Metadata: in.Metadata} - _, err := c.protoClient.DeleteConfiguration(ctx, req) - return err -} - -// SubscribeConfiguration gets configuration from configuration store and subscribe the updates. -func (c *GRPCClient) SubscribeConfiguration(ctx context.Context, in *ConfigurationRequestItem) WatchChan { - cli, err := c.protoClient.SubscribeConfiguration(ctx) - res := WatchResponse{} - resCh := make(chan WatchResponse, 1) - if err != nil { - res.Err = err - resCh <- res - close(resCh) - return resCh - } - request := &runtimev1pb.SubscribeConfigurationRequest{StoreName: in.StoreName, AppId: in.AppId, Group: in.Group, Label: in.Label, Keys: in.Keys, Metadata: in.Metadata} - err = cli.Send(request) - if err != nil { - res.Err = err - resCh <- res - close(resCh) - return resCh - } - GoWithRecover(func() { - for { - resp, err := cli.Recv() - if err != nil { - res.Err = err - resCh <- res - close(resCh) - return - } - item := &SubConfigurationResp{} - item.StoreName = resp.StoreName - item.AppId = resp.AppId - for _, v := range resp.Items { - c := &ConfigurationItem{} - c.Metadata = v.Metadata - c.Label = v.Label - c.Group = v.Group - c.Key = v.Key - c.Tags = v.Tags - c.Content = v.Content - item.Items = append(item.Items, c) - } - res.Item = item - res.Err = nil - resCh <- res - } - }, nil) - return resCh -} diff --git a/sdk/go-sdk/client/configuration_test.go b/sdk/go-sdk/client/configuration_test.go deleted file mode 100644 index 8f8f9247ab..0000000000 --- a/sdk/go-sdk/client/configuration_test.go +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSaveConfiguration(t *testing.T) { - ctx := context.Background() - item1 := &ConfigurationItem{Key: "hello1", Content: "world1"} - item2 := &ConfigurationItem{Key: "hello2", Content: "world2"} - saveRequest := &SaveConfigurationRequest{StoreName: "etcd", AppId: "sofa"} - saveRequest.Items = append(saveRequest.Items, item1) - saveRequest.Items = append(saveRequest.Items, item2) - t.Run("save configuration", func(t *testing.T) { - err := testClient.SaveConfiguration(ctx, saveRequest) - assert.Nil(t, err) - }) -} -func TestGetConfiguration(t *testing.T) { - getRequest := &ConfigurationRequestItem{StoreName: "etcd", AppId: "sofa", Keys: []string{"hello1", "hello2"}} - t.Run("get configuration", func(t *testing.T) { - resp, err := testClient.GetConfiguration(context.Background(), getRequest) - assert.Nil(t, err) - assert.Equal(t, resp[0].Key, "hello1") - assert.Equal(t, resp[0].Content, "world1") - assert.Equal(t, resp[1].Key, "hello2") - assert.Equal(t, resp[1].Content, "world2") - }) -} - -func TestDeleteConfiguration(t *testing.T) { - ctx := context.Background() - deleteRequest := &ConfigurationRequestItem{StoreName: "etcd", AppId: "sofa", Keys: []string{"hello1", "hello2"}} - t.Run("delete configuration", func(t *testing.T) { - err := testClient.DeleteConfiguration(ctx, deleteRequest) - assert.Nil(t, err) - }) - - getRequest := &ConfigurationRequestItem{StoreName: "etcd", AppId: "sofa", Keys: []string{"hello1", "hello2"}} - t.Run("get configuration", func(t *testing.T) { - resp, err := testClient.GetConfiguration(context.Background(), getRequest) - assert.Nil(t, err) - assert.Equal(t, 0, len(resp)) - }) -} - -func TestSubscribeConfiguration(t *testing.T) { - item := &ConfigurationRequestItem{StoreName: "etcd", AppId: "sofa", Keys: []string{"hello1"}} - ch := testClient.SubscribeConfiguration(context.Background(), item) - for wc := range ch { - assert.Equal(t, wc.Item.Items[0].Key, "hello1") - assert.Equal(t, wc.Item.Items[0].Content, "Test") - } -} diff --git a/sdk/go-sdk/client/goroutine.go b/sdk/go-sdk/client/goroutine.go deleted file mode 100644 index 9ac02c8b4b..0000000000 --- a/sdk/go-sdk/client/goroutine.go +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -// Tool for `Recover go func()`, copied from `mosn.io/pkg/utils/goroutine.go` - -import ( - "fmt" - "io" - "os" - "runtime/debug" -) - -var recoverLogger = defaultRecoverLogger - -// RegisterRecoverLogger replace the log handler when go with recover catch a panic -// notice the replaced handler should be simple. -// if the handler panic, the recover handler will be failed. -func RegisterRecoverLogger(f func(w io.Writer, r interface{})) { - recoverLogger = f -} - -func defaultRecoverLogger(w io.Writer, r interface{}) { - fmt.Fprintf(w, "goroutine panic: %v\n%s\n", r, string(debug.Stack())) -} - -// GoWithRecover wraps a `go func()` with recover() -func GoWithRecover(handler func(), recoverHandler func(r interface{})) { - go func() { - defer func() { - if r := recover(); r != nil { - recoverLogger(os.Stderr, r) - if recoverHandler != nil { - go func() { - defer func() { - if p := recover(); p != nil { - recoverLogger(os.Stderr, p) - } - }() - recoverHandler(r) - }() - } - } - }() - handler() - }() -} diff --git a/sdk/go-sdk/client/goroutine_test.go b/sdk/go-sdk/client/goroutine_test.go deleted file mode 100644 index c08df9fa88..0000000000 --- a/sdk/go-sdk/client/goroutine_test.go +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -// Copied from `mosn.io/pkg/utils/goroutine_test.go`. - -import ( - "fmt" - "io" - "testing" - "time" -) - -func debugIgnoreLogger(w io.Writer, r interface{}) { -} - -func TestGoWithRecover(t *testing.T) { - panicStr := "test panic" - panicHandler := func() { - panic(panicStr) - } - output := "" - recoverHandler := func(r interface{}) { - output = fmt.Sprintf("%v", r) - } - GoWithRecover(panicHandler, recoverHandler) - time.Sleep(time.Second) // wait panic goroutine - if output != panicStr { - t.Errorf("expected catch panic output, but got: %s", output) - } -} - -// recover handler panic, should not panic -func TestRecoverPanic(t *testing.T) { - handler := func() { - panic("1") - } - recoverHandler := func(r interface{}) { - panic("2") - } - GoWithRecover(handler, recoverHandler) -} - -// Example for how to recover with recover -type _run struct { - count int - noPanic bool -} - -func (r *_run) work() { - GoWithRecover(r.exec, func(p interface{}) { - r.work() - }) -} - -func (r *_run) exec() { - r.count++ - if r.count <= 2 { - panic("panic") - } - r.noPanic = true -} - -func TestGoWithRecoverAgain(t *testing.T) { - r := &_run{} - r.work() - time.Sleep(time.Second) - if !(r.noPanic && r.count == 3) { - t.Errorf("panic handler is not restart expectedly, noPanic: %v, count: %d", r.noPanic, r.count) - } -} diff --git a/sdk/go-sdk/client/hello.go b/sdk/go-sdk/client/hello.go deleted file mode 100644 index 0cc59779e8..0000000000 --- a/sdk/go-sdk/client/hello.go +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -type SayHelloRequest struct { - ServiceName string -} - -type SayHelloResp struct { - Hello string -} - -func (c *GRPCClient) SayHello(ctx context.Context, in *SayHelloRequest) (*SayHelloResp, error) { - req := &runtimev1pb.SayHelloRequest{ - ServiceName: in.ServiceName, - } - resp, err := c.protoClient.SayHello(ctx, req) - if err != nil { - return nil, err - } - return &SayHelloResp{Hello: resp.Hello}, nil -} diff --git a/sdk/go-sdk/client/hello_test.go b/sdk/go-sdk/client/hello_test.go deleted file mode 100644 index 36f902f698..0000000000 --- a/sdk/go-sdk/client/hello_test.go +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSayHello(t *testing.T) { - item := &SayHelloRequest{ - ServiceName: "helloworld", - } - resp, err := testClient.SayHello(context.Background(), item) - assert.Nil(t, err) - assert.Equal(t, resp.Hello, "world") -} diff --git a/sdk/go-sdk/client/invoke.go b/sdk/go-sdk/client/invoke.go deleted file mode 100755 index f5bbee1684..0000000000 --- a/sdk/go-sdk/client/invoke.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - "encoding/json" - "strings" - - anypb "github.com/golang/protobuf/ptypes/any" - "github.com/pkg/errors" - - pb "mosn.io/layotto/spec/proto/runtime/v1" - v1 "mosn.io/layotto/spec/proto/runtime/v1" -) - -// DataContent the service invocation content -type DataContent struct { - // Data is the input data - Data []byte - // ContentType is the type of the data content - ContentType string -} - -func (c *GRPCClient) invokeServiceWithRequest(ctx context.Context, req *pb.InvokeServiceRequest) (out []byte, err error) { - if req == nil { - return nil, errors.New("nil request") - } - - resp, err := c.protoClient.InvokeService(ctx, req) - if err != nil { - return nil, errors.Wrap(err, "error invoking service") - } - - // allow for service to not return any value - if resp != nil && resp.GetData() != nil { - out = resp.GetData().Value - return - } - - out = nil - return -} - -func queryAndVerbToHTTPExtension(query string, verb string) *v1.HTTPExtension { - if v, ok := v1.HTTPExtension_Verb_value[strings.ToUpper(verb)]; ok { - return &v1.HTTPExtension{Verb: v1.HTTPExtension_Verb(v), Querystring: query} - } - return &v1.HTTPExtension{Verb: v1.HTTPExtension_NONE} -} - -func hasRequiredInvokeArgs(appID, methodName, verb string) error { - if appID == "" { - return errors.New("appID") - } - if methodName == "" { - return errors.New("methodName") - } - if verb == "" { - return errors.New("verb") - } - return nil -} - -// InvokeMethod invokes service without raw data ([]byte). -func (c *GRPCClient) InvokeMethod(ctx context.Context, appID, methodName, verb string) (out []byte, err error) { - if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil { - return nil, errors.Wrap(err, "missing required parameter") - } - method, query := extractMethodAndQuery(methodName) - req := &pb.InvokeServiceRequest{ - Id: appID, - Message: &v1.CommonInvokeRequest{ - Method: method, - HttpExtension: queryAndVerbToHTTPExtension(query, verb), - }, - } - return c.invokeServiceWithRequest(ctx, req) -} - -// InvokeMethodWithContent invokes service without content (data + content type). -func (c *GRPCClient) InvokeMethodWithContent(ctx context.Context, appID, methodName, verb string, content *DataContent) (out []byte, err error) { - if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil { - return nil, errors.Wrap(err, "missing required parameter") - } - if content == nil { - return nil, errors.New("content required") - } - method, query := extractMethodAndQuery(methodName) - req := &pb.InvokeServiceRequest{ - Id: appID, - Message: &v1.CommonInvokeRequest{ - Method: method, - Data: &anypb.Any{Value: content.Data}, - ContentType: content.ContentType, - HttpExtension: queryAndVerbToHTTPExtension(query, verb), - }, - } - return c.invokeServiceWithRequest(ctx, req) -} - -// InvokeMethodWithCustomContent invokes service with custom content (struct + content type). -func (c *GRPCClient) InvokeMethodWithCustomContent(ctx context.Context, appID, methodName, verb string, contentType string, content interface{}) (out []byte, err error) { - if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil { - return nil, errors.Wrap(err, "missing required parameter") - } - if contentType == "" { - return nil, errors.New("content type required") - } - if content == nil { - return nil, errors.New("content required") - } - - contentData, err := json.Marshal(content) - if err != nil { - return nil, errors.WithMessage(err, "error serializing input struct") - } - - method, query := extractMethodAndQuery(methodName) - - req := &pb.InvokeServiceRequest{ - Id: appID, - Message: &v1.CommonInvokeRequest{ - Method: method, - Data: &anypb.Any{Value: contentData}, - ContentType: contentType, - HttpExtension: queryAndVerbToHTTPExtension(query, verb), - }, - } - - return c.invokeServiceWithRequest(ctx, req) -} - -func extractMethodAndQuery(name string) (method, query string) { - splitStr := strings.SplitN(name, "?", 2) - method = splitStr[0] - if len(splitStr) == 2 { - query = splitStr[1] - } - return -} diff --git a/sdk/go-sdk/client/invoke_test.go b/sdk/go-sdk/client/invoke_test.go deleted file mode 100755 index 1125777f25..0000000000 --- a/sdk/go-sdk/client/invoke_test.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" - - v1 "mosn.io/layotto/spec/proto/runtime/v1" -) - -type _testStructwithText struct { - Key1, Key2 string -} - -type _testStructwithTextandNumbers struct { - Key1 string - Key2 int -} - -type _testStructwithSlices struct { - Key1 []string - Key2 []int -} - -func TestInvokeMethodWithContent(t *testing.T) { - ctx := context.Background() - data := "ping" - - t.Run("with content", func(t *testing.T) { - content := &DataContent{ - ContentType: "text/plain", - Data: []byte(data), - } - resp, err := testClient.InvokeMethodWithContent(ctx, "test", "fn", "post", content) - assert.Nil(t, err) - assert.NotNil(t, resp) - assert.Equal(t, string(resp), data) - }) - - t.Run("with content, method contains querystring", func(t *testing.T) { - content := &DataContent{ - ContentType: "text/plain", - Data: []byte(data), - } - resp, err := testClient.InvokeMethodWithContent(ctx, "test", "fn?foo=bar&url=http://dapr.io", "get", content) - assert.Nil(t, err) - assert.NotNil(t, resp) - assert.Equal(t, string(resp), data) - }) - - t.Run("without content", func(t *testing.T) { - resp, err := testClient.InvokeMethod(ctx, "test", "fn", "get") - assert.Nil(t, err) - assert.Nil(t, resp) - }) - - t.Run("without service ID", func(t *testing.T) { - _, err := testClient.InvokeMethod(ctx, "", "fn", "get") - assert.NotNil(t, err) - }) - t.Run("without method", func(t *testing.T) { - _, err := testClient.InvokeMethod(ctx, "test", "", "get") - assert.NotNil(t, err) - }) - t.Run("without verb", func(t *testing.T) { - _, err := testClient.InvokeMethod(ctx, "test", "fn", "") - assert.NotNil(t, err) - }) - t.Run("from struct with text", func(t *testing.T) { - testdata := _testCustomContentwithText{ - Key1: "value1", - Key2: "value2", - } - _, err := testClient.InvokeMethodWithCustomContent(ctx, "test", "fn", "post", "text/plain", testdata) - assert.Nil(t, err) - }) - - t.Run("from struct with text and numbers", func(t *testing.T) { - testdata := _testCustomContentwithTextandNumbers{ - Key1: "value1", - Key2: 2500, - } - _, err := testClient.InvokeMethodWithCustomContent(ctx, "test", "fn", "post", "text/plain", testdata) - assert.Nil(t, err) - }) - - t.Run("from struct with slices", func(t *testing.T) { - testdata := _testCustomContentwithSlices{ - Key1: []string{"value1", "value2", "value3"}, - Key2: []int{25, 40, 600}, - } - _, err := testClient.InvokeMethodWithCustomContent(ctx, "test", "fn", "post", "text/plain", testdata) - assert.Nil(t, err) - }) -} - -func TestVerbParsing(t *testing.T) { - t.Run("valid lower case", func(t *testing.T) { - v := queryAndVerbToHTTPExtension("", "post") - assert.NotNil(t, v) - assert.Equal(t, v1.HTTPExtension_POST, v.Verb) - assert.Len(t, v.Querystring, 0) - }) - - t.Run("valid upper case", func(t *testing.T) { - v := queryAndVerbToHTTPExtension("", "GET") - assert.NotNil(t, v) - assert.Equal(t, v1.HTTPExtension_GET, v.Verb) - }) - - t.Run("invalid verb", func(t *testing.T) { - v := queryAndVerbToHTTPExtension("", "BAD") - assert.NotNil(t, v) - assert.Equal(t, v1.HTTPExtension_NONE, v.Verb) - }) - - t.Run("valid query", func(t *testing.T) { - v := queryAndVerbToHTTPExtension("foo=bar&url=http://dapr.io", "post") - assert.NotNil(t, v) - assert.Equal(t, v1.HTTPExtension_POST, v.Verb) - assert.Equal(t, "foo=bar&url=http://dapr.io", v.Querystring) - }) -} - -func TestExtractMethodAndQuery(t *testing.T) { - type args struct { - name string - } - tests := []struct { - name string - args args - wantMethod string - wantQuery string - }{ - { - "pure uri", - args{name: "method"}, - "method", - "", - }, - { - "root route method", - args{name: "/"}, - "/", - "", - }, - { - "uri with one query", - args{name: "method?foo=bar"}, - "method", - "foo=bar", - }, - { - "uri with two query", - args{name: "method?foo=bar&url=http://dapr.io"}, - "method", - "foo=bar&url=http://dapr.io", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotMethod, gotQuery := extractMethodAndQuery(tt.args.name) - if gotMethod != tt.wantMethod { - t.Errorf("extractMethodAndQuery() gotMethod = %v, want %v", gotMethod, tt.wantMethod) - } - if gotQuery != tt.wantQuery { - t.Errorf("extractMethodAndQuery() gotQuery = %v, want %v", gotQuery, tt.wantQuery) - } - }) - } -} diff --git a/sdk/go-sdk/client/lock.go b/sdk/go-sdk/client/lock.go deleted file mode 100644 index 80ef9ee281..0000000000 --- a/sdk/go-sdk/client/lock.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2021 Layotto 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 client - -import ( - "context" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -func (c *GRPCClient) TryLock(ctx context.Context, req *runtimev1pb.TryLockRequest) (*runtimev1pb.TryLockResponse, error) { - return c.protoClient.TryLock(ctx, req) -} - -func (c *GRPCClient) Unlock(ctx context.Context, req *runtimev1pb.UnlockRequest) (*runtimev1pb.UnlockResponse, error) { - return c.protoClient.Unlock(ctx, req) -} diff --git a/sdk/go-sdk/client/lock_test.go b/sdk/go-sdk/client/lock_test.go deleted file mode 100644 index 2258643ec9..0000000000 --- a/sdk/go-sdk/client/lock_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package client - -/* - * Copyright 2021 Layotto 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. - */ - -import ( - "testing" - - "context" - - "github.com/stretchr/testify/assert" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -func TestTryLock(t *testing.T) { - ctx := context.Background() - t.Run("try lock successfully", func(t *testing.T) { - request := runtimev1pb.TryLockRequest{ - StoreName: "demo", - ResourceId: "lock_test", - LockOwner: "layotto", - } - lock, err := testClient.TryLock(ctx, &request) - assert.Nil(t, err) - assert.True(t, lock.Success) - }) -} - -func TestUnLock(t *testing.T) { - ctx := context.Background() - t.Run("can't unlock with different owner", func(t *testing.T) { - request := runtimev1pb.TryLockRequest{ - StoreName: "demo", - ResourceId: "unlock_test", - LockOwner: "layotto", - } - lock, err := testClient.TryLock(ctx, &request) - assert.Nil(t, err) - assert.True(t, lock.Success) - // 2. unlock with different owner - unlockReq := runtimev1pb.UnlockRequest{ - StoreName: "demo", - ResourceId: "unlock_test", - LockOwner: "layotto1", - } - unlock, err := testClient.Unlock(ctx, &unlockReq) - assert.Nil(t, err) - assert.Equal(t, unlock.Status, runtimev1pb.UnlockResponse_LOCK_BELONG_TO_OTHERS) - }) - - t.Run("unlock successfully", func(t *testing.T) { - request := runtimev1pb.UnlockRequest{ - StoreName: "demo", - ResourceId: "unlock_test", - LockOwner: "layotto", - } - unlock, err := testClient.Unlock(ctx, &request) - assert.Nil(t, err) - assert.Equal(t, unlock.Status, runtimev1pb.UnlockResponse_SUCCESS) - }) - - t.Run("unlock but LOCK_UNEXIST", func(t *testing.T) { - request := runtimev1pb.UnlockRequest{ - StoreName: "demo", - ResourceId: "unlock_test", - LockOwner: "layotto", - } - unlock, err := testClient.Unlock(ctx, &request) - assert.Nil(t, err) - assert.Equal(t, unlock.Status, runtimev1pb.UnlockResponse_LOCK_UNEXIST) - }) -} diff --git a/sdk/go-sdk/client/pubsub.go b/sdk/go-sdk/client/pubsub.go deleted file mode 100644 index 1c401bb38b..0000000000 --- a/sdk/go-sdk/client/pubsub.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - "encoding/json" - - "github.com/pkg/errors" - - pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -// PublishEvent publishes data onto specific pubsub topic. -func (c *GRPCClient) PublishEvent(ctx context.Context, pubsubName, topicName string, data []byte) error { - if pubsubName == "" { - return errors.New("pubsubName name required") - } - if topicName == "" { - return errors.New("topic name required") - } - - envelop := &pb.PublishEventRequest{ - PubsubName: pubsubName, - Topic: topicName, - Data: data, - } - - _, err := c.protoClient.PublishEvent(ctx, envelop) - if err != nil { - return errors.Wrapf(err, "error publishing event unto %s topic", topicName) - } - - return nil -} - -// PublishEventfromCustomContent serializes an struct and publishes its contents as data (JSON) onto topic in specific pubsub component. -func (c *GRPCClient) PublishEventfromCustomContent(ctx context.Context, pubsubName, topicName string, data interface{}) error { - if pubsubName == "" { - return errors.New("pubsubName name required") - } - if topicName == "" { - return errors.New("topic name required") - } - - bytes, err := json.Marshal(data) - - if err != nil { - return errors.WithMessage(err, "error serializing input struct") - } - - envelop := &pb.PublishEventRequest{ - PubsubName: pubsubName, - Topic: topicName, - Data: bytes, - DataContentType: "application/json", - } - - _, err = c.protoClient.PublishEvent(ctx, envelop) - - if err != nil { - return errors.Wrapf(err, "error publishing event unto %s topic", topicName) - } - - return nil -} diff --git a/sdk/go-sdk/client/pubsub_test.go b/sdk/go-sdk/client/pubsub_test.go deleted file mode 100644 index 5c3a485706..0000000000 --- a/sdk/go-sdk/client/pubsub_test.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" -) - -type _testCustomContentwithText struct { - Key1, Key2 string -} - -type _testCustomContentwithTextandNumbers struct { - Key1 string - Key2 int -} - -type _testCustomContentwithSlices struct { - Key1 []string - Key2 []int -} - -// go test -timeout 30s ./client -count 1 -run ^TestPublishEvent$ -func TestPublishEvent(t *testing.T) { - ctx := context.Background() - - t.Run("with data", func(t *testing.T) { - err := testClient.PublishEvent(ctx, "messages", "test", []byte("ping")) - assert.Nil(t, err) - }) - - t.Run("without data", func(t *testing.T) { - err := testClient.PublishEvent(ctx, "messages", "test", nil) - assert.Nil(t, err) - }) - - t.Run("with empty topic name", func(t *testing.T) { - err := testClient.PublishEvent(ctx, "messages", "", []byte("ping")) - assert.NotNil(t, err) - }) - - t.Run("from struct with text", func(t *testing.T) { - testdata := _testStructwithText{ - Key1: "value1", - Key2: "value2", - } - err := testClient.PublishEventfromCustomContent(ctx, "messages", "test", testdata) - assert.Nil(t, err) - }) - - t.Run("from struct with text and numbers", func(t *testing.T) { - testdata := _testStructwithTextandNumbers{ - Key1: "value1", - Key2: 2500, - } - err := testClient.PublishEventfromCustomContent(ctx, "messages", "test", testdata) - assert.Nil(t, err) - }) - - t.Run("from struct with slices", func(t *testing.T) { - testdata := _testStructwithSlices{ - Key1: []string{"value1", "value2", "value3"}, - Key2: []int{25, 40, 600}, - } - err := testClient.PublishEventfromCustomContent(ctx, "messages", "test", testdata) - assert.Nil(t, err) - }) -} diff --git a/sdk/go-sdk/client/secret.go b/sdk/go-sdk/client/secret.go deleted file mode 100644 index cb7a24b34c..0000000000 --- a/sdk/go-sdk/client/secret.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - - "google.golang.org/grpc" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -func (c *GRPCClient) GetSecret(ctx context.Context, in *runtimev1pb.GetSecretRequest, opts ...grpc.CallOption) (*runtimev1pb.GetSecretResponse, error) { - - return c.protoClient.GetSecret(ctx, in) -} -func (c *GRPCClient) GetBulkSecret(ctx context.Context, in *runtimev1pb.GetBulkSecretRequest, opts ...grpc.CallOption) (*runtimev1pb.GetBulkSecretResponse, error) { - - return c.protoClient.GetBulkSecret(ctx, in) -} diff --git a/sdk/go-sdk/client/secret_test.go b/sdk/go-sdk/client/secret_test.go deleted file mode 100644 index 3bf43e53c8..0000000000 --- a/sdk/go-sdk/client/secret_test.go +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2021 Layotto 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 client - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -var secretKey = "secret-key" -var secretValue = "secret-value" - -func TestGetSecret(t *testing.T) { - - resp, err := testClient.GetSecret(context.Background(), &runtimev1pb.GetSecretRequest{ - Key: secretKey, - }) - assert.Nil(t, err) - assert.Equal(t, resp.Data[secretKey], secretValue) -} - -func TestGetBulkSecret(t *testing.T) { - resp, err := testClient.GetBulkSecret(context.Background(), &runtimev1pb.GetBulkSecretRequest{}) - assert.Nil(t, err) - assert.Equal(t, resp.Data[secretKey].Secrets[secretKey], secretValue) -} diff --git a/sdk/go-sdk/client/sequencer.go b/sdk/go-sdk/client/sequencer.go deleted file mode 100644 index 788778d8ab..0000000000 --- a/sdk/go-sdk/client/sequencer.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2021 Layotto 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 client - -import ( - "context" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -func (c *GRPCClient) GetNextId(ctx context.Context, req *runtimev1pb.GetNextIdRequest) (*runtimev1pb.GetNextIdResponse, error) { - return c.protoClient.GetNextId(ctx, req) -} diff --git a/sdk/go-sdk/client/state.go b/sdk/go-sdk/client/state.go deleted file mode 100755 index 04d2fc92f1..0000000000 --- a/sdk/go-sdk/client/state.go +++ /dev/null @@ -1,469 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - "time" - - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" - - "github.com/golang/protobuf/ptypes/duration" - "github.com/pkg/errors" -) - -const ( - // StateConsistencyUndefined is the undefined value for state consistency. - StateConsistencyUndefined StateConsistency = 0 - // StateConsistencyEventual represents eventual state consistency value. - StateConsistencyEventual StateConsistency = 1 - // StateConsistencyStrong represents strong state consistency value. - StateConsistencyStrong StateConsistency = 2 - - // StateConcurrencyUndefined is the undefined value for state concurrency. - StateConcurrencyUndefined StateConcurrency = 0 - // StateConcurrencyFirstWrite represents first write concurrency value. - StateConcurrencyFirstWrite StateConcurrency = 1 - // StateConcurrencyLastWrite represents last write concurrency value. - StateConcurrencyLastWrite StateConcurrency = 2 - - // StateOperationTypeUndefined is the undefined value for state operation type. - StateOperationTypeUndefined OperationType = 0 - // StateOperationTypeUpsert represents upsert operation type value. - StateOperationTypeUpsert OperationType = 1 - // StateOperationTypeDelete represents delete operation type value. - StateOperationTypeDelete OperationType = 2 - // UndefinedType represents undefined type value - UndefinedType = "undefined" -) - -type ( - // StateConsistency is the consistency enum type. - StateConsistency int - // StateConcurrency is the concurrency enum type. - StateConcurrency int - // OperationType is the operation enum type. - OperationType int -) - -// GetPBConsistency get consistency pb value -func (s StateConsistency) GetPBConsistency() runtimev1pb.StateOptions_StateConsistency { - return runtimev1pb.StateOptions_StateConsistency(s) -} - -// GetPBConcurrency get concurrency pb value -func (s StateConcurrency) GetPBConcurrency() runtimev1pb.StateOptions_StateConcurrency { - return runtimev1pb.StateOptions_StateConcurrency(s) -} - -// String returns the string value of the OperationType. -func (o OperationType) String() string { - names := [...]string{ - UndefinedType, - "upsert", - "delete", - } - if o < StateOperationTypeUpsert || o > StateOperationTypeDelete { - return UndefinedType - } - - return names[o] -} - -// String returns the string value of the StateConsistency. -func (s StateConsistency) String() string { - names := [...]string{ - UndefinedType, - "strong", - "eventual", - } - if s < StateConsistencyStrong || s > StateConsistencyEventual { - return UndefinedType - } - - return names[s] -} - -// String returns the string value of the StateConcurrency. -func (s StateConcurrency) String() string { - names := [...]string{ - UndefinedType, - "first-write", - "last-write", - } - if s < StateConcurrencyFirstWrite || s > StateConcurrencyLastWrite { - return UndefinedType - } - - return names[s] -} - -var ( - stateOptionDefault = &runtimev1pb.StateOptions{ - Concurrency: runtimev1pb.StateOptions_CONCURRENCY_LAST_WRITE, - Consistency: runtimev1pb.StateOptions_CONSISTENCY_STRONG, - } -) - -// StateOperation is a collection of StateItems with a store name. -type StateOperation struct { - Type OperationType - Item *SetStateItem -} - -// StateItem represents a single state item. -type StateItem struct { - Key string - Value []byte - Etag string - Metadata map[string]string -} - -// BulkStateItem represents a single state item. -type BulkStateItem struct { - Key string - Value []byte - Etag string - Metadata map[string]string - Error string -} - -// SetStateItem represents a single state to be persisted. -type SetStateItem struct { - Key string - Value []byte - Etag *ETag - Metadata map[string]string - Options *StateOptions -} - -// DeleteStateItem represents a single state to be deleted. -type DeleteStateItem SetStateItem - -// ETag represents an versioned record information -type ETag struct { - Value string -} - -// StateOptions represents the state store persistence policy. -type StateOptions struct { - Concurrency StateConcurrency - Consistency StateConsistency -} - -// StateOption StateOptions's function type -type StateOption func(*StateOptions) - -// WithConcurrency set StateOptions's Concurrency -func WithConcurrency(concurrency StateConcurrency) StateOption { - return func(so *StateOptions) { - so.Concurrency = concurrency - } -} - -// WithConsistency set StateOptions's consistency -func WithConsistency(consistency StateConsistency) StateOption { - return func(so *StateOptions) { - so.Consistency = consistency - } -} - -func toProtoSaveStateItem(si *SetStateItem) (item *runtimev1pb.StateItem) { - s := &runtimev1pb.StateItem{ - Key: si.Key, - Metadata: si.Metadata, - Value: si.Value, - Options: toProtoStateOptions(si.Options), - } - - if si.Etag != nil { - s.Etag = &runtimev1pb.Etag{ - Value: si.Etag.Value, - } - } - - return s -} - -func toProtoStateOptions(so *StateOptions) (opts *runtimev1pb.StateOptions) { - if so == nil { - return copyStateOptionDefaultPB() - } - return &runtimev1pb.StateOptions{ - Concurrency: runtimev1pb.StateOptions_StateConcurrency(so.Concurrency), - Consistency: runtimev1pb.StateOptions_StateConsistency(so.Consistency), - } -} - -func copyStateOptionDefaultPB() *runtimev1pb.StateOptions { - return &runtimev1pb.StateOptions{ - Concurrency: stateOptionDefault.GetConcurrency(), - Consistency: stateOptionDefault.GetConsistency(), - } -} - -func copyStateOptionDefault() *StateOptions { - return &StateOptions{ - Concurrency: StateConcurrency(stateOptionDefault.GetConcurrency()), - Consistency: StateConsistency(stateOptionDefault.GetConsistency()), - } -} - -func toProtoDuration(d time.Duration) *duration.Duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &duration.Duration{ - Seconds: secs, - Nanos: int32(nanos), - } -} - -// ExecuteStateTransaction provides way to execute multiple operations on a specified store. -func (c *GRPCClient) ExecuteStateTransaction(ctx context.Context, storeName string, meta map[string]string, ops []*StateOperation) error { - // 1. parameter validation - if storeName == "" { - return errors.New("nil storeName") - } - if len(ops) == 0 { - return nil - } - // 2. prepare request - items := make([]*runtimev1pb.TransactionalStateOperation, 0) - for _, op := range ops { - item := &runtimev1pb.TransactionalStateOperation{ - OperationType: op.Type.String(), - Request: toProtoSaveStateItem(op.Item), - } - items = append(items, item) - } - - req := &runtimev1pb.ExecuteStateTransactionRequest{ - Metadata: meta, - StoreName: storeName, - Operations: items, - } - // 3. send request - _, err := c.protoClient.ExecuteStateTransaction(ctx, req) - if err != nil { - return errors.Wrap(err, "error executing state transaction") - } - return nil -} - -// SaveState saves the raw data into store, default options: strong, last-write -func (c *GRPCClient) SaveState(ctx context.Context, storeName, key string, data []byte, so ...StateOption) error { - var stateOptions = new(StateOptions) - for _, o := range so { - o(stateOptions) - } - if len(so) == 0 { - stateOptions = copyStateOptionDefault() - } - item := &SetStateItem{Key: key, Value: data, Options: stateOptions} - return c.SaveBulkState(ctx, storeName, item) -} - -// SaveBulkState saves the multiple state item to store. -func (c *GRPCClient) SaveBulkState(ctx context.Context, storeName string, items ...*SetStateItem) error { - if storeName == "" { - return errors.New("nil store") - } - if items == nil { - return errors.New("nil item") - } - - req := &runtimev1pb.SaveStateRequest{ - StoreName: storeName, - States: make([]*runtimev1pb.StateItem, 0), - } - - for _, si := range items { - item := toProtoSaveStateItem(si) - req.States = append(req.States, item) - } - - _, err := c.protoClient.SaveState(ctx, req) - if err != nil { - return errors.Wrap(err, "error saving state") - } - return nil -} - -// GetBulkState retrieves state for multiple keys from specific store. -func (c *GRPCClient) GetBulkState(ctx context.Context, storeName string, keys []string, meta map[string]string, parallelism int32) ([]*BulkStateItem, error) { - if storeName == "" { - return nil, errors.New("nil store") - } - if len(keys) == 0 { - return nil, errors.New("keys required") - } - items := make([]*BulkStateItem, 0) - - req := &runtimev1pb.GetBulkStateRequest{ - StoreName: storeName, - Keys: keys, - Metadata: meta, - Parallelism: parallelism, - } - - results, err := c.protoClient.GetBulkState(ctx, req) - if err != nil { - return nil, errors.Wrap(err, "error getting state") - } - - if results == nil || results.Items == nil { - return items, nil - } - - for _, r := range results.Items { - item := &BulkStateItem{ - Key: r.Key, - Etag: r.Etag, - Value: r.Data, - Metadata: r.Metadata, - Error: r.Error, - } - items = append(items, item) - } - - return items, nil -} - -// GetState retrieves state from specific store using default consistency option. -func (c *GRPCClient) GetState(ctx context.Context, storeName, key string) (item *StateItem, err error) { - return c.GetStateWithConsistency(ctx, storeName, key, nil, StateConsistencyStrong) -} - -// GetStateWithConsistency retrieves state from specific store using provided state consistency. -func (c *GRPCClient) GetStateWithConsistency(ctx context.Context, storeName, key string, meta map[string]string, sc StateConsistency) (item *StateItem, err error) { - if err := hasRequiredStateArgs(storeName, key); err != nil { - return nil, errors.Wrap(err, "missing required arguments") - } - - req := &runtimev1pb.GetStateRequest{ - StoreName: storeName, - Key: key, - Consistency: runtimev1pb.StateOptions_StateConsistency(sc), - Metadata: meta, - } - - result, err := c.protoClient.GetState(ctx, req) - if err != nil { - return nil, errors.Wrap(err, "error getting state") - } - - return &StateItem{ - Etag: result.Etag, - Key: key, - Value: result.Data, - Metadata: result.Metadata, - }, nil -} - -// DeleteState deletes content from store using default state options. -func (c *GRPCClient) DeleteState(ctx context.Context, storeName, key string) error { - return c.DeleteStateWithETag(ctx, storeName, key, nil, nil, nil) -} - -// DeleteStateWithETag deletes content from store using provided state options and etag. -func (c *GRPCClient) DeleteStateWithETag(ctx context.Context, storeName, key string, etag *ETag, meta map[string]string, opts *StateOptions) error { - if err := hasRequiredStateArgs(storeName, key); err != nil { - return errors.Wrap(err, "missing required arguments") - } - - req := &runtimev1pb.DeleteStateRequest{ - StoreName: storeName, - Key: key, - Options: toProtoStateOptions(opts), - Metadata: meta, - } - - if etag != nil { - req.Etag = &runtimev1pb.Etag{ - Value: etag.Value, - } - } - - _, err := c.protoClient.DeleteState(ctx, req) - if err != nil { - return errors.Wrap(err, "error deleting state") - } - - return nil -} - -// DeleteBulkState deletes content for multiple keys from store. -func (c *GRPCClient) DeleteBulkState(ctx context.Context, storeName string, keys []string) error { - if len(keys) == 0 { - return nil - } - - items := make([]*DeleteStateItem, 0, len(keys)) - for i := 0; i < len(keys); i++ { - item := &DeleteStateItem{ - Key: keys[i], - } - items = append(items, item) - } - - return c.DeleteBulkStateItems(ctx, storeName, items) -} - -// DeleteBulkState deletes content for multiple keys from store. -func (c *GRPCClient) DeleteBulkStateItems(ctx context.Context, storeName string, items []*DeleteStateItem) error { - if len(items) == 0 { - return nil - } - - states := make([]*runtimev1pb.StateItem, 0, len(items)) - for i := 0; i < len(items); i++ { - item := items[i] - if err := hasRequiredStateArgs(storeName, item.Key); err != nil { - return errors.Wrap(err, "missing required arguments") - } - - state := &runtimev1pb.StateItem{ - Key: item.Key, - Metadata: item.Metadata, - Options: toProtoStateOptions(item.Options), - } - if item.Etag != nil { - state.Etag = &runtimev1pb.Etag{ - Value: item.Etag.Value, - } - } - states = append(states, state) - } - - req := &runtimev1pb.DeleteBulkStateRequest{ - StoreName: storeName, - States: states, - } - _, err := c.protoClient.DeleteBulkState(ctx, req) - - return err -} - -func hasRequiredStateArgs(storeName, key string) error { - if storeName == "" { - return errors.New("store") - } - if key == "" { - return errors.New("key") - } - return nil -} diff --git a/sdk/go-sdk/client/state_test.go b/sdk/go-sdk/client/state_test.go deleted file mode 100755 index d6325816f0..0000000000 --- a/sdk/go-sdk/client/state_test.go +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2021 Layotto 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. -// CODE ATTRIBUTION: https://github.com/dapr/go-sdk -// Modified the import package to use layotto's pb -// We use same sdk code with Dapr's for state API because we want to keep compatible with Dapr state API -package client - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/assert" - - v1 "mosn.io/layotto/spec/proto/runtime/v1" -) - -const test = "test" - -func TestTypes(t *testing.T) { - var op OperationType = -1 - assert.Equal(t, UndefinedType, op.String()) - var c StateConcurrency = -1 - assert.Equal(t, UndefinedType, c.String()) - var d StateConsistency = -1 - assert.Equal(t, UndefinedType, d.String()) -} - -func TestDurationConverter(t *testing.T) { - d := 10 * time.Second - pd := toProtoDuration(d) - assert.NotNil(t, pd) - assert.Equal(t, pd.Seconds, int64(10)) -} - -func TestStateOptionsConverter(t *testing.T) { - s := &StateOptions{ - Concurrency: StateConcurrencyLastWrite, - Consistency: StateConsistencyStrong, - } - p := toProtoStateOptions(s) - assert.NotNil(t, p) - assert.Equal(t, p.Concurrency, v1.StateOptions_CONCURRENCY_LAST_WRITE) - assert.Equal(t, p.Consistency, v1.StateOptions_CONSISTENCY_STRONG) -} - -// go test -timeout 30s ./client -count 1 -run ^TestSaveState$ -func TestSaveState(t *testing.T) { - ctx := context.Background() - data := test - store := test - key := "key1" - - t.Run("save data", func(t *testing.T) { - err := testClient.SaveState(ctx, store, key, []byte(data)) - assert.Nil(t, err) - }) - - t.Run("get saved data", func(t *testing.T) { - item, err := testClient.GetState(ctx, store, key) - assert.Nil(t, err) - assert.NotNil(t, item) - assert.NotEmpty(t, item.Etag) - assert.Equal(t, item.Key, key) - assert.Equal(t, string(item.Value), data) - }) - - t.Run("get saved data with consistency", func(t *testing.T) { - item, err := testClient.GetStateWithConsistency(ctx, store, key, nil, StateConsistencyStrong) - assert.Nil(t, err) - assert.NotNil(t, item) - assert.NotEmpty(t, item.Etag) - assert.Equal(t, item.Key, key) - assert.Equal(t, string(item.Value), data) - }) - - t.Run("save data with version", func(t *testing.T) { - item := &SetStateItem{ - Etag: &ETag{ - Value: "1", - }, - Key: key, - Value: []byte(data), - } - err := testClient.SaveBulkState(ctx, store, item) - assert.Nil(t, err) - }) - - t.Run("delete data", func(t *testing.T) { - err := testClient.DeleteState(ctx, store, key) - assert.Nil(t, err) - }) -} - -// go test -timeout 30s ./client -count 1 -run ^TestDeleteState$ -func TestDeleteState(t *testing.T) { - ctx := context.Background() - data := test - store := test - key := "key1" - - t.Run("delete not exist data", func(t *testing.T) { - err := testClient.DeleteState(ctx, store, key) - assert.Nil(t, err) - }) - t.Run("delete not exist data with etag and meta", func(t *testing.T) { - err := testClient.DeleteStateWithETag(ctx, store, key, &ETag{Value: "100"}, map[string]string{"meta1": "value1"}, - &StateOptions{Concurrency: StateConcurrencyFirstWrite, Consistency: StateConsistencyEventual}) - assert.Nil(t, err) - }) - - t.Run("save data", func(t *testing.T) { - err := testClient.SaveState(ctx, store, key, []byte(data)) - assert.Nil(t, err) - }) - t.Run("confirm data saved", func(t *testing.T) { - item, err := testClient.GetState(ctx, store, key) - assert.Nil(t, err) - assert.NotNil(t, item) - assert.NotEmpty(t, item.Etag) - assert.Equal(t, item.Key, key) - assert.Equal(t, string(item.Value), data) - }) - - t.Run("delete exist data", func(t *testing.T) { - err := testClient.DeleteState(ctx, store, key) - assert.Nil(t, err) - }) - t.Run("confirm data deleted", func(t *testing.T) { - item, err := testClient.GetState(ctx, store, key) - assert.Nil(t, err) - assert.NotNil(t, item) - assert.NotEmpty(t, item.Etag) - assert.Equal(t, item.Key, key) - assert.Nil(t, item.Value) - }) - - t.Run("save data again with etag, meta", func(t *testing.T) { - err := testClient.SaveBulkState(ctx, store, &SetStateItem{ - Key: key, - Value: []byte(data), - Etag: &ETag{ - Value: "1", - }, - Metadata: map[string]string{"meta1": "value1"}, - Options: &StateOptions{Concurrency: StateConcurrencyFirstWrite, Consistency: StateConsistencyEventual}, - }) - assert.Nil(t, err) - }) - t.Run("confirm data saved", func(t *testing.T) { - item, err := testClient.GetStateWithConsistency(ctx, store, key, map[string]string{"meta1": "value1"}, StateConsistencyEventual) - assert.Nil(t, err) - assert.NotNil(t, item) - assert.NotEmpty(t, item.Etag) - assert.Equal(t, item.Key, key) - assert.Equal(t, string(item.Value), data) - }) - - t.Run("delete exist data with etag and meta", func(t *testing.T) { - err := testClient.DeleteStateWithETag(ctx, store, key, &ETag{Value: "100"}, map[string]string{"meta1": "value1"}, - &StateOptions{Concurrency: StateConcurrencyFirstWrite, Consistency: StateConsistencyEventual}) - assert.Nil(t, err) - }) - t.Run("confirm data deleted", func(t *testing.T) { - item, err := testClient.GetStateWithConsistency(ctx, store, key, map[string]string{"meta1": "value1"}, StateConsistencyEventual) - assert.Nil(t, err) - assert.NotNil(t, item) - assert.NotEmpty(t, item.Etag) - assert.Equal(t, item.Key, key) - assert.Nil(t, item.Value) - }) -} - -func TestDeleteBulkState(t *testing.T) { - ctx := context.Background() - data := test - store := test - keys := []string{"key1", "key2", "key3"} - - t.Run("delete not exist data", func(t *testing.T) { - err := testClient.DeleteBulkState(ctx, store, keys) - assert.Nil(t, err) - }) - - t.Run("delete not exist data with stateIem", func(t *testing.T) { - items := make([]*DeleteStateItem, 0, len(keys)) - for _, key := range keys { - items = append(items, &DeleteStateItem{ - Key: key, - Metadata: map[string]string{}, - Options: &StateOptions{ - Concurrency: StateConcurrencyFirstWrite, - Consistency: StateConsistencyEventual, - }, - }) - } - err := testClient.DeleteBulkStateItems(ctx, store, items) - assert.Nil(t, err) - }) - - t.Run("delete exist data", func(t *testing.T) { - // save data - items := make([]*SetStateItem, 0, len(keys)) - for _, key := range keys { - items = append(items, &SetStateItem{ - Key: key, - Value: []byte(data), - Metadata: map[string]string{}, - Etag: &ETag{Value: "1"}, - Options: &StateOptions{ - Concurrency: StateConcurrencyFirstWrite, - Consistency: StateConsistencyEventual, - }, - }) - } - err := testClient.SaveBulkState(ctx, store, items...) - assert.Nil(t, err) - - // confirm data saved - getItems, err := testClient.GetBulkState(ctx, store, keys, nil, 1) - assert.NoError(t, err) - assert.Equal(t, len(keys), len(getItems)) - - // delete - err = testClient.DeleteBulkState(ctx, store, keys) - assert.NoError(t, err) - - // confirm data deleted - getItems, err = testClient.GetBulkState(ctx, store, keys, nil, 1) - assert.NoError(t, err) - assert.Equal(t, 0, len(getItems)) - }) - - t.Run("delete exist data with stateItem", func(t *testing.T) { - // save data - items := make([]*SetStateItem, 0, len(keys)) - for _, key := range keys { - items = append(items, &SetStateItem{ - Key: key, - Value: []byte(data), - Metadata: map[string]string{}, - Etag: &ETag{Value: "1"}, - Options: &StateOptions{ - Concurrency: StateConcurrencyFirstWrite, - Consistency: StateConsistencyEventual, - }, - }) - } - err := testClient.SaveBulkState(ctx, store, items...) - assert.Nil(t, err) - - // confirm data saved - getItems, err := testClient.GetBulkState(ctx, store, keys, nil, 1) - assert.NoError(t, err) - assert.Equal(t, len(keys), len(getItems)) - - // delete - deleteItems := make([]*DeleteStateItem, 0, len(keys)) - for _, key := range keys { - deleteItems = append(deleteItems, &DeleteStateItem{ - Key: key, - Metadata: map[string]string{}, - Etag: &ETag{Value: "1"}, - Options: &StateOptions{ - Concurrency: StateConcurrencyFirstWrite, - Consistency: StateConsistencyEventual, - }, - }) - } - err = testClient.DeleteBulkStateItems(ctx, store, deleteItems) - assert.Nil(t, err) - - // confirm data deleted - getItems, err = testClient.GetBulkState(ctx, store, keys, nil, 1) - assert.NoError(t, err) - assert.Equal(t, 0, len(getItems)) - }) -} - -// go test -timeout 30s ./client -count 1 -run ^TestStateTransactions$ -func TestStateTransactions(t *testing.T) { - ctx := context.Background() - data := `{ "message": "test" }` - store := test - meta := map[string]string{} - keys := []string{"k1", "k2", "k3"} - adds := make([]*StateOperation, 0) - - for _, k := range keys { - op := &StateOperation{ - Type: StateOperationTypeUpsert, - Item: &SetStateItem{ - Key: k, - Value: []byte(data), - }, - } - adds = append(adds, op) - } - - t.Run("exec inserts", func(t *testing.T) { - err := testClient.ExecuteStateTransaction(ctx, store, meta, adds) - assert.Nil(t, err) - }) - - t.Run("exec upserts", func(t *testing.T) { - items, err := testClient.GetBulkState(ctx, store, keys, nil, 10) - assert.Nil(t, err) - assert.NotNil(t, items) - assert.Len(t, items, len(keys)) - - upsers := make([]*StateOperation, 0) - for _, item := range items { - op := &StateOperation{ - Type: StateOperationTypeUpsert, - Item: &SetStateItem{ - Key: item.Key, - Etag: &ETag{ - Value: item.Etag, - }, - Value: item.Value, - }, - } - upsers = append(upsers, op) - } - err = testClient.ExecuteStateTransaction(ctx, store, meta, upsers) - assert.Nil(t, err) - }) - - t.Run("get and validate inserts", func(t *testing.T) { - items, err := testClient.GetBulkState(ctx, store, keys, nil, 10) - assert.Nil(t, err) - assert.NotNil(t, items) - assert.Len(t, items, len(keys)) - assert.Equal(t, data, string(items[0].Value)) - }) - - for _, op := range adds { - op.Type = StateOperationTypeDelete - } - - t.Run("exec deletes", func(t *testing.T) { - err := testClient.ExecuteStateTransaction(ctx, store, meta, adds) - assert.Nil(t, err) - }) - - t.Run("ensure deletes", func(t *testing.T) { - items, err := testClient.GetBulkState(ctx, store, keys, nil, 3) - assert.Nil(t, err) - assert.NotNil(t, items) - assert.Len(t, items, 0) - }) - -} diff --git a/sdk/go-sdk/go.mod b/sdk/go-sdk/go.mod deleted file mode 100644 index d685a85bfe..0000000000 --- a/sdk/go-sdk/go.mod +++ /dev/null @@ -1,15 +0,0 @@ -module mosn.io/layotto/sdk/go-sdk - -go 1.14 - -require ( - github.com/golang/protobuf v1.5.0 - github.com/google/uuid v1.1.2 - github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.7.0 - google.golang.org/grpc v1.37.0 - google.golang.org/protobuf v1.26.0-rc.1 - mosn.io/layotto/spec v0.0.0-20210707123820-584778d048d3 -) - -replace mosn.io/layotto/spec v0.0.0-20210707123820-584778d048d3 => ../../spec diff --git a/sdk/go-sdk/go.sum b/sdk/go-sdk/go.sum deleted file mode 100644 index f63b65b4ce..0000000000 --- a/sdk/go-sdk/go.sum +++ /dev/null @@ -1,97 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/sdk/go-sdk/test/runtime/integrate_test.go b/sdk/go-sdk/test/runtime/integrate_test.go deleted file mode 100644 index 077bb0a1d9..0000000000 --- a/sdk/go-sdk/test/runtime/integrate_test.go +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2021 Layotto 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 runtime - -import ( - "context" - "fmt" - "net" - "sync" - "testing" - "time" - - "github.com/golang/protobuf/ptypes/empty" - "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "google.golang.org/grpc" - - "mosn.io/layotto/sdk/go-sdk/client" - runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" -) - -const ( - appid = "testApplication" - group = "application" -) - -var PubsubStoreName string - -func TestHelloApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - helloReq := &client.SayHelloRequest{ - ServiceName: "quick_start_demo", - } - helloResp, err := cli.SayHello(ctx, helloReq) - assert.Nil(t, err) - assert.Equal(t, "greeting", helloResp.Hello) -} - -func TestConfigurationApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - item1 := &client.ConfigurationItem{Group: group, Label: "test", Key: "key1", Content: "value1"} - item2 := &client.ConfigurationItem{Group: group, Label: "test", Key: "key2", Content: "value2"} - - componentArray := [...]string{"etcd_config_demo"} - for _, storeName := range componentArray { - saveRequest := &client.SaveConfigurationRequest{StoreName: storeName, AppId: appid} - saveRequest.Items = append(saveRequest.Items, item1) - saveRequest.Items = append(saveRequest.Items, item2) - err = cli.SaveConfiguration(ctx, saveRequest) - assert.Nil(t, err) - - // Since configuration data might be cached and eventual-consistent,we need to sleep a while before querying new data - time.Sleep(time.Second * 2) - getRequest := &client.ConfigurationRequestItem{StoreName: storeName, AppId: appid, Group: group, Label: "test", Keys: []string{"key1", "key2"}} - resp, err := cli.GetConfiguration(ctx, getRequest) - assert.Nil(t, err) - assert.Equal(t, item1, resp[0]) - assert.Equal(t, item2, resp[1]) - } -} - -func TestStateApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - stateKey := "MyStateKey" - stateValue := []byte("Hello Layotto!") - - componentArray := [...]string{"redis_state_demo", "zookeeper_state_demo"} - for _, storeName := range componentArray { - err = cli.SaveState(ctx, storeName, stateKey, stateValue) - assert.Nil(t, err) - - stateResp, err := cli.GetState(ctx, storeName, stateKey) - assert.Nil(t, err) - assert.Equal(t, stateValue, stateResp.Value) - } -} - -func TestLockApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - owner1 := uuid.New().String() - owner2 := uuid.New().String() - resourceID := "MyLock" - - componentArray := [...]string{"redis_lock_demo", "etcd_lock_demo", "zookeeper_lock_demo"} - for _, storeName := range componentArray { - // 1. client1 tryLock - resp, err := cli.TryLock(ctx, &runtimev1pb.TryLockRequest{ - StoreName: storeName, - ResourceId: resourceID, - LockOwner: owner1, - Expire: 100000, - }) - assert.Nil(t, err) - assert.True(t, resp.Success) - - var wg sync.WaitGroup - wg.Add(1) - // 2. client2 tryLock - go func() { - resp, err := cli.TryLock(ctx, &runtimev1pb.TryLockRequest{ - StoreName: storeName, - ResourceId: resourceID, - LockOwner: owner2, - Expire: 1000, - }) - assert.Nil(t, err) - assert.False(t, resp.Success) - wg.Done() - }() - wg.Wait() - // 3. client1 unlock - unlockResp, err := cli.Unlock(ctx, &runtimev1pb.UnlockRequest{ - StoreName: storeName, - ResourceId: resourceID, - LockOwner: owner1, - }) - assert.Nil(t, err) - assert.Equal(t, runtimev1pb.UnlockResponse_SUCCESS, unlockResp.Status) - - // 4. client2 get lock - wg.Add(1) - go func() { - resp, err := cli.TryLock(ctx, &runtimev1pb.TryLockRequest{ - StoreName: storeName, - ResourceId: resourceID, - LockOwner: owner2, - Expire: 10, - }) - assert.Nil(t, err) - assert.True(t, true, resp.Success) - // 5. client2 unlock - unlockResp, err := cli.Unlock(ctx, &runtimev1pb.UnlockRequest{ - StoreName: storeName, - ResourceId: resourceID, - LockOwner: owner2, - }) - assert.Nil(t, err) - assert.Equal(t, runtimev1pb.UnlockResponse_SUCCESS, unlockResp.Status) - wg.Done() - }() - wg.Wait() - } -} - -func TestSequencerApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - sequencerKey := "MySequencerKey" - - componentArray := [...]string{"redis_sequencer_demo", "etcd_sequencer_demo", "zookeeper_sequencer_demo"} - for _, storeName := range componentArray { - for i := 1; i < 10; i++ { - resp, err := cli.GetNextId(ctx, &runtimev1pb.GetNextIdRequest{ - StoreName: storeName, - Key: sequencerKey, - }) - assert.Nil(t, err) - assert.Equal(t, int64(i), resp.NextId) - } - } -} - -func TestPubsubApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - componentArray := [...]string{"redis_pub_subs_demo"} - for _, storeName := range componentArray { - PubsubStoreName = storeName - //start a subscriber to subscribe to events - go func() { - port := 8888 - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) - assert.Nil(t, err) - grpcServer := grpc.NewServer() - runtimev1pb.RegisterAppCallbackServer(grpcServer, &AppCallbackServerImpl{}) - err = grpcServer.Serve(lis) - assert.Nil(t, err) - }() - - //publisher publishes an event - err := cli.PublishEventfromCustomContent(ctx, storeName, "topic1", "value1") - assert.Nil(t, err) - - //sleep for a while before subscriber get messages - time.Sleep(time.Second) - } -} - -func TestSecretApi(t *testing.T) { - cli, err := client.NewClientWithAddress("127.0.0.1:34904") - if err != nil { - t.Fatal(err) - } - defer cli.Close() - - ctx := context.Background() - - componentArray := [...]string{"local_file_secret_demo"} - for _, storeName := range componentArray { - //get the secret - secret, err := cli.GetSecret(ctx, &runtimev1pb.GetSecretRequest{ - StoreName: storeName, - Key: "testPassword", - }) - assert.Nil(t, err) - assert.Equal(t, "pw2", secret.Data["testPassword"]) - - //get the bulk secret - bulkSecret, err := cli.GetBulkSecret(ctx, &runtimev1pb.GetBulkSecretRequest{ - StoreName: storeName, - }) - assert.Nil(t, err) - assert.Equal(t, "admin", bulkSecret.Data["db-user-pass:username"].Secrets["db-user-pass:username"]) - assert.Equal(t, "pw1", bulkSecret.Data["db-user-pass:password"].Secrets["db-user-pass:password"]) - assert.Equal(t, "pw2", bulkSecret.Data["testPassword"].Secrets["testPassword"]) - } -} - -type AppCallbackServerImpl struct { -} - -func (a *AppCallbackServerImpl) ListTopicSubscriptions(ctx context.Context, empty *empty.Empty) (*runtimev1pb.ListTopicSubscriptionsResponse, error) { - result := &runtimev1pb.ListTopicSubscriptionsResponse{} - ts := &runtimev1pb.TopicSubscription{ - PubsubName: PubsubStoreName, - Topic: "topic1", - Metadata: nil, - } - result.Subscriptions = append(result.Subscriptions, ts) - return result, nil -} - -func (a *AppCallbackServerImpl) OnTopicEvent(ctx context.Context, request *runtimev1pb.TopicEventRequest) (*runtimev1pb.TopicEventResponse, error) { - var t *testing.T - assert.Equal(t, "topic1", request.Topic) - assert.Equal(t, "value1", request.Data) - return &runtimev1pb.TopicEventResponse{}, nil -} diff --git a/sdk/go-sdk/test/runtime/integrate_test.sh b/sdk/go-sdk/test/runtime/integrate_test.sh deleted file mode 100644 index 2a41afb114..0000000000 --- a/sdk/go-sdk/test/runtime/integrate_test.sh +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright 2021 Layotto 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. -# - -# fail fast -set -e - -# start storage systems, e.g. redis, zk, etcd -nohup redis-server --port 6380 & -bash /usr/share/zookeeper/bin/zkServer.sh start -nohup bash /usr/share/zookeeper/bin/zkCli.sh < ./sdk/go-sdk/test/runtime/zkCreateZnode.sh -cd .. -nohup etcd & - -# build and run Layotto -cd layotto -go build ./cmd/layotto -nohup ./layotto start -c ./configs/config_integrate_test.json & - -# run integrate_test -cd sdk/go-sdk/test/runtime -go test -p 1 -v ./... - -# run demos -cd ../../../../demo/configuration/common -go build -o client -names="etcd_config_demo" -for key in ${names}; do - ./client -s $key -done - -cd ../../state/common -go build -o client -names="redis_state_demo zookeeper_state_demo" -for key in ${names}; do - ./client -s $key -done - -cd ../../lock/common -go build -o client -names="redis_lock_demo etcd_lock_demo zookeeper_lock_demo" -for key in ${names}; do - ./client -s $key -done - -cd ../../sequencer/common -go build -o client -names="redis_sequencer_demo etcd_sequencer_demo zookeeper_sequencer_demo" -for key in ${names}; do - ./client -s $key -done - -cd ../../pubsub/server -names="redis_pub_subs_demo" -for key in ${names}; do - cd ../server - go build -o subscriber - ./subscriber -s $key & - cd ../client - go build -o publisher - ./publisher -s $key -done - -cd ../../secret/common -go build -o client -names="local_file_secret_demo" -for key in ${names}; do - ./client -s $key -done \ No newline at end of file diff --git a/sdk/go-sdk/test/runtime/zkCreateZnode.sh b/sdk/go-sdk/test/runtime/zkCreateZnode.sh deleted file mode 100644 index 20927512f6..0000000000 --- a/sdk/go-sdk/test/runtime/zkCreateZnode.sh +++ /dev/null @@ -1,26 +0,0 @@ - # - # Copyright 2021 Layotto 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. - -# sdk/go-sdk/test/runtime/integrate_test.go required -create /MyStateKey "" - -# demo/state/ required -create /key1 "" -create /key2 "" -create /key3 "" -create /key4 "" -create /key5 "" - -quit \ No newline at end of file