规则链

This commit is contained in:
XM-GO
2023-04-18 16:29:26 +08:00
parent db5a45590a
commit 5dfa341083
46 changed files with 980 additions and 381 deletions

View File

@@ -1,10 +1,8 @@
package nodes
import (
"pandax/pkg/rule_engine/message"
"time"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
)
const ClearAlarmNodeName = "ClearAlarmNode"
@@ -13,17 +11,13 @@ type clearAlarmNodeFactory struct{}
type clearAlarmNode struct {
bareNode
DetailBuilderScript string `json:"detailBuilderScript" yaml:"detailBuilderScript"`
AlarmType string `json:"alarmType" yaml:"alarmType"`
AlarmSeverity string `json:"alarmSeverity" yaml:"alarmSeverity"`
Propagate string `json:"propagate" yaml:"propagate"`
AlarmStartTime *time.Time `json:"alarmStartTime" yaml:"alarmStartTime"`
AlarmEndTime *time.Time `json:"alarmEndTime" yaml:"alarmEndTime"`
Script string `json:"script" yaml:"script"`
AlarmType string `json:"alarmType" yaml:"alarmType"`
}
func (f clearAlarmNodeFactory) Name() string { return ClearAlarmNodeName }
func (f clearAlarmNodeFactory) Category() string { return NODE_CATEGORY_ACTION }
func (f clearAlarmNodeFactory) Labels() []string { return []string{"Created", "Updated", "Failure"} }
func (f clearAlarmNodeFactory) Labels() []string { return []string{"Cleared", "Failure"} }
func (f clearAlarmNodeFactory) Create(id string, meta Metadata) (Node, error) {
node := &clearAlarmNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
@@ -33,5 +27,16 @@ func (f clearAlarmNodeFactory) Create(id string, meta Metadata) (Node, error) {
func (n *clearAlarmNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
cleared := n.GetLinkedNode("Cleared")
failure := n.GetLinkedNode("Failure")
scriptEngine := NewScriptEngine(msg, "Details", n.Script)
details, err := scriptEngine.ScriptAlarmDetails()
if err != nil {
return failure.Handle(msg)
}
// TODO 编写创建告警信息
logrus.Info(details)
cleared.Handle(msg)
return nil
}

View File

@@ -1,20 +1,18 @@
package nodes
import (
"fmt"
"pandax/pkg/rule_engine/message"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
)
type createAlarmNode struct {
bareNode
DetailBuilderScript string `json:"detailBuilderScript" yaml:"detailBuilderScript"`
AlarmType string `json:"alarmType" yaml:"alarmType"`
AlarmSeverity string `json:"alarmSeverity" yaml:"alarmSeverity"`
Propagate string `json:"propagate" yaml:"propagate"`
AlarmStartTime string `json:"alarmStartTime" yaml:"alarmStartTime"`
AlarmEndTime string `json:"alarmEndTime" yaml:"alarmEndTime"`
Script string `json:"script" yaml:"script"`
AlarmType string `json:"alarmType" yaml:"alarmType"`
AlarmSeverity int64 `json:"alarmSeverity" yaml:"alarmSeverity"`
Propagate string `json:"propagate" yaml:"propagate"`
/* AlarmStartTime string `json:"alarmStartTime" yaml:"alarmStartTime"`
AlarmEndTime string `json:"alarmEndTime" yaml:"alarmEndTime"`*/
}
type createAlarmNodeFactory struct{}
@@ -33,11 +31,19 @@ func (n *createAlarmNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
node1 := n.GetLinkedNode("Created")
node2 := n.GetLinkedNode("Updated")
//node2 := n.GetLinkedNode("Updated")
node3 := n.GetLinkedNode("Failure")
if node1 == nil || node2 == nil || node3 == nil {
return fmt.Errorf("no valid label linked node in %s", n.Name())
scriptEngine := NewScriptEngine(msg, "Details", n.Script)
details, err := scriptEngine.ScriptAlarmDetails()
if err != nil {
if node3 != nil {
return node3.Handle(msg)
}
}
// TODO 创建告警
logrus.Info(details)
node1.Handle(msg)
return nil
}

View File

@@ -13,8 +13,8 @@ const DelayNodeName = "DelayNode"
type delayNode struct {
bareNode
PeriodTs int `json:"periodTs" yaml:"periodTs" jpath:"periodTs"`
MaxPendingMessages int `json:"maxPendingMessages" yaml:"maxPendingMessages" jpath:"maxPendingMessages"`
PeriodTs int `json:"periodTs" yaml:"periodTs" jpath:"periodTs"` //周期时间
MaxPendingMessages int `json:"maxPendingMessages" yaml:"maxPendingMessages" jpath:"maxPendingMessages"` //最大等待消息数
messageQueue []message.Message `jpath:"-"`
delayTimer *time.Timer `jpath:"-"`
lock sync.Mutex `jpath:"-"`
@@ -48,7 +48,7 @@ func (n *delayNode) Handle(msg message.Message) error {
if n.delayTimer == nil {
n.messageQueue = append(n.messageQueue, msg)
n.delayTimer = time.NewTimer(time.Duration(n.PeriodTs) * time.Second)
// start timecallback goroutine
go func(n *delayNode) error {
defer n.delayTimer.Stop()
for {
@@ -64,7 +64,6 @@ func (n *delayNode) Handle(msg message.Message) error {
}(n)
return nil
}
// the delay timer had already been created, just queue message
n.lock.Lock()
defer n.lock.Unlock()
if len(n.messageQueue) == n.MaxPendingMessages {

View File

@@ -1,22 +1,23 @@
package nodes
import (
"fmt"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
"time"
)
type messageGeneratorNode struct {
bareNode
DetailBuilderScript string `json:"detail_builder_script" yaml:"detail_builder_script"`
FrequenceInSecond int32 `json:"frequency" yaml:"frequency"`
Script string `json:"script" yaml:"script"`
PeriodSecond int64 `json:"periodSecond" yaml:"periodSecond"` //周期
MessageCount int64 `json:"messageCount" yaml:"messageCount"`
}
type messageGeneratorNodeFactory struct{}
func (f messageGeneratorNodeFactory) Name() string { return "GeneratorNode" }
func (f messageGeneratorNodeFactory) Name() string { return "MessageGeneratorNode" }
func (f messageGeneratorNodeFactory) Category() string { return NODE_CATEGORY_ACTION }
func (f messageGeneratorNodeFactory) Labels() []string { return []string{"Created", "Updated"} }
func (f messageGeneratorNodeFactory) Labels() []string { return []string{"Success", "Failure"} }
func (f messageGeneratorNodeFactory) Create(id string, meta Metadata) (Node, error) {
node := &messageGeneratorNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
@@ -27,11 +28,36 @@ func (f messageGeneratorNodeFactory) Create(id string, meta Metadata) (Node, err
func (n *messageGeneratorNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
createdLabelNode := n.GetLinkedNode("Created")
updatedLabelNode := n.GetLinkedNode("Updated")
if createdLabelNode == nil || updatedLabelNode == nil {
return fmt.Errorf("no valid label linked node in %s", n.Name())
}
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
ticker := time.NewTicker(time.Duration(n.PeriodSecond) * time.Second)
count := 0
go func() {
for {
<-ticker.C
count++
if int64(count) == n.MessageCount {
ticker.Stop()
return
}
scriptEngine := NewScriptEngine(msg, "Generate", n.Script)
generate, err := scriptEngine.ScriptGenerate()
if err != nil {
if failureLabelNode != nil {
go failureLabelNode.Handle(msg)
}
return
}
msg.SetMsg(generate["msg"].(map[string]interface{}))
msg.SetType(generate["msgType"].(string))
msg.SetMetadata(message.NewDefaultMetadata(generate["metadata"].(map[string]interface{})))
if successLabelNode != nil {
go successLabelNode.Handle(msg)
}
}
}()
return nil
}

View File

@@ -1,8 +1,8 @@
package nodes
import (
"fmt"
"log"
"pandax/apps/visual/entity"
"pandax/apps/visual/services"
"pandax/pkg/rule_engine/message"
)
@@ -27,15 +27,31 @@ func (n *logNode) Handle(msg message.Message) error {
successLableNode := n.GetLinkedNode("Success")
failureLableNode := n.GetLinkedNode("Failure")
scriptEngine := NewScriptEngine()
logMessage, err := scriptEngine.ScriptToString(msg, n.Script)
if successLableNode == nil || failureLableNode == nil {
return fmt.Errorf("no valid label linked node in %s", n.Name())
}
scriptEngine := NewScriptEngine(msg, "ToString", n.Script)
logMessage, err := scriptEngine.ScriptToString()
if err != nil {
return failureLableNode.Handle(msg)
if failureLableNode != nil {
return failureLableNode.Handle(msg)
} else {
return err
}
}
log.Println(logMessage)
return successLableNode.Handle(msg)
services.VisualRuleChainMsgLogModelDao.Insert(entity.VisualRuleChainMsgLog{
MessageId: msg.GetId(),
MsgType: msg.GetType(),
DeviceName: msg.GetMetadata().GetValues()["deviceName"].(string),
Ts: msg.GetTs(),
Content: logMessage,
})
if err != nil {
if failureLableNode != nil {
return failureLableNode.Handle(msg)
} else {
return err
}
}
if successLableNode != nil {
return successLableNode.Handle(msg)
}
return nil
}

View File

@@ -1,29 +0,0 @@
package nodes
import (
"log"
"pandax/pkg/rule_engine/message"
)
type MyNode struct {
bareNode
}
type myNodeFactory struct{}
func (f myNodeFactory) Name() string { return "MyNode" }
func (f myNodeFactory) Category() string { return NODE_CATEGORY_ACTION }
func (f myNodeFactory) Labels() []string { return []string{"Next", "Next2"} }
func (f myNodeFactory) Create(id string, meta Metadata) (Node, error) {
node := &MyNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
}
return decodePath(meta, node)
}
func (n *MyNode) Handle(msg message.Message) error {
nextLableNode := n.GetLinkedNode("Next")
log.Println(nextLableNode.Name())
return nil
}

View File

@@ -1,7 +1,6 @@
package nodes
import (
"fmt"
"pandax/pkg/rule_engine/message"
)
@@ -22,13 +21,33 @@ func (f saveAttributesNodeFactory) Create(id string, meta Metadata) (Node, error
}
func (n *SaveAttributesNode) Handle(msg message.Message) error {
successLableNode := n.GetLinkedNode("Success")
failureLableNode := n.GetLinkedNode("Failure")
if successLableNode == nil || failureLableNode == nil {
return fmt.Errorf("no valid label linked node in %s", n.Name())
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
if msg.GetType() != message.EventAttributesType {
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return nil
}
}
if msg.GetType() != "POST_ATTRIBUTES_REQUEST" {
return failureLableNode.Handle(msg)
//deviceName := msg.GetMetadata().GetValues()["deviceName"].(string)
//namespace := msg.GetMetadata().GetValues()["namespace"].(string)
//marshal, err := json.Marshal(msg.GetMsg())
//if err != nil {
// if failureLabelNode != nil {
// return failureLabelNode.Handle(msg)
// } else {
// return nil
// }
//}
// todo 添加设备上报参数
if successLabelNode != nil {
return successLabelNode.Handle(msg)
} else {
return nil
}
return nil

View File

@@ -19,7 +19,24 @@ func (f saveTimeSeriesNodeFactory) Create(id string, meta Metadata) (Node, error
func (n *SaveTimeSeriesNode) Handle(msg message.Message) error {
successLableNode := n.GetLinkedNode("Success")
//failureLableNode := n.GetLinkedNode("Failure")
failureLableNode := n.GetLinkedNode("Failure")
if msg.GetType() != message.EventTelemetryType {
if failureLableNode != nil {
return failureLableNode.Handle(msg)
} else {
return nil
}
}
/*deviceName := msg.GetMetadata().GetValues()["deviceName"].(string)
namespace := msg.GetMetadata().GetValues()["namespace"].(string)
marshal, err := json.Marshal(msg.GetMsg())*/
// todo 添加设备上报遥测
if successLableNode != nil {
return successLableNode.Handle(msg)
} else {
return nil
}
return successLableNode.Handle(msg)
}

View File

@@ -1,17 +1,26 @@
package nodes
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/XM-GO/PandaKit/httpclient"
"github.com/sirupsen/logrus"
"net/url"
"pandax/pkg/rule_engine/message"
"time"
)
type externalDingNode struct {
bareNode
WebHook string `json:"webHook" yaml:"webHook"`
Secret string `json:"secret"`
MsgType string `json:"msgType" yaml:"msgType"`
Content string `json:"content" yaml:"content"`
IsAtAll bool `json:"isAtAll" yaml:"isAtAll"`
atMobiles []string `json:"atMobiles" yaml:"atMobiles"`
AtMobiles []string `json:"atMobiles" yaml:"atMobiles"`
}
type externalDingNodeFactory struct{}
@@ -29,5 +38,47 @@ func (f externalDingNodeFactory) Create(id string, meta Metadata) (Node, error)
func (n *externalDingNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
//获取消息
template, err := ParseTemplate(n.Content, msg.GetAllMap())
if err != nil {
return err
}
sendData := map[string]interface{}{
"msgtype": "text",
"text": map[string]string{"content": template},
}
if n.IsAtAll {
sendData["at"] = map[string]interface{}{"isAtAll": n.IsAtAll}
} else {
sendData["at"] = map[string]interface{}{"atMobiles": n.AtMobiles}
}
marshal, _ := json.Marshal(sendData)
timestamp := time.Now().UnixMilli()
sign := getSign(timestamp, n.Secret)
url := fmt.Sprintf("%s&timestamp=%d&sign=%s", n.WebHook, timestamp, sign)
postJson := httpclient.NewRequest(url).Header("Content-Type", "application/json").PostJson(string(marshal))
if postJson.StatusCode != 200 {
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return err
}
}
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}
func getSign(timestamp int64, secret string) string {
stringToSign := fmt.Sprintf("%d\n%s", timestamp, secret)
hash := hmac.New(sha256.New, []byte(secret))
hash.Write([]byte(stringToSign))
signData := hash.Sum(nil)
return url.QueryEscape(base64.StdEncoding.EncodeToString(signData))
}

View File

@@ -1,15 +1,22 @@
package nodes
import (
"encoding/json"
"github.com/Shopify/sarama"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
"strings"
"time"
)
type externalKafkaNode struct {
bareNode
Server string `json:"server" yaml:"server"`
Topic string `json:"topic" yaml:"topic"`
KafkaCli string
Server string `json:"server" yaml:"server"` //kafka集群 "10.130.138.164:9092,10.130.138.165:9093"
Topic string `json:"topic" yaml:"topic"` //topic
KeyPattern string `json:"keyPattern" yaml:"keyPattern"` //metadataKey or messageKey
ProducesBatchSize int64 `json:"producesBatchSize" yaml:"producesBatchSize"`
OtherProperties map[string]interface{} `json:"otherProperties"` //发送的其他参数
KafkaCli sarama.SyncProducer
}
type externalKafkaNodeFactory struct{}
@@ -21,11 +28,58 @@ func (f externalKafkaNodeFactory) Create(id string, meta Metadata) (Node, error)
node := &externalKafkaNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
}
return decodePath(meta, node)
_, err := decodePath(meta, node)
if err != nil {
return node, err
}
config := sarama.NewConfig()
config.Producer.Return.Successes = true
config.Producer.Timeout = 5 * time.Second
config.Producer.MaxMessageBytes = int(node.ProducesBatchSize)
p, err := sarama.NewSyncProducer(strings.Split(node.Server, ","), config)
if err != nil {
logrus.Errorf("sarama.NewSyncProducer err, message=%s \n", err)
return node, err
}
node.KafkaCli = p
return node, nil
}
func (n *externalKafkaNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
defer n.KafkaCli.Close()
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
value := sarama.ByteEncoder("")
if n.KeyPattern == "metadataKey" {
marshal, err := json.Marshal(msg.GetMetadata().GetValues())
if err != nil {
return err
}
value = marshal
} else {
marshal, err := json.Marshal(msg.GetMsg())
if err != nil {
return err
}
value = marshal
}
kafkaM := &sarama.ProducerMessage{
Topic: n.Topic,
Value: value,
}
_, _, err := n.KafkaCli.SendMessage(kafkaM)
if err != nil {
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return err
}
}
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}

View File

@@ -13,6 +13,8 @@ import (
type externalMqttNode struct {
bareNode
TopicPattern string `json:"topicPattern"`
Username string `json:"username"`
Password string `json:"password"`
Host string `json:"host"`
Port string `json:"port"`
ConnectTimeoutSec int `json:"connectTimeoutSec"`
@@ -28,38 +30,55 @@ func (f externalMqttNodeFactory) Name() string { return "MqttNode" }
func (f externalMqttNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL }
func (f externalMqttNodeFactory) Labels() []string { return []string{"Success", "Failure"} }
func (f externalMqttNodeFactory) Create(id string, meta Metadata) (Node, error) {
node := &externalMqttNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
}
_, err := decodePath(meta, node)
if err != nil {
return node, err
}
broker := fmt.Sprintf("tcp://%s:%s", node.Host, node.Port)
opts := mqtt.NewClientOptions().AddBroker(broker)
opts.SetClientID(node.ClientId)
if node.ClientId != "" {
opts.SetClientID(node.ClientId)
}
opts.SetCleanSession(node.CleanSession)
opts.SetConnectTimeout(time.Duration(node.ConnectTimeoutSec) * time.Second)
if node.Username != "" {
opts.SetUsername(node.Username)
}
if node.Password != "" {
opts.SetPassword(node.Password)
}
node.MqttCli = mqtt.NewClient(opts)
if token := node.MqttCli.Connect(); token.Wait() && token.Error() != nil {
logrus.WithError(token.Error())
return nil, token.Error()
}
return decodePath(meta, node)
return node, nil
}
func (n *externalMqttNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
defer n.MqttCli.Disconnect(1000)
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
topic := n.TopicPattern //need fix add msg.metadata in it
sendmqttmsg, err := json.Marshal(msg.GetMsg())
if err != nil {
return nil
return err
}
token := n.MqttCli.Publish(topic, 1, false, sendmqttmsg)
if token.Wait() && token.Error() != nil {
fmt.Println(token.Error())
return failureLabelNode.Handle(msg)
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return token.Error()
}
}
return successLabelNode.Handle(msg)
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}

View File

@@ -37,12 +37,23 @@ func (f externalNatsNodeFactory) Create(id string, meta Metadata) (Node, error)
func (n *externalNatsNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
defer n.client.Close()
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
err := n.client.Publish(n.Subject, []byte(n.Body))
template, err := ParseTemplate(n.Body, msg.GetAllMap())
if err != nil {
n.client.Close()
return failureLabelNode.Handle(msg)
return err
}
return successLabelNode.Handle(msg)
err = n.client.Publish(n.Subject, []byte(template))
if err != nil {
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return err
}
}
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}

View File

@@ -1,6 +1,9 @@
package nodes
import (
"encoding/json"
"errors"
"github.com/XM-GO/PandaKit/httpclient"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
)
@@ -9,7 +12,7 @@ type externalRestapiNode struct {
bareNode
RestEndpointUrlPattern string `json:"restEndpointUrlPattern" yaml:"restEndpointUrlPattern"`
RequestMethod string `json:"requestMethod" yaml:"requestMethod"`
headers map[string]string `json:"headers" yaml:"headers"`
Headers map[string]string `json:"headers" yaml:"headers"`
}
type externalRestapiNodeFactory struct{}
@@ -26,6 +29,73 @@ func (f externalRestapiNodeFactory) Create(id string, meta Metadata) (Node, erro
func (n *externalRestapiNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
successLableNode := n.GetLinkedNode("Success")
failureLableNode := n.GetLinkedNode("Failure")
if n.RequestMethod == "GET" {
resp := httpclient.NewRequest(n.RestEndpointUrlPattern).Get()
if resp.StatusCode != 200 {
return errors.New("网络请求失败")
}
var response map[string]interface{}
err := json.Unmarshal(resp.Body, &response)
if err != nil && failureLableNode != nil {
return failureLableNode.Handle(msg)
} else {
if successLableNode != nil {
metadata := msg.GetMetadata()
for key, value := range response {
metadata.SetKeyValue(key, value)
}
msg.SetMetadata(metadata)
return successLableNode.Handle(msg)
}
}
}
if n.RequestMethod == "POST" {
binary, _ := msg.MarshalBinary()
req := httpclient.NewRequest(n.RestEndpointUrlPattern)
for key, value := range n.Headers {
req.Header(key, value)
}
resp := req.PostJson(string(binary))
if resp.StatusCode != 200 {
if failureLableNode != nil {
return failureLableNode.Handle(msg)
}
} else {
if successLableNode != nil {
return successLableNode.Handle(msg)
}
}
}
/*if n.RequestMethod == "PUT" {
binary, _ := msg.MarshalBinary()
req := httpclient.NewRequest(n.RestEndpointUrlPattern)
for key,value := range n.Headers {
req.Header(key,value)
}
_, err := http.HttpPut(n.RestEndpointUrlPattern, n.Headers, nil, binary)
if err != nil {
if failureLableNode != nil {
return failureLableNode.Handle(msg)
}
} else {
if successLableNode != nil {
return successLableNode.Handle(msg)
}
}
}
if n.RequestMethod == "DELETE" {
_, err := http.HttpDelete(n.RestEndpointUrlPattern)
if err != nil {
if failureLableNode != nil {
return failureLableNode.Handle(msg)
}
} else {
if successLableNode != nil {
return successLableNode.Handle(msg)
}
}
}*/
return nil
}

View File

@@ -1,8 +1,13 @@
package nodes
import (
"github.com/sirupsen/logrus"
"pandax/apps/visual/services"
"pandax/pkg/rule_engine/manifest"
"pandax/pkg/rule_engine/message"
"errors"
"fmt"
"github.com/sirupsen/logrus"
)
type externalRuleChainNode struct {
@@ -13,13 +18,11 @@ type externalRuleChainNode struct {
type externalRuleChainNodeFactory struct{}
func (f externalRuleChainNodeFactory) Name() string { return "RuleChainNode" }
func (f externalRuleChainNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL }
func (f externalRuleChainNodeFactory) Labels() []string { return []string{"Success", "Failure"} }
func (f externalRuleChainNodeFactory) Category() string { return NODE_CATEGORY_FLOWS }
func (f externalRuleChainNodeFactory) Labels() []string { return []string{} }
func (f externalRuleChainNodeFactory) Create(id string, meta Metadata) (Node, error) {
labels := []string{"Success", "Failure"}
node := &externalRuleChainNode{
bareNode: newBareNode(f.Name(), id, meta, labels),
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
}
return decodePath(meta, node)
@@ -27,6 +30,21 @@ func (f externalRuleChainNodeFactory) Create(id string, meta Metadata) (Node, er
func (n *externalRuleChainNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
data := services.VisualRuleChainModelDao.FindOne(n.RuleId)
if data == nil {
return errors.New(fmt.Sprintf("节点 %s ,获取规则链失败", n.Name()))
}
m, err := manifest.New([]byte(data.RuleDataJson))
if err != nil {
logrus.WithError(err).Errorf("invalidi manifest file")
return err
}
nodes, err := GetNodes(m)
if err != nil {
return errors.New(fmt.Sprintf("节点 %s ,构建节点失败", n.Name()))
}
if node, found := nodes[m.FirstRuleNodeId]; found {
go node.Handle(msg)
}
return nil
}

View File

@@ -1,18 +1,28 @@
package nodes
import (
"crypto/tls"
"fmt"
"github.com/sirupsen/logrus"
"net/smtp"
"pandax/pkg/rule_engine/message"
"strings"
"github.com/jordan-wright/email"
)
type externalSendEmailNode struct {
bareNode
From string `json:"from" yaml:"from"`
To string `json:"to" yaml:"to"`
Cc string `json:"cc" yaml:"cc"`
Bcc string `json:"bcc" yaml:"bcc"`
Subject string `json:"subject" yaml:"subject"`
Body string `json:"body" yaml:"body"`
Host string `json:"host"` // 服务器地址
Port int `json:"port"` // 服务器端口
From string `json:"from"` // 邮箱账号
Nickname string `json:"nickname"` // 发件人
Secret string `json:"secret"` // 邮箱密码
IsSSL bool `json:"isSsl"` // 是否开启ssl
To string `json:"to"` //收件人
Subject string `json:"subject"` //主题
Body string `json:"body"` //内容
}
type externalSendEmailNodeFactory struct{}
@@ -21,10 +31,14 @@ func (f externalSendEmailNodeFactory) Name() string { return "SendEmailNode"
func (f externalSendEmailNodeFactory) Category() string { return NODE_CATEGORY_EXTERNAL }
func (f externalSendEmailNodeFactory) Labels() []string { return []string{"Success", "Failure"} }
func (f externalSendEmailNodeFactory) Create(id string, meta Metadata) (Node, error) {
labels := []string{"Success", "Failure"}
node := &externalSendEmailNode{
bareNode: newBareNode(f.Name(), id, meta, labels),
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
/*Host: email.Host,
Port: email.Port,
Nickname: email.Nickname,
Secret: email.Secret,
IsSSL: email.IsSSL,*/
}
return decodePath(meta, node)
}
@@ -33,19 +47,48 @@ func (n *externalSendEmailNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
successLabelNode := n.GetLinkedNode("Success")
//failureLabelNode := n.GetLinkedNode("Failure")
failureLabelNode := n.GetLinkedNode("Failure")
/*dialer := runtime.NewDialer(runtime.EMAIL)
variables := map[string]string{
"from": n.From,
"to": n.To,
"cc": n.Cc,
"bcc": n.Bcc,
"subject": n.Subject,
"body": n.Body,
tos := strings.Split(n.To, ",")
if tos[len(tos)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除
tos = tos[:len(tos)-1]
}
if err := dialer.DialAndSend(msg.GetMetadata(), variables); err != nil {
return failureLabelNode.Handle(msg)
}*/
return successLabelNode.Handle(msg)
err := n.send(tos, msg)
if err != nil {
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return err
}
}
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}
func (m *externalSendEmailNode) send(to []string, msg message.Message) error {
auth := smtp.PlainAuth("", m.From, m.Secret, m.Host)
e := email.NewEmail()
if m.Nickname != "" {
e.From = fmt.Sprintf("%s <%s>", m.Nickname, m.From)
} else {
e.From = m.From
}
e.To = to
e.Subject = m.Subject
template, err := ParseTemplate(m.Body, msg.GetMetadata().GetValues())
if err != nil {
return err
}
e.HTML = []byte(template)
hostAddr := fmt.Sprintf("%s:%d", m.Host, m.Port)
if m.IsSSL {
err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: m.Host})
} else {
err = e.Send(hostAddr, auth)
}
return err
}

View File

@@ -7,6 +7,12 @@ import (
type externalSendSmsNode struct {
bareNode
SecretId string `json:"secretId" yaml:"secretId"`
SecretKey string `json:"secretKey" yaml:"secretKey"`
SdkAppId string `json:"sdkAppId" yaml:"sdkAppId"` //应用Id腾讯 或 签名名称(阿里)
PhoneNumber string `json:"phoneNumber" yaml:"phoneNumber"` //发送到手机号
TemplateId string `json:"templateId" yaml:"templateId"` //短信模板Id
TemplateParam map[string]interface{} `json:"templateParam" yaml:"templateParam"` //模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空*/
}
type externalSendSmsNodeFactory struct{}

View File

@@ -1,6 +1,8 @@
package nodes
import (
"encoding/json"
"github.com/XM-GO/PandaKit/httpclient"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
)
@@ -11,7 +13,7 @@ type externalWechatNode struct {
MsgType string `json:"msgType" yaml:"msgType"`
Content string `json:"content" yaml:"content"`
IsAtAll bool `json:"isAtAll" yaml:"isAtAll"`
atMobiles []string `json:"atMobiles" yaml:"atMobiles"`
AtMobiles []string `json:"atMobiles" yaml:"atMobiles"`
}
type externalWechatNodeFactory struct{}
@@ -29,5 +31,29 @@ func (f externalWechatNodeFactory) Create(id string, meta Metadata) (Node, error
func (n *externalWechatNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
template, err := ParseTemplate(n.Content, msg.GetAllMap())
sendData := map[string]interface{}{
"msgtype": "text",
"text": map[string]interface{}{"content": template},
}
if n.IsAtAll {
sendData["text"].(map[string]interface{})["mentioned_mobile_list"] = []string{"@all"}
} else {
sendData["text"].(map[string]interface{})["mentioned_mobile_list"] = n.AtMobiles
}
marshal, _ := json.Marshal(sendData)
postJson := httpclient.NewRequest(n.WebHook).Header("Content-Type", "application/json").PostJson(string(marshal))
if postJson.StatusCode != 200 {
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return err
}
}
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}

View File

@@ -1,16 +1,10 @@
package nodes
import (
"fmt"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
)
const (
DEVICE = "DEVICE"
GATEWAY = "GATEWAY"
)
//检查关联关系
//该消息来自与哪个实体或到那个实体
type deviceTypeSwitchNode struct {
@@ -21,7 +15,9 @@ type deviceTypeSwitchNodeFactory struct{}
func (f deviceTypeSwitchNodeFactory) Name() string { return "DeviceTypeSwitchNode" }
func (f deviceTypeSwitchNodeFactory) Category() string { return NODE_CATEGORY_FILTER }
func (f deviceTypeSwitchNodeFactory) Labels() []string { return []string{DEVICE, GATEWAY} }
func (f deviceTypeSwitchNodeFactory) Labels() []string {
return []string{message.DEVICE, message.GATEWAY}
}
func (f deviceTypeSwitchNodeFactory) Create(id string, meta Metadata) (Node, error) {
node := &deviceTypeSwitchNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
@@ -32,15 +28,18 @@ func (f deviceTypeSwitchNodeFactory) Create(id string, meta Metadata) (Node, err
func (n *deviceTypeSwitchNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
deviceLabelNode := n.GetLinkedNode(DEVICE)
gatewayLabelNode := n.GetLinkedNode(GATEWAY)
deviceLabelNode := n.GetLinkedNode(message.DEVICE)
gatewayLabelNode := n.GetLinkedNode(message.GATEWAY)
if deviceLabelNode == nil && gatewayLabelNode == nil {
return fmt.Errorf("no device and gateway label linked node in %s", n.Name())
if msg.GetMetadata().GetKeyValue("deviceType") == message.DEVICE {
if deviceLabelNode != nil {
return deviceLabelNode.Handle(msg)
}
}
if msg.GetMetadata().GetKeyValue("deviceType") == DEVICE {
return deviceLabelNode.Handle(msg)
if msg.GetMetadata().GetKeyValue("deviceType") == message.GATEWAY {
if gatewayLabelNode != nil {
return gatewayLabelNode.Handle(msg)
}
}
return gatewayLabelNode.Handle(msg)
return nil
}

View File

@@ -2,7 +2,6 @@ package nodes
import (
"github.com/sirupsen/logrus"
"log"
"pandax/pkg/rule_engine/message"
)
@@ -36,7 +35,6 @@ func (n *messageTypeSwitchNode) Handle(msg message.Message) error {
nodes := n.GetLinkedNodes()
messageType := msg.GetType()
log.Println("开始执行messageTypeSwitchNode")
for label, node := range nodes {
if messageType == label {
return node.Handle(msg)

View File

@@ -2,7 +2,6 @@ package nodes
import (
"github.com/sirupsen/logrus"
"log"
"pandax/pkg/rule_engine/message"
)
@@ -30,9 +29,8 @@ func (n *scriptFilterNode) Handle(msg message.Message) error {
trueLabelNode := n.GetLinkedNode("True")
falseLabelNode := n.GetLinkedNode("False")
scriptEngine := NewScriptEngine()
isTrue, error := scriptEngine.ScriptOnFilter(msg, n.Script)
log.Println(isTrue)
scriptEngine := NewScriptEngine(msg, "Filter", n.Script)
isTrue, error := scriptEngine.ScriptOnFilter()
if isTrue == true && error == nil && trueLabelNode != nil {
return trueLabelNode.Handle(msg)
} else {
@@ -40,5 +38,6 @@ func (n *scriptFilterNode) Handle(msg message.Message) error {
return falseLabelNode.Handle(msg)
}
}
return nil
}

View File

@@ -2,7 +2,6 @@ package nodes
import (
"github.com/sirupsen/logrus"
"log"
"pandax/pkg/rule_engine/message"
)
@@ -36,17 +35,16 @@ func (f switchFilterNodeFactory) Create(id string, meta Metadata) (Node, error)
func (n *switchFilterNode) Handle(msg message.Message) error {
logrus.Infof("%s handle message '%s'", n.Name(), msg.GetType())
scriptEngine := NewScriptEngine()
SwitchResults, err := scriptEngine.ScriptOnSwitch(msg, n.Script)
log.Println("开始执行switchFilterNode", SwitchResults)
scriptEngine := NewScriptEngine(msg, "Switch", n.Script)
SwitchResults, err := scriptEngine.ScriptOnSwitch()
if err != nil {
return nil
return err
}
nodes := n.GetLinkedNodes()
for label, node := range nodes {
for _, switchresult := range SwitchResults {
if label == switchresult {
node.Handle(msg)
go node.Handle(msg)
}
}
}

View File

@@ -31,6 +31,4 @@ func init() {
RegisterFactory(externalSendSmsNodeFactory{})
RegisterFactory(externalRuleChainNodeFactory{})
RegisterFactory(myNodeFactory{})
}

View File

@@ -58,6 +58,6 @@ func (c *nodeMetadata) With(key string, val interface{}) Metadata {
}
func (c *nodeMetadata) DecodePath(rawVal interface{}) error {
//return tool.Map2Struct(c.keypairs, rawVal)
//return utils.Map2Struct(c.keypairs, rawVal)
return mapstructure.Decode(c.keypairs, rawVal)
}

View File

@@ -49,7 +49,6 @@ func (n *bareNode) GetLinkedNode(label string) Node {
if node, found := n.nodes[label]; found {
return node
}
logrus.Errorf("no label '%s' in node '%s'", label, n.name)
return nil
}
@@ -73,6 +72,7 @@ func GetNodes(m *manifest.Manifest) (map[string]Node, error) {
metadata := NewMetadataWithValues(n.Properties)
node, err := NewNode(n.Type, n.Id, metadata)
if err != nil {
logrus.Errorf("new node '%s' failure", n.Id)
continue
}
if _, found := nodes[n.Id]; found {

View File

@@ -1,36 +1,45 @@
package nodes
import (
"fmt"
"github.com/dop251/goja"
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
)
type ScriptEngine interface {
ScriptOnMessage(msg message.Message, script string) (message.Message, error)
//used by filter_switch_node
ScriptOnSwitch(msg message.Message, script string) ([]string, error)
//used by filter_script_node
ScriptOnFilter(msg message.Message, script string) (bool, error)
ScriptToString(msg message.Message, script string) (string, error)
ScriptOnMessage() (message.Message, error)
ScriptOnSwitch() ([]string, error)
ScriptOnFilter() (bool, error)
ScriptToString() (string, error)
ScriptAlarmDetails() (map[string]interface{}, error)
ScriptGenerate() (map[string]interface{}, error)
}
type baseScriptEngine struct {
Fun string
Script string
Msg message.Message
}
func NewScriptEngine() ScriptEngine {
return &baseScriptEngine{}
func NewScriptEngine(msg message.Message, fun string, script string) ScriptEngine {
return &baseScriptEngine{
Fun: fun,
Script: fmt.Sprintf("function %s(msg, metadata, msgType) { %s }", fun, script),
Msg: msg,
}
}
func (bse *baseScriptEngine) ScriptOnMessage(msg message.Message, script string) (message.Message, error) {
func (bse *baseScriptEngine) ScriptOnMessage() (message.Message, error) {
msg := bse.Msg
vm := goja.New()
_, err := vm.RunString(script)
_, err := vm.RunString(bse.Script)
if err != nil {
logrus.Info("JS代码有问题")
return nil, err
}
var fn func(map[string]interface{}, map[string]interface{}, string) map[string]interface{}
err = vm.ExportTo(vm.Get("Transform"), &fn)
err = vm.ExportTo(vm.Get(bse.Fun), &fn)
if err != nil {
logrus.Info("Js函数映射到 Go 函数失败!")
return nil, err
@@ -40,19 +49,18 @@ func (bse *baseScriptEngine) ScriptOnMessage(msg message.Message, script string)
msg.SetMetadata(message.NewDefaultMetadata(datas["metadata"].(map[string]interface{})))
msg.SetType(datas["msgType"].(string))
return msg, nil
return nil, nil
}
func (bse *baseScriptEngine) ScriptOnSwitch(msg message.Message, script string) ([]string, error) {
func (bse *baseScriptEngine) ScriptOnSwitch() ([]string, error) {
msg := bse.Msg
vm := goja.New()
_, err := vm.RunString(script)
_, err := vm.RunString(bse.Script)
if err != nil {
logrus.Info("JS代码有问题")
return nil, err
}
var fn func(map[string]interface{}, map[string]interface{}, string) []string
err = vm.ExportTo(vm.Get("Switch"), &fn)
err = vm.ExportTo(vm.Get(bse.Fun), &fn)
if err != nil {
logrus.Info("Js函数映射到 Go 函数失败!")
return nil, err
@@ -61,15 +69,16 @@ func (bse *baseScriptEngine) ScriptOnSwitch(msg message.Message, script string)
return datas, nil
}
func (bse *baseScriptEngine) ScriptOnFilter(msg message.Message, script string) (bool, error) {
func (bse *baseScriptEngine) ScriptOnFilter() (bool, error) {
msg := bse.Msg
vm := goja.New()
_, err := vm.RunString(script)
_, err := vm.RunString(bse.Script)
if err != nil {
logrus.Info("JS代码有问题")
return false, err
}
var fn func(map[string]interface{}, map[string]interface{}, string) bool
err = vm.ExportTo(vm.Get("Filter"), &fn)
err = vm.ExportTo(vm.Get(bse.Fun), &fn)
if err != nil {
logrus.Info("Js函数映射到 Go 函数失败!")
return false, err
@@ -78,7 +87,56 @@ func (bse *baseScriptEngine) ScriptOnFilter(msg message.Message, script string)
return datas, nil
}
func (bse *baseScriptEngine) ScriptToString(msg message.Message, script string) (string, error) {
return "", nil
func (bse *baseScriptEngine) ScriptToString() (string, error) {
msg := bse.Msg
vm := goja.New()
_, err := vm.RunString(bse.Script)
if err != nil {
logrus.Info("JS代码有问题")
return "", err
}
var fn func(map[string]interface{}, map[string]interface{}, string) string
err = vm.ExportTo(vm.Get(bse.Fun), &fn)
if err != nil {
logrus.Info("Js函数映射到 Go 函数失败!")
return "", err
}
data := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType())
return data, nil
}
func (bse *baseScriptEngine) ScriptAlarmDetails() (map[string]interface{}, error) {
msg := bse.Msg
vm := goja.New()
_, err := vm.RunString(bse.Script)
if err != nil {
logrus.Info("JS代码有问题")
return nil, err
}
var fn func(map[string]interface{}, map[string]interface{}, string) map[string]interface{}
err = vm.ExportTo(vm.Get(bse.Fun), &fn)
if err != nil {
logrus.Info("Js函数映射到 Go 函数失败!")
return nil, err
}
datas := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType())
return datas, nil
}
func (bse *baseScriptEngine) ScriptGenerate() (map[string]interface{}, error) {
msg := bse.Msg
vm := goja.New()
_, err := vm.RunString(bse.Script)
if err != nil {
logrus.Info("JS代码有问题")
return nil, err
}
var fn func(map[string]interface{}, map[string]interface{}, string) map[string]interface{}
err = vm.ExportTo(vm.Get(bse.Fun), &fn)
if err != nil {
logrus.Info("Js函数映射到 Go 函数失败!")
return nil, err
}
datas := fn(msg.GetMsg(), msg.GetMetadata().GetValues(), msg.GetType())
return datas, nil
}

View File

@@ -0,0 +1,19 @@
package nodes
import (
"bytes"
"text/template"
)
func ParseTemplate(content string, data map[string]interface{}) (string, error) {
tmpl, err := template.New("template").Parse(content)
if err != nil {
return "", err
}
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, data)
if err != nil {
return "", err
}
return buffer.String(), nil
}

View File

@@ -3,12 +3,13 @@ package nodes
import (
"github.com/sirupsen/logrus"
"pandax/pkg/rule_engine/message"
"strings"
)
type transformDeleteKeyNode struct {
bareNode
FormType string `json:"formType" yaml:"formType"` //msg metadata
Keys []string `json:"keys" yaml:"keys"`
FormType string `json:"formType" yaml:"formType"` //msg metadata
Keys string `json:"keys" yaml:"keys"`
}
type transformDeleteKeyNodeFactory struct{}
@@ -27,9 +28,10 @@ func (n *transformDeleteKeyNode) Handle(msg message.Message) error {
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
keys := strings.Split(n.Keys, ",")
if n.FormType == "msg" {
data := msg.GetMsg()
for _, key := range n.Keys {
for _, key := range keys {
if _, found := data[key]; found {
delete(data, key)
msg.SetMsg(data)
@@ -37,7 +39,7 @@ func (n *transformDeleteKeyNode) Handle(msg message.Message) error {
}
} else if n.FormType == "metadata" {
data := msg.GetMetadata()
for _, key := range n.Keys {
for _, key := range keys {
if data.GetKeyValue(key) != nil {
values := data.GetValues()
delete(values, key)
@@ -45,8 +47,12 @@ func (n *transformDeleteKeyNode) Handle(msg message.Message) error {
}
}
} else {
failureLabelNode.Handle(msg)
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
}
}
return successLabelNode.Handle(msg)
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}

View File

@@ -11,8 +11,8 @@ type transformRenameKeyNode struct {
Keys []KeyName `json:"keys" yaml:"keys"`
}
type KeyName struct {
oldName string `json:"oldName" yaml:"oldName"`
newName string `json:"newName" yaml:"newName"`
OldName string `json:"oldName" yaml:"oldName"`
NewName string `json:"newName" yaml:"newName"`
}
type transformRenameKeyNodeFactory struct{}
@@ -20,7 +20,7 @@ func (f transformRenameKeyNodeFactory) Name() string { return "RenameKeyNode
func (f transformRenameKeyNodeFactory) Category() string { return NODE_CATEGORY_TRANSFORM }
func (f transformRenameKeyNodeFactory) Labels() []string { return []string{"Success", "Failure"} }
func (f transformRenameKeyNodeFactory) Create(id string, meta Metadata) (Node, error) {
node := &transformScriptNode{
node := &transformRenameKeyNode{
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
}
return decodePath(meta, node)
@@ -34,25 +34,29 @@ func (n *transformRenameKeyNode) Handle(msg message.Message) error {
if n.FormType == "msg" {
data := msg.GetMsg()
for _, key := range n.Keys {
if _, found := data[key.oldName]; found {
data[key.newName] = data[key.oldName]
delete(data, key.oldName)
if _, found := data[key.OldName]; found {
data[key.NewName] = data[key.OldName]
delete(data, key.OldName)
msg.SetMsg(data)
}
}
} else if n.FormType == "metadata" {
data := msg.GetMetadata()
for _, key := range n.Keys {
if data.GetKeyValue(key.oldName) != nil {
if data.GetKeyValue(key.OldName) != nil {
values := data.GetValues()
values[key.newName] = values[key.oldName]
delete(values, key.oldName)
values[key.NewName] = values[key.OldName]
delete(values, key.OldName)
msg.SetMetadata(message.NewDefaultMetadata(values))
}
}
} else {
failureLabelNode.Handle(msg)
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
}
}
return successLabelNode.Handle(msg)
if successLabelNode != nil {
return successLabelNode.Handle(msg)
}
return nil
}

View File

@@ -16,9 +16,8 @@ func (f transformScriptNodeFactory) Name() string { return "ScriptNode" }
func (f transformScriptNodeFactory) Category() string { return NODE_CATEGORY_TRANSFORM }
func (f transformScriptNodeFactory) Labels() []string { return []string{"Success", "Failure"} }
func (f transformScriptNodeFactory) Create(id string, meta Metadata) (Node, error) {
labels := []string{"Success", "Failure"}
node := &transformScriptNode{
bareNode: newBareNode(f.Name(), id, meta, labels),
bareNode: newBareNode(f.Name(), id, meta, f.Labels()),
}
return decodePath(meta, node)
}
@@ -29,10 +28,17 @@ func (n *transformScriptNode) Handle(msg message.Message) error {
successLabelNode := n.GetLinkedNode("Success")
failureLabelNode := n.GetLinkedNode("Failure")
scriptEngine := NewScriptEngine()
newMessage, err := scriptEngine.ScriptOnMessage(msg, n.Script)
scriptEngine := NewScriptEngine(msg, "Transform", n.Script)
newMessage, err := scriptEngine.ScriptOnMessage()
if err != nil {
return failureLabelNode.Handle(msg)
if failureLabelNode != nil {
return failureLabelNode.Handle(msg)
} else {
return err
}
}
return successLabelNode.Handle(newMessage)
if successLabelNode != nil {
return successLabelNode.Handle(newMessage)
}
return nil
}