diff --git a/pkg/client/config.go b/pkg/client/config.go index 59e13750..831e8124 100644 --- a/pkg/client/config.go +++ b/pkg/client/config.go @@ -63,17 +63,35 @@ func (c *ClientConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { } type Config struct { + Enabled bool `yaml:"enabled" json:"enabled,omitempty" koanf:"enabled"` + ApplicationID string `yaml:"application-id" json:"application-id,omitempty" koanf:"application-id"` + TxServiceGroup string `yaml:"tx-service-group" json:"tx-service-group,omitempty" koanf:"tx-service-group"` + AccessKey string `yaml:"access-key" json:"access-key,omitempty" koanf:"access-key"` + SecretKey string `yaml:"secret-key" json:"secret-key,omitempty" koanf:"secret-key"` + EnableAutoDataSourceProxy bool `yaml:"enable-auto-data-source-proxy" json:"enable-auto-data-source-proxy,omitempty" koanf:"enable-auto-data-source-proxy"` + DataSourceProxyMode string `yaml:"data-source-proxy-mode" json:"data-source-proxy-mode,omitempty" koanf:"data-source-proxy-mode"` + TCCConfig tcc.Config `yaml:"tcc" json:"tcc" koanf:"tcc"` ClientConfig ClientConfig `yaml:"client" json:"client" koanf:"client"` GettyConfig getty.Config `yaml:"getty" json:"getty" koanf:"getty"` TransportConfig getty.TransportConfig `yaml:"transport" json:"transport" koanf:"transport"` + ServiceConfig tm.ServiceConfig `yaml:"service" json:"service" koanf:"service"` } func (c *Config) RegisterFlags(f *flag.FlagSet) { + f.BoolVar(&c.Enabled, "enabled", true, "Whether enable auto configuration.") + f.StringVar(&c.ApplicationID, "application-id", "seata-go", "Application id.") + f.StringVar(&c.TxServiceGroup, "tx-service-group", "default_tx_group", "Transaction service group.") + f.StringVar(&c.AccessKey, "access-key", "", "Used for aliyun accessKey.") + f.StringVar(&c.SecretKey, "secret-key", "", "Used for aliyun secretKey.") + f.BoolVar(&c.EnableAutoDataSourceProxy, "enable-auto-data-source-proxy", true, "Whether enable auto proxying of datasource bean.") + f.StringVar(&c.DataSourceProxyMode, "data-source-proxy-mode", "AT", "Data source proxy mode.") + c.TCCConfig.FenceConfig.RegisterFlagsWithPrefix("tcc", f) c.ClientConfig.RegisterFlagsWithPrefix("client", f) c.GettyConfig.RegisterFlagsWithPrefix("getty", f) c.TransportConfig.RegisterFlagsWithPrefix("transport", f) + c.ServiceConfig.RegisterFlagsWithPrefix("service", f) } type loaderConf struct { diff --git a/pkg/client/config_test.go b/pkg/client/config_test.go index bf0a5f8c..6e680f65 100644 --- a/pkg/client/config_test.go +++ b/pkg/client/config_test.go @@ -29,6 +29,13 @@ import ( func TestLoadPath(t *testing.T) { cfg := LoadPath("../../testdata/conf/seatago.yml") assert.NotNil(t, cfg) + assert.Equal(t, true, cfg.Enabled) + assert.Equal(t, "applicationName", cfg.ApplicationID) + assert.Equal(t, "default_tx_group", cfg.TxServiceGroup) + assert.Equal(t, "aliyunAccessKey", cfg.AccessKey) + assert.Equal(t, "aliyunSecretKey", cfg.SecretKey) + assert.Equal(t, true, cfg.EnableAutoDataSourceProxy) + assert.Equal(t, "AT", cfg.DataSourceProxyMode) assert.NotNil(t, cfg.TCCConfig) assert.NotNil(t, cfg.TCCConfig.FenceConfig) @@ -90,19 +97,32 @@ func TestLoadPath(t *testing.T) { assert.Equal(t, time.Second*30, cfg.TransportConfig.RPCRmRequestTimeout) assert.Equal(t, time.Second*30, cfg.TransportConfig.RPCTmRequestTimeout) + assert.NotNil(t, cfg.ServiceConfig) + assert.Equal(t, false, cfg.ServiceConfig.EnableDegrade) + assert.Equal(t, false, cfg.ServiceConfig.DisableGlobalTransaction) + assert.Equal(t, "default", cfg.ServiceConfig.VgroupMapping["default_tx_group"]) + assert.Equal(t, "127.0.0.1:8091", cfg.ServiceConfig.Grouplist["default"]) + // reset flag.CommandLine flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) } func TestLoadJson(t *testing.T) { - confJson := `{"client":{"rm":{"async-commit-buffer-limit":10000,"report-retry-count":5,"table-meta-check-enable":false,"report-success-enable":false,"saga-branch-register-enable":false,"saga-json-parser":"fastjson","saga-retry-persist-mode-update":false,"saga-compensate-persist-mode-update":false,"tcc-action-interceptor-order":-2147482648,"sql-parser-type":"druid","lock":{"retry-interval":10,"retry-times":"30s","retry-policy-branch-rollback-on-conflict":true}}, - "tm":{"commit-retry-count":5,"rollback-retry-count":5,"default-global-transaction-timeout":"60s","degrade-check":false,"degrade-check-period":2000,"degrade-check-allow-times":"10s","interceptor-order":-2147482648}}, - "tcc":{"fence":{"log-table-name":"tcc_fence_log_test2","clean-period":80000000000}}, - "getty":{"reconnect-interval":1,"connection-num":10,"heartbeat-period":"10s","session":{"compress-encoding":true,"tcp-no-delay":false,"tcp-keep-alive":false,"keep-alive-period":"120s","tcp-r-buf-size":261120,"tcp-w-buf-size":32768,"tcp-read-timeout":"2s","tcp-write-timeout":"8s","wait-timeout":"2s","max-msg-len":261120,"session-name":"client_test","cron-period":"2s"}}, - "transport":{"shutdown":{"wait":"3s"},"type":"TCP","server":"NIO","heartbeat":true,"serialization":"seata","compressor":"none"," enable-tm-client-batch-send-request":false,"enable-rm-client-batch-send-request":true,"rpc-rm-request-timeout":"30s","rpc-tm-request-timeout":"30s"}}` - + confJson := `{"enabled":false,"application-id":"application_test","tx-service-group":"default_tx_group","access-key":"test","secret-key":"test","enable-auto-data-source-proxy":false,"data-source-proxy-mode":"AT", + "client":{"rm":{"async-commit-buffer-limit":10000,"report-retry-count":5,"table-meta-check-enable":false,"report-success-enable":false,"saga-branch-register-enable":false,"saga-json-parser":"fastjson","saga-retry-persist-mode-update":false,"saga-compensate-persist-mode-update":false,"tcc-action-interceptor-order":-2147482648,"sql-parser-type":"druid","lock":{"retry-interval":10,"retry-times":"30s","retry-policy-branch-rollback-on-conflict":true}}, + "tm":{"commit-retry-count":5,"rollback-retry-count":5,"default-global-transaction-timeout":"60s","degrade-check":false,"degrade-check-period":2000,"degrade-check-allow-times":"10s","interceptor-order":-2147482648}},"tcc":{"fence":{"log-table-name":"tcc_fence_log_test2","clean-period":80000000000}}, + "getty":{"reconnect-interval":1,"connection-num":10,"heartbeat-period":"10s","session":{"compress-encoding":true,"tcp-no-delay":false,"tcp-keep-alive":false,"keep-alive-period":"120s","tcp-r-buf-size":261120,"tcp-w-buf-size":32768,"tcp-read-timeout":"2s","tcp-write-timeout":"8s","wait-timeout":"2s","max-msg-len":261120,"session-name":"client_test","cron-period":"2s"}}, + "transport":{"shutdown":{"wait":"3s"}, "type":"TCP", "server":"NIO", "heartbeat":true,"serialization":"seata","compressor":"none"," enable-tm-client-batch-send-request":false,"enable-rm-client-batch-send-request":true,"rpc-rm-request-timeout":"30s","rpc-tm-request-timeout":"30s"}, + "service":{"enable-degrade":true,"disable-global-transaction":true,"vgroup-mapping":{"default_tx_group":"default_test"},"grouplist":{"default":"127.0.0.1:8092"}}}` cfg := LoadJson([]byte(confJson)) assert.NotNil(t, cfg) + assert.Equal(t, false, cfg.Enabled) + assert.Equal(t, "application_test", cfg.ApplicationID) + assert.Equal(t, "default_tx_group", cfg.TxServiceGroup) + assert.Equal(t, "test", cfg.AccessKey) + assert.Equal(t, "test", cfg.SecretKey) + assert.Equal(t, false, cfg.EnableAutoDataSourceProxy) + assert.Equal(t, "AT", cfg.DataSourceProxyMode) assert.Equal(t, 10000, cfg.ClientConfig.RmConfig.AsyncCommitBufferLimit) assert.Equal(t, 5, cfg.ClientConfig.RmConfig.ReportRetryCount) @@ -164,6 +184,12 @@ func TestLoadJson(t *testing.T) { assert.Equal(t, time.Second*30, cfg.TransportConfig.RPCRmRequestTimeout) assert.Equal(t, time.Second*30, cfg.TransportConfig.RPCTmRequestTimeout) + assert.NotNil(t, cfg.ServiceConfig) + assert.Equal(t, true, cfg.ServiceConfig.EnableDegrade) + assert.Equal(t, true, cfg.ServiceConfig.DisableGlobalTransaction) + assert.Equal(t, "default_test", cfg.ServiceConfig.VgroupMapping["default_tx_group"]) + assert.Equal(t, "127.0.0.1:8092", cfg.ServiceConfig.Grouplist["default"]) + // reset flag.CommandLine flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) } diff --git a/pkg/tm/config.go b/pkg/tm/config.go index b940910c..6e69fe61 100644 --- a/pkg/tm/config.go +++ b/pkg/tm/config.go @@ -19,6 +19,7 @@ package tm import ( "flag" + "github.com/seata/seata-go/pkg/util/flagext" "time" ) @@ -41,3 +42,17 @@ func (cfg *TmConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { f.DurationVar(&cfg.DegradeCheckAllowTimes, prefix+".degrade-check-allow-times", 10*time.Second, "The duration allowed for degrade checking.") f.IntVar(&cfg.InterceptorOrder, prefix+".interceptor-order", -2147482648, "The order of interceptor.") } + +type ServiceConfig struct { + VgroupMapping flagext.StringMap `yaml:"vgroup-mapping" json:"vgroup-mapping" koanf:"vgroup-mapping"` + Grouplist flagext.StringMap `yaml:"grouplist" json:"grouplist" koanf:"grouplist"` + EnableDegrade bool `yaml:"enable-degrade" json:"enable-degrade" koanf:"enable-degrade"` + DisableGlobalTransaction bool `yaml:"disable-global-transaction" json:"disable-global-transaction" koanf:"disable-global-transaction"` +} + +func (cfg *ServiceConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { + f.BoolVar(&cfg.EnableDegrade, prefix+".enable-degrade", false, "degrade current not support.") + f.BoolVar(&cfg.DisableGlobalTransaction, prefix+".disable-global-transaction", false, "disable globalTransaction.") + f.Var(&cfg.VgroupMapping, prefix+".vgroup-mapping", "The vgroup mapping.") + f.Var(&cfg.Grouplist, prefix+".grouplist", "The group list.") +} diff --git a/pkg/util/flagext/stringmap.go b/pkg/util/flagext/stringmap.go new file mode 100644 index 00000000..50791249 --- /dev/null +++ b/pkg/util/flagext/stringmap.go @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 flagext + +import ( + "encoding/json" +) + +// StringMap is a map of string that implements flag.Value +type StringMap map[string]string + +// String implements flag.Value +func (v StringMap) String() string { + data, err := json.Marshal(v) + if err != nil { + panic(err) + } + return string(data) +} + +// Set implements flag.Value +func (v *StringMap) Set(s string) error { + return json.Unmarshal([]byte(s), &v) +} diff --git a/pkg/util/flagext/stringmap_test.go b/pkg/util/flagext/stringmap_test.go new file mode 100644 index 00000000..5996be0c --- /dev/null +++ b/pkg/util/flagext/stringmap_test.go @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 flagext + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_StringMap(t *testing.T) { + type TestStruct struct { + Val StringMap `json:"val"` + } + + var testStruct TestStruct + s := `{"aaa":"bb"}` + assert.Nil(t, testStruct.Val.Set(s)) + assert.Equal(t, s, testStruct.Val.String()) + + expected := []byte(`{"val":{"aaa":"bb"}}`) + actual, err := json.Marshal(testStruct) + assert.Nil(t, err) + assert.Equal(t, expected, actual) + + var testStruct2 TestStruct + + err = json.Unmarshal(expected, &testStruct2) + assert.Nil(t, err) + assert.Equal(t, testStruct, testStruct2) + +}