aboutsummaryrefslogtreecommitdiff
path: root/weed/shell
diff options
context:
space:
mode:
Diffstat (limited to 'weed/shell')
-rw-r--r--weed/shell/command_s3_circuitbreaker.go58
-rw-r--r--weed/shell/command_s3_circuitbreaker_test.go145
2 files changed, 164 insertions, 39 deletions
diff --git a/weed/shell/command_s3_circuitbreaker.go b/weed/shell/command_s3_circuitbreaker.go
index f1a8b08bb..7d6eebf34 100644
--- a/weed/shell/command_s3_circuitbreaker.go
+++ b/weed/shell/command_s3_circuitbreaker.go
@@ -7,7 +7,7 @@ import (
"github.com/alecthomas/units"
"github.com/chrislusf/seaweedfs/weed/filer"
"github.com/chrislusf/seaweedfs/weed/pb/s3_pb"
- "github.com/chrislusf/seaweedfs/weed/s3api/s3_config"
+ "github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
"io"
"strconv"
"strings"
@@ -32,21 +32,29 @@ func (c *commandS3CircuitBreaker) Help() string {
return `configure and apply s3 circuit breaker options for each bucket
# examples
- # add
- s3.circuitBreaker -actions Read,Write -values 500,200 -global -enable -apply -type count
- s3.circuitBreaker -actions Write -values 200MiB -global -enable -apply -type bytes
- s3.circuitBreaker -actions Write -values 200MiB -bucket x,y,z -enable -apply -type bytes
-
- #delete
- s3.circuitBreaker -actions Write -bucket x,y,z -delete -apply -type bytes
- s3.circuitBreaker -actions Write -bucket x,y,z -delete -apply
- s3.circuitBreaker -actions Write -delete -apply
+ # add circuit breaker config for global
+ s3.circuitBreaker -global -type count -actions Read,Write -values 500,200 -apply
+
+ # disable global config
+ s3.circuitBreaker -global -disable -apply
+
+ # add circuit breaker config for buckets x,y,z
+ s3.circuitBreaker -buckets x,y,z -type count -actions Read,Write -values 200,100 -apply
+
+ # disable circuit breaker config of x
+ s3.circuitBreaker -buckets x -disable -apply
+
+ # delete circuit breaker config of x
+ s3.circuitBreaker -buckets x -delete -apply
+
+ # clear all circuit breaker config
+ s3.circuitBreaker -delete -apply
`
}
func (c *commandS3CircuitBreaker) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
- dir := s3_config.CircuitBreakerConfigDir
- file := s3_config.CircuitBreakerConfigFile
+ dir := s3_constants.CircuitBreakerConfigDir
+ file := s3_constants.CircuitBreakerConfigFile
s3CircuitBreakerCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
buckets := s3CircuitBreakerCommand.String("buckets", "", "the bucket name(s) to configure, eg: -buckets x,y,z")
@@ -73,7 +81,7 @@ func (c *commandS3CircuitBreaker) Do(args []string, commandEnv *CommandEnv, writ
}
cbCfg := &s3_pb.S3CircuitBreakerConfig{
- Buckets: make(map[string]*s3_pb.CbOptions),
+ Buckets: make(map[string]*s3_pb.S3CircuitBreakerOptions),
}
if buf.Len() > 0 {
if err = filer.ParseS3ConfigurationFromBytes(buf.Bytes(), cbCfg); err != nil {
@@ -121,10 +129,10 @@ func (c *commandS3CircuitBreaker) Do(args []string, commandEnv *CommandEnv, writ
if len(*buckets) > 0 {
for _, bucket := range cmdBuckets {
- var cbOptions *s3_pb.CbOptions
+ var cbOptions *s3_pb.S3CircuitBreakerOptions
var exists bool
if cbOptions, exists = cbCfg.Buckets[bucket]; !exists {
- cbOptions = &s3_pb.CbOptions{}
+ cbOptions = &s3_pb.S3CircuitBreakerOptions{}
cbCfg.Buckets[bucket] = cbOptions
}
cbOptions.Enabled = !*disabled
@@ -145,7 +153,7 @@ func (c *commandS3CircuitBreaker) Do(args []string, commandEnv *CommandEnv, writ
if *global {
globalOptions := cbCfg.Global
if globalOptions == nil {
- globalOptions = &s3_pb.CbOptions{Actions: make(map[string]int64, len(cmdActions))}
+ globalOptions = &s3_pb.S3CircuitBreakerOptions{Actions: make(map[string]int64, len(cmdActions))}
cbCfg.Global = globalOptions
}
globalOptions.Enabled = !*disabled
@@ -192,7 +200,7 @@ func loadConfig(commandEnv *CommandEnv, dir string, file string, buf *bytes.Buff
return nil
}
-func insertOrUpdateValues(cbOptions *s3_pb.CbOptions, cmdActions []string, cmdValues []int64, limitType *string) error {
+func insertOrUpdateValues(cbOptions *s3_pb.S3CircuitBreakerOptions, cmdActions []string, cmdValues []int64, limitType *string) error {
if len(*limitType) == 0 {
return fmt.Errorf("type not valid, only 'count' and 'bytes' are allowed")
}
@@ -203,7 +211,7 @@ func insertOrUpdateValues(cbOptions *s3_pb.CbOptions, cmdActions []string, cmdVa
if len(cmdValues) > 0 {
for i, action := range cmdActions {
- cbOptions.Actions[s3_config.Concat(action, *limitType)] = cmdValues[i]
+ cbOptions.Actions[s3_constants.Concat(action, *limitType)] = cmdValues[i]
}
}
return nil
@@ -223,7 +231,7 @@ func deleteBucketsActions(cmdBuckets []string, cbCfg *s3_pb.S3CircuitBreakerConf
if cbOption, ok := cbCfg.Buckets[bucket]; ok {
if len(cmdActions) > 0 && cbOption.Actions != nil {
for _, action := range cmdActions {
- delete(cbOption.Actions, s3_config.Concat(action, *limitType))
+ delete(cbOption.Actions, s3_constants.Concat(action, *limitType))
}
}
@@ -250,7 +258,7 @@ func deleteGlobalActions(cbCfg *s3_pb.S3CircuitBreakerConfig, cmdActions []strin
return
} else {
for _, action := range cmdActions {
- delete(globalOptions.Actions, s3_config.Concat(action, *limitType))
+ delete(globalOptions.Actions, s3_constants.Concat(action, *limitType))
}
}
@@ -270,27 +278,27 @@ func (c *commandS3CircuitBreaker) initActionsAndValues(buckets, actions, limitTy
//check action valid
for _, action := range cmdActions {
var found bool
- for _, allowedAction := range s3_config.AllowedActions {
+ for _, allowedAction := range s3_constants.AllowedActions {
if allowedAction == action {
found = true
}
}
if !found {
- return nil, nil, nil, fmt.Errorf("value(%s) of flag[-action] not valid, allowed actions: %v", *actions, s3_config.AllowedActions)
+ return nil, nil, nil, fmt.Errorf("value(%s) of flag[-action] not valid, allowed actions: %v", *actions, s3_constants.AllowedActions)
}
}
}
if !parseValues {
if len(cmdActions) < 0 {
- for _, action := range s3_config.AllowedActions {
+ for _, action := range s3_constants.AllowedActions {
cmdActions = append(cmdActions, action)
}
}
if len(*limitType) > 0 {
switch *limitType {
- case s3_config.LimitTypeCount:
+ case s3_constants.LimitTypeCount:
elements := strings.Split(*values, ",")
if len(cmdActions) != len(elements) {
if len(elements) != 1 || len(elements) == 0 {
@@ -312,7 +320,7 @@ func (c *commandS3CircuitBreaker) initActionsAndValues(buckets, actions, limitTy
cmdValues = append(cmdValues, int64(v))
}
}
- case s3_config.LimitTypeBytes:
+ case s3_constants.LimitTypeBytes:
elements := strings.Split(*values, ",")
if len(cmdActions) != len(elements) {
if len(elements) != 1 || len(elements) == 0 {
diff --git a/weed/shell/command_s3_circuitbreaker_test.go b/weed/shell/command_s3_circuitbreaker_test.go
index 214256b5c..191a62e6a 100644
--- a/weed/shell/command_s3_circuitbreaker_test.go
+++ b/weed/shell/command_s3_circuitbreaker_test.go
@@ -2,6 +2,8 @@ package shell
import (
"bytes"
+ "encoding/json"
+ "reflect"
"strings"
"testing"
)
@@ -15,33 +17,137 @@ var (
TestCases = []*Case{
//add circuit breaker config for global
{
- args: strings.Split("-global -type count -actions Read,Write -values 500,200", " "),
- result: "{\n \"global\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"500\",\n \"Write:count\": \"200\"\n }\n }\n}\n",
+ args: strings.Split("-global -type count -actions Read,Write -values 500,200", " "),
+ result: `{
+ "global": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "500",
+ "Write:count": "200"
+ }
+ }
+ }`,
},
+
//disable global config
{
- args: strings.Split("-global -disable", " "),
- result: "{\n \"global\": {\n \"actions\": {\n \"Read:count\": \"500\",\n \"Write:count\": \"200\"\n }\n }\n}\n",
+ args: strings.Split("-global -disable", " "),
+ result: `{
+ "global": {
+ "actions": {
+ "Read:count": "500",
+ "Write:count": "200"
+ }
+ }
+ }`,
},
+
//add circuit breaker config for buckets x,y,z
{
- args: strings.Split("-buckets x,y,z -type count -actions Read,Write -values 200,100", " "),
- result: "{\n \"global\": {\n \"actions\": {\n \"Read:count\": \"500\",\n \"Write:count\": \"200\"\n }\n },\n \"buckets\": {\n \"x\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n },\n \"y\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n },\n \"z\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n }\n }\n}\n",
+ args: strings.Split("-buckets x,y,z -type count -actions Read,Write -values 200,100", " "),
+ result: `{
+ "global": {
+ "actions": {
+ "Read:count": "500",
+ "Write:count": "200"
+ }
+ },
+ "buckets": {
+ "x": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ },
+ "y": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ },
+ "z": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ }
+ }
+ }`,
},
+
//disable circuit breaker config of x
{
- args: strings.Split("-buckets x -disable", " "),
- result: "{\n \"global\": {\n \"actions\": {\n \"Read:count\": \"500\",\n \"Write:count\": \"200\"\n }\n },\n \"buckets\": {\n \"x\": {\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n },\n \"y\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n },\n \"z\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n }\n }\n}\n",
+ args: strings.Split("-buckets x -disable", " "),
+ result: `{
+ "global": {
+ "actions": {
+ "Read:count": "500",
+ "Write:count": "200"
+ }
+ },
+ "buckets": {
+ "x": {
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ },
+ "y": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ },
+ "z": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ }
+ }
+ }`,
},
+
//delete circuit breaker config of x
{
- args: strings.Split("-buckets x -delete", " "),
- result: "{\n \"global\": {\n \"actions\": {\n \"Read:count\": \"500\",\n \"Write:count\": \"200\"\n }\n },\n \"buckets\": {\n \"y\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n },\n \"z\": {\n \"enabled\": true,\n \"actions\": {\n \"Read:count\": \"200\",\n \"Write:count\": \"100\"\n }\n }\n }\n}\n",
+ args: strings.Split("-buckets x -delete", " "),
+ result: `{
+ "global": {
+ "actions": {
+ "Read:count": "500",
+ "Write:count": "200"
+ }
+ },
+ "buckets": {
+ "y": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ },
+ "z": {
+ "enabled": true,
+ "actions": {
+ "Read:count": "200",
+ "Write:count": "100"
+ }
+ }
+ }
+ }`,
},
+
//clear all circuit breaker config
{
- args: strings.Split("-delete", " "),
- result: "{\n\n}\n",
+ args: strings.Split("-delete", " "),
+ result: `{
+
+ }`,
},
}
)
@@ -65,10 +171,21 @@ func TestCircuitBreakerShell(t *testing.T) {
}
if i != 0 {
result := writeBuf.String()
- if result != tc.result {
- t.Fatal("result of s3 circuit breaker shell command is unexpect!")
+
+ actual := make(map[string]interface{})
+ err := json.Unmarshal([]byte(result), &actual)
+ if err != nil {
+ t.Error(err)
}
+ expect := make(map[string]interface{})
+ err = json.Unmarshal([]byte(result), &expect)
+ if err != nil {
+ t.Error(err)
+ }
+ if !reflect.DeepEqual(actual, expect) {
+ t.Fatal("result of s3 circuit breaker shell command is unexpect!")
+ }
}
}
}