mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +08:00
98 lines
2.3 KiB
Go
98 lines
2.3 KiB
Go
package pluginInternal
|
|
|
|
import (
|
|
"encoding/gob"
|
|
"net/rpc"
|
|
|
|
"github.com/hashicorp/go-plugin"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func init() {
|
|
gob.Register(new(funcData))
|
|
}
|
|
|
|
// funcData is used to transfer between plugin and host via RPC.
|
|
type funcData struct {
|
|
Name string // function name
|
|
Args []interface{} // function arguments
|
|
}
|
|
|
|
// functionRPC runs on the host side.
|
|
type functionRPC struct {
|
|
client *rpc.Client
|
|
}
|
|
|
|
func (g *functionRPC) GetNames() ([]string, error) {
|
|
var resp []string
|
|
err := g.client.Call("Plugin.GetNames", new(interface{}), &resp)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("rpc call GetNames() failed")
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// host -> plugin
|
|
func (g *functionRPC) Call(funcName string, funcArgs ...interface{}) (interface{}, error) {
|
|
log.Info().Str("funcName", funcName).Interface("funcArgs", funcArgs).Msg("call function via RPC")
|
|
f := funcData{
|
|
Name: funcName,
|
|
Args: funcArgs,
|
|
}
|
|
|
|
var args interface{} = f
|
|
var resp interface{}
|
|
err := g.client.Call("Plugin.Call", &args, &resp)
|
|
if err != nil {
|
|
log.Error().Err(err).
|
|
Str("funcName", funcName).Interface("funcArgs", funcArgs).
|
|
Msg("rpc call Call() failed")
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// functionRPCServer runs on the plugin side, executing the user custom function.
|
|
type functionRPCServer struct {
|
|
Impl FuncCaller
|
|
}
|
|
|
|
// plugin execution
|
|
func (s *functionRPCServer) GetNames(args interface{}, resp *[]string) error {
|
|
log.Info().Interface("args", args).Msg("GetNames called on plugin side")
|
|
var err error
|
|
*resp, err = s.Impl.GetNames()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("GetNames execution failed")
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// plugin execution
|
|
func (s *functionRPCServer) Call(args interface{}, resp *interface{}) error {
|
|
log.Info().Interface("args", args).Msg("function called on plugin side")
|
|
f := args.(*funcData)
|
|
var err error
|
|
*resp, err = s.Impl.Call(f.Name, f.Args...)
|
|
if err != nil {
|
|
log.Error().Err(err).Interface("args", args).Msg("function execution failed")
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// HRPPlugin implements hashicorp's plugin.Plugin.
|
|
type HRPPlugin struct {
|
|
Impl FuncCaller
|
|
}
|
|
|
|
func (p *HRPPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
|
|
return &functionRPCServer{Impl: p.Impl}, nil
|
|
}
|
|
|
|
func (HRPPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
|
|
return &functionRPC{client: c}, nil
|
|
}
|