Custom Components Overview
You can encapsulate your business logic or general logic into components, and then invoke them through rule nodes by configuring the rule chain. Steps:
- Implement the component interface.
- Register the custom component to the registrar.
- Invoke the component through the rule chain configuration.
# Custom component
# Component interface
Implement the types.Node (opens new window) interface:
// Node node component interface
// Encapsulate business or general logic into components, and then invoke the component through rule chain configuration
type Node interface {
//New create a new component instance
// Each rule node of the rule chain will create a new instance, the data is isolated
New() Node
//Type component type, the type cannot be repeated.
// Used for rule chain, node.type configuration, initialize the corresponding component
// It is recommended to use `/` to distinguish the namespace and prevent conflicts. For example: x/httpClient
Type() string
//Init component initialization, usually do some component parameter configuration or client initialization operations
// The rule node in the rule chain will call it once during initialization
Init(ruleConfig Config, configuration Configuration) error
//OnMsg handle messages and control the flow to child nodes. Each data flowing into the component will be processed by this method
//ctx: rule engine message processing context
//msg: message
OnMsg(ctx RuleContext, msg RuleMsg)
//Destroy destroy, do some resource release operations
Destroy()
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Life cycle
- New: Called when creating a node component instance.
- Init: Used to parse the JSON configuration of the current node, initialized once when initializing the rule chain.
- OnMsg: Used to handle messages and control the flow to child nodes. Each data flowing into the component will be processed by this function.
- Destroy: Called when the node is destroyed. The rule engine will call this method when it is destroyed, or when the rule chain or node configuration is updated.
If the node configuration is dynamically updated, the
Init
method of the new instance of the node is called first, and then theDestroy
method of the old instance is called after the initialization is successful.
# Handle messages
After the current rule node is processed, notify the next or multiple nodes through the following methods. The rule engine will query the child nodes that meet the relationship and trigger their OnMsg
method to perform chain data flow calls
//TellSuccess notify the rule engine that the current message is processed successfully, and send the message to the next node through the `Success` relationship
TellSuccess(msg RuleMsg)
//TellNext use the specified relationTypes to send messages to the next node
TellNext(msg RuleMsg, relationTypes ...string)
//TellFailure notify the rule engine that the current message processing failed, and send the message to the next node through the `Failure` relationship
TellFailure(msg RuleMsg, err error)
2
3
4
5
6
# Example
Implement the types.Node (opens new window) interface, define the component:
// UpperNode is a plugin that converts the message data to uppercase
type UpperNode struct{}
func (n *UpperNode) Type() string {
return "test/upper"
}
func (n *UpperNode) New() types.Node {
return &UpperNode{}
}
func (n *UpperNode) Init(ruleConfig types.Config, configuration types.Configuration) error {
// Do some initialization work
return nil
}
// Handle messages
func (n *UpperNode) OnMsg(ctx types.RuleContext, msg types.RuleMsg) {
msg.Data = strings.ToUpper(msg.Data)
// Send the modified message to the next node
ctx.TellSuccess(msg)
}
func (n *UpperNode) Destroy() {
// Do some cleanup work
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Register the component to the registrar:
rulego.Registry.Register(&MyNode{})
Then use your custom component in the rule chain file:
{
"ruleChain": {
"name": "Test Rule Chain",
"root": true,
"debugMode": false
},
"metadata": {
"nodes": [
{
"id": "s1",
"type": "test/upper",
"name": "Name",
"debugMode": true,
"configuration": {
"field1": "Component-defined configuration parameters",
"....": "..."
}
}
],
"connections": [
{
"fromId": "s1",
"toId": "Connect to the next component ID",
"type": "The connection relationship with the component"
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# go plugin
method to provide components
This method supports dynamic loading of components, but it can only support non-windows systems. A plugin can provide multiple components.
Implement the types.PluginRegistry (opens new window) interface.
And export the variable name: Plugins
, refer to examples/plugin (opens new window)
# Example
Implement the types.PluginRegistry (opens new window) interface
// Export the plugin variable
var Plugins MyPlugins
type MyPlugins struct{}
func (p *MyPlugins) Init() error {
return nil
}
func (p *MyPlugins) Components() []types.Node {
// A plugin can provide multiple components
return []types.Node{&UpperNode{}, &TimeNode{}, &FilterNode{}}
}
2
3
4
5
6
7
8
9
10
11
12
Compile the plugin:
# Compile the plugin, generate the plugin.so file, you need to compile it in a mac or linux environment
go build -buildmode=plugin -o plugin.so plugin.go
2
Register the component to the registrar:
rulego.Registry.RegisterPlugin("test", "./plugin.so")
# Visualization
- Component Form Conventions
- Custom component visualization reference: See the Get Component Configuration Form section.
# Contribute Components
The core feature of RuleGo is componentization, and all business logic is components, and they can be flexibly configured and reused. At present, RuleGo has built-in a lot of common components. However, we know that these components are far from meeting the needs of all users, so we hope that more developers can contribute extension components to RuleGo, making RuleGo's ecology more rich and powerful.
- If the code for your component does not have third-party dependencies or is a general-purpose component, please submit it to the standard components components (opens new window) under the main repository.
- Common components should be submitted to the extension component repository: rulego-components (opens new window)
- CI/CD related components should be submitted to: rulego-components-ci (opens new window)
- AI-related components should be submitted to: rulego-components-ai (opens new window)
- IoT-related components should be submitted to: rulego-components-iot (opens new window)