Selaa lähdekoodia

Merge pull request #231 from emqx/rest

feat(rules): show rules return brief status
jinfahua 5 vuotta sitten
vanhempi
commit
59ef16218a

+ 12 - 5
docs/en_US/cli/rules.md

@@ -51,7 +51,7 @@ Below is the contents of ``rule.txt``.
 
 ## show rules
 
-The command is used for displaying all of rules defined in the server.
+The command is used for displaying all of rules defined in the server with a brief status.
 
 ```shell
 show rules
@@ -61,8 +61,16 @@ Sample:
 
 ```shell
 # bin/cli show rules
-rule1
-rule2
+[
+  {
+    "id": "rule1",
+    "status": "Running"
+  },
+  {
+     "id": "rule2",
+     "status": "Stopped: canceled by error."
+  }
+]
 ```
 
 ## describe a rule
@@ -156,7 +164,7 @@ Rule rule1 was restarted.
 ## get the status of a rule
 
 The command is used to get the status of the rule. If the rule is running, the metrics will be retrieved realtime. The status can be
-- running with metrics: $metrics
+- $metrics
 - stopped: $reason
 
 ```shell
@@ -167,7 +175,6 @@ Sample:
 
 ```shell
 # bin/cli getstatus rule rule1
-running with metrics:
 {
     "source_demo_0_records_in_total":5,
     "source_demo_0_records_out_total":5,

+ 12 - 4
docs/en_US/restapi/rules.md

@@ -23,7 +23,7 @@ Request Sample
 
 ## show rules
 
-The API is used for displaying all of rules defined in the server.
+The API is used for displaying all of rules defined in the server with a brief status.
 
 ```shell
 GET http://localhost:9081/rules
@@ -32,7 +32,16 @@ GET http://localhost:9081/rules
 Response Sample:
 
 ```json
-["rule1","rule2"]
+[
+  {
+    "id": "rule1",
+    "status": "Running"
+  },
+  {
+     "id": "rule2",
+     "status": "Stopped: canceled by error."
+  }
+]
 ```
 
 ## describe a rule
@@ -101,7 +110,7 @@ POST http://localhost:8080/rules/{id}/restart
 ## get the status of a rule
 
 The command is used to get the status of the rule. If the rule is running, the metrics will be retrieved realtime. The status can be
-- running with metrics: $metrics
+- $metrics
 - stopped: $reason
 
 ```shell
@@ -111,7 +120,6 @@ GET http://localhost:8080/rules/{id}/status
 Response Sample:
 
 ```shell
-running with metrics:
 {
     "source_demo_0_records_in_total":5,
     "source_demo_0_records_out_total":5,

+ 11 - 4
docs/zh_CN/cli/rules.md

@@ -51,7 +51,7 @@ create rule $rule_name $rule_json | create rule $rule_name -f $rule_def_file
 
 ## 展示规则
 
-该命令用于显示服务器中定义的所有规则。
+该命令用于显示服务器中定义的所有规则,包括规则id和当前状态
 
 ```shell
 show rules
@@ -61,8 +61,16 @@ show rules
 
 ```shell
 # bin/cli show rules
-rule1
-rule2
+[
+  {
+    "id": "rule1",
+    "status": "Running"
+  },
+  {
+     "id": "rule2",
+     "status": "Stopped: canceled by error."
+  }
+]
 ```
 
 ## 描述规则
@@ -167,7 +175,6 @@ getstatus rule $rule_name
 
 ```shell
 # bin/cli getstatus rule rule1
-running with metrics:
 {
     "source_demo_0_records_in_total":5,
     "source_demo_0_records_out_total":5,

+ 1 - 1
fvt_scripts/rule_test.jmx

@@ -174,7 +174,7 @@
           </HTTPSamplerProxy>
           <hashTree>
             <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
-              <stringProp name="JSON_PATH">$[0]</stringProp>
+              <stringProp name="JSON_PATH">$[0].id</stringProp>
               <stringProp name="EXPECTED_VALUE">rule1</stringProp>
               <boolProp name="JSONVALIDATION">false</boolProp>
               <boolProp name="EXPECT_NULL">false</boolProp>

+ 0 - 15
xsql/processors/xsql_processor.go

@@ -317,21 +317,6 @@ func (p *RuleProcessor) ExecDesc(name string) (string, error) {
 	return fmt.Sprintln(dst.String()), nil
 }
 
-func (p *RuleProcessor) ExecShow() (string, error) {
-	keys, err := p.GetAllRules()
-	if err != nil {
-		return "", err
-	}
-	if len(keys) == 0 {
-		keys = append(keys, "No rule definitions are found.")
-	}
-	var result string
-	for _, c := range keys {
-		result = result + fmt.Sprintln(c)
-	}
-	return result, nil
-}
-
 func (p *RuleProcessor) GetAllRules() ([]string, error) {
 	err := p.db.Open()
 	if err != nil {

+ 1 - 1
xstream/server/server/rest.go

@@ -176,7 +176,7 @@ func rulesHandler(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusCreated)
 		w.Write([]byte(result))
 	case http.MethodGet:
-		content, err := ruleProcessor.GetAllRules()
+		content, err := getAllRulesWithStatus()
 		if err != nil {
 			handleError(w, fmt.Errorf("Show rules error: %s", err), http.StatusBadRequest, logger)
 			return

+ 13 - 2
xstream/server/server/rpc.go

@@ -137,11 +137,22 @@ func (t *Server) DescRule(name string, reply *string) error {
 }
 
 func (t *Server) ShowRules(_ int, reply *string) error {
-	r, err := ruleProcessor.ExecShow()
+	r, err := getAllRulesWithStatus()
 	if err != nil {
 		return fmt.Errorf("Show rule error : %s.", err)
+	}
+	if len(r) == 0 {
+		*reply = "No rule definitions are found."
 	} else {
-		*reply = r
+		result, err := json.Marshal(r)
+		if err != nil {
+			return fmt.Errorf("Show rule error : %s.", err)
+		}
+		dst := &bytes.Buffer{}
+		if err := json.Indent(dst, result, "", "  "); err != nil {
+			return fmt.Errorf("Show rule error : %s.", err)
+		}
+		*reply = dst.String()
 	}
 	return nil
 }

+ 72 - 34
xstream/server/server/ruleManager.go

@@ -69,45 +69,83 @@ func doStartRule(rs *RuleState) error {
 	return nil
 }
 
-func getRuleStatus(name string) (string, error) {
+func getAllRulesWithStatus() ([]map[string]interface{}, error) {
+	names, err := ruleProcessor.GetAllRules()
+	if err != nil {
+		return nil, err
+	}
+	result := make([]map[string]interface{}, len(names))
+	for i, name := range names {
+		s, err := getRuleState(name)
+		if err != nil {
+			return nil, err
+		}
+		result[i] = map[string]interface{}{
+			"id":     name,
+			"status": s,
+		}
+	}
+	return result, nil
+}
+
+func getRuleState(name string) (string, error) {
+	if rs, ok := registry.Load(name); ok {
+		return doGetRuleState(rs)
+	} else {
+		return "", fmt.Errorf("Rule %s is not found", name)
+	}
+}
+
+func doGetRuleState(rs *RuleState) (string, error) {
 	result := ""
+	if !rs.Triggered {
+		result = "Stopped: canceled manually."
+		return result, nil
+	}
+	c := (*rs.Topology).GetContext()
+	if c != nil {
+		err := c.Err()
+		switch err {
+		case nil:
+			result = "Running"
+		case context.Canceled:
+			result = "Stopped: canceled by error."
+		case context.DeadlineExceeded:
+			result = "Stopped: deadline exceed."
+		default:
+			result = fmt.Sprintf("Stopped: %v.", err)
+		}
+	} else {
+		result = "Stopped: no context found."
+	}
+	return result, nil
+}
+
+func getRuleStatus(name string) (string, error) {
 	if rs, ok := registry.Load(name); ok {
-		if !rs.Triggered {
-			result = "Stopped: canceled manually."
-			return result, nil
+		result, err := doGetRuleState(rs)
+		if err != nil {
+			return "", err
 		}
-		c := (*rs.Topology).GetContext()
-		if c != nil {
-			err := c.Err()
-			switch err {
-			case nil:
-				keys, values := (*rs.Topology).GetMetrics()
-				metrics := "{"
-				for i, key := range keys {
-					value := values[i]
-					switch value.(type) {
-					case string:
-						metrics += fmt.Sprintf("\"%s\":%q,", key, value)
-					default:
-						metrics += fmt.Sprintf("\"%s\":%v,", key, value)
-					}
-				}
-				metrics = metrics[:len(metrics)-1] + "}"
-				dst := &bytes.Buffer{}
-				if err = json.Indent(dst, []byte(metrics), "", "  "); err != nil {
-					result = metrics
-				} else {
-					result = dst.String()
+		if result == "Running" {
+			keys, values := (*rs.Topology).GetMetrics()
+			metrics := "{"
+			for i, key := range keys {
+				value := values[i]
+				switch value.(type) {
+				case string:
+					metrics += fmt.Sprintf("\"%s\":%q,", key, value)
+				default:
+					metrics += fmt.Sprintf("\"%s\":%v,", key, value)
 				}
-			case context.Canceled:
-				result = "Stopped: canceled by error."
-			case context.DeadlineExceeded:
-				result = "Stopped: deadline exceed."
-			default:
-				result = fmt.Sprintf("Stopped: %v.", err)
 			}
-		} else {
-			result = "Stopped: no context found."
+			metrics = metrics[:len(metrics)-1] + "}"
+			dst := &bytes.Buffer{}
+			if err = json.Indent(dst, []byte(metrics), "", "  "); err != nil {
+				result = metrics
+			} else {
+				result = dst.String()
+			}
 		}
 		return result, nil
 	} else {