GO SDK for Portable Plugin

By using GO SDK for portable plugins, user can develop portable plugins with go language. The GO SDK provides similar APIs for the source, sink and function extensions. Additionally, it provides a sdk start function as the execution entry point to define the plugin and its symbols.

Development

Symbols

As the GO SDK provides almost identical API interfaces, the user’s source, sink and function plugin can almost reuse by only some small modifications.

To develop the portable plugin, users need to depend on github.com/lf-edge/ekuiper/sdk/go instead of eKuiper main project. Then to implement source, just implement the interfaces in package github.com/lf-edge/ekuiper/sdk/go/api.

For source, implement the source interface as below as the same as described in native plugin source.

  1. type Source interface {
  2. // Open Should be sync function for normal case. The container will run it in go func
  3. Open(ctx StreamContext, consumer chan<- SourceTuple, errCh chan<- error)
  4. // Configure Called during initialization. Configure the source with the data source(e.g. topic for mqtt) and the properties read from the yaml
  5. Configure(datasource string, props map[string]interface{}) error
  6. Closable
  7. }

For sink, implement the sink interface as below as the same as described in native plugin sink.

  1. type Sink interface {
  2. //Should be sync function for normal case. The container will run it in go func
  3. Open(ctx StreamContext) error
  4. //Called during initialization. Configure the sink with the properties from rule action definition
  5. Configure(props map[string]interface{}) error
  6. //Called when each row of data has transferred to this sink
  7. Collect(ctx StreamContext, data interface{}) error
  8. Closable
  9. }

For function, implement the function interface as below as the same as described in native plugin function.

  1. type Function interface {
  2. //The argument is a list of xsql.Expr
  3. Validate(args []interface{}) error
  4. //Execute the function, return the result and if execution is successful.
  5. //If execution fails, return the error and false.
  6. Exec(args []interface{}, ctx FunctionContext) (interface{}, bool)
  7. //If this function is an aggregate function. Each parameter of an aggregate function will be a slice
  8. IsAggregate() bool
  9. }

Plugin Main Program

As the portable plugin is a standalone program, it needs a main program to be able to built into an executable. In go SDK, a start function is provided to define the meta data of the plugin and let it start. A typical main program is as below:

  1. package main
  2. import (
  3. "github.com/lf-edge/ekuiper/sdk/go/api"
  4. sdk "github.com/lf-edge/ekuiper/sdk/go/runtime"
  5. "os"
  6. )
  7. func main() {
  8. sdk.Start(os.Args, &sdk.PluginConfig{
  9. Name: "mirror",
  10. Sources: map[string]sdk.NewSourceFunc{
  11. "random": func() api.Source {
  12. return &randomSource{}
  13. },
  14. },
  15. Functions: map[string]sdk.NewFunctionFunc{
  16. "echo": func() api.Function {
  17. return &echo{}
  18. },
  19. },
  20. Sinks: map[string]sdk.NewSinkFunc{
  21. "file": func() api.Sink {
  22. return &fileSink{}
  23. },
  24. },
  25. })
  26. }

Here, in the main function, it calls sdk.Start to start the plugin process. In the argument, a PluginConfig struct is specified to define the plugin name, the sources, functions and sinks name and their initialization functions. This information must match the json file when packaging the plugin.

For the full examples, please check the sdk example.

Package

We need to prepare the executable file and the json file and then package them. For GO SDK, we need to build the main program into an executable by merely using go build like a normal program (it is actually a normal program). Due to go binary file may have different binary name in different os, make sure the file name is correct in the json file. For detail, please check packaing.