lua

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2021 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Example (Api)

Run simple test with all API functions

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"

	"time"

	"github.com/vxcontrol/luar"
	"github.com/vxcontrol/vxcommon/agent"
	"github.com/vxcontrol/vxcommon/lua"
	"github.com/vxcontrol/vxcommon/vxproto"
)

func randString(nchars int) string {
	rbytes := make([]byte, nchars)
	if _, err := rand.Read(rbytes); err != nil {
		return ""
	}

	return hex.EncodeToString(rbytes)
}

// getRef is function for returning referense of string
func getRef(str string) *string {
	return &str
}

type FakeMainModule struct{}

func (mModule *FakeMainModule) DefaultRecvPacket(packet *vxproto.Packet) error {
	return nil
}

func (mModule *FakeMainModule) HasAgentIDValid(agentID string, agentType vxproto.AgentType) bool {
	return true
}

func (mModule *FakeMainModule) HasAgentInfoValid(agentID string, info *agent.Information) bool {
	return true
}

func (mModule *FakeMainModule) OnConnect(socket vxproto.IAgentSocket) error {
	seconds := time.Now().Unix()
	stoken := randString(20)
	socket.SetAuthReq(&agent.AuthenticationRequest{
		Timestamp: &seconds,
		Atoken:    getRef(""),
	})
	socket.SetAuthResp(&agent.AuthenticationResponse{
		Atoken: getRef(socket.GetSource()),
		Stoken: getRef(stoken),
	})
	socket.SetInfo(&agent.Information{
		Os: &agent.Information_OS{
			Type: getRef("linux"),
			Name: getRef("Ubuntu 16.04"),
			Arch: getRef("amd64"),
		},
		User: &agent.Information_User{
			Name:  getRef("root"),
			Group: getRef("root"),
		},
	})
	return nil
}

type MFiles map[string][]byte
type MArgs map[string][]string

// Init module
func initModule(files MFiles, args MArgs, name string, proto vxproto.IVXProto) (*lua.Module, *lua.State) {
	if proto == nil {
		return nil, nil
	}

	moduleSocket := proto.NewModule(name, "")
	if moduleSocket == nil {
		return nil, nil
	}

	if !proto.AddModule(moduleSocket) {
		return nil, nil
	}

	state, err := lua.NewState(files)
	if err != nil {
		return nil, nil
	}

	module, err := lua.NewModule(args, state, moduleSocket)
	if err != nil {
		return nil, nil
	}

	luar.Register(state.L, "", luar.Map{
		"print": fmt.Println,
	})

	return module, state
}

// Run main logic of module
func runModule(module *lua.Module) string {
	if module == nil {
		return "internal error"
	}
	module.Start()
	return module.GetResult()
}

func main() {
	args := map[string][]string{}
	files := map[string][]byte{
		"main.lua": []byte(`
			__api.set_recv_timeout(10) -- 10 ms

			-- src is string
			-- data is string
			-- path is string
			-- name is string
			-- mtype is int:
			--   {DEBUG: 0, INFO: 1, WARNING: 2, ERROR: 3}
			-- cmtype is string
			-- data is string
			if __api.add_cbs({
				["data"] = function(src, data)
					return true
				end,
				["file"] = function(src, path, name)
					return true
				end,
				["text"] = function(src, text, name)
					return true
				end,
				["msg"] = function(src, msg, mtype)
					return true
				end,
				["control"] = function(cmtype, data)
					return true
				end,
			}) == false then
				return "failed"
			end
			if __api.del_cbs({ "data", "file", "text", "msg", "control" }) == false then
				return "failed"
			end

			-- res is boolean
			res = __api.send_data_to("def_token", "test_data")
			res = __api.send_file_to("def_token", "file_data", "file_name")
			res = __api.send_text_to("def_token", "text_data", "text_name")
			res = __api.send_msg_to("def_token", "msg_data", 0)
			res = __api.send_file_from_fs_to("def_token", "file_path", "file_name")

			-- res is boolean
			src, data, res = __api.recv_data()
			src, path, name, res = __api.recv_file()
			src, text, name, res = __api.recv_text()
			src, msg, mtype, res = __api.recv_msg()

			-- res is boolean
			data, res = __api.recv_data_from("def_token")
			path, name, res = __api.recv_file_from("def_token")
			text, name, res = __api.recv_text_from("def_token")
			msg, mtype, res = __api.recv_msg_from("def_token")

			return "success"
		`),
	}

	proto := vxproto.New(&FakeMainModule{})
	module, _ := initModule(files, args, "test_module", proto)
	fmt.Println("Result: ", runModule(module))
	module.Close()
	proto.Close()
}
Output:

Result:  success
Example (Args)

Run simple test with arguments for state

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"

	"time"

	"github.com/vxcontrol/luar"
	"github.com/vxcontrol/vxcommon/agent"
	"github.com/vxcontrol/vxcommon/lua"
	"github.com/vxcontrol/vxcommon/vxproto"
)

func randString(nchars int) string {
	rbytes := make([]byte, nchars)
	if _, err := rand.Read(rbytes); err != nil {
		return ""
	}

	return hex.EncodeToString(rbytes)
}

// getRef is function for returning referense of string
func getRef(str string) *string {
	return &str
}

type FakeMainModule struct{}

func (mModule *FakeMainModule) DefaultRecvPacket(packet *vxproto.Packet) error {
	return nil
}

func (mModule *FakeMainModule) HasAgentIDValid(agentID string, agentType vxproto.AgentType) bool {
	return true
}

func (mModule *FakeMainModule) HasAgentInfoValid(agentID string, info *agent.Information) bool {
	return true
}

func (mModule *FakeMainModule) OnConnect(socket vxproto.IAgentSocket) error {
	seconds := time.Now().Unix()
	stoken := randString(20)
	socket.SetAuthReq(&agent.AuthenticationRequest{
		Timestamp: &seconds,
		Atoken:    getRef(""),
	})
	socket.SetAuthResp(&agent.AuthenticationResponse{
		Atoken: getRef(socket.GetSource()),
		Stoken: getRef(stoken),
	})
	socket.SetInfo(&agent.Information{
		Os: &agent.Information_OS{
			Type: getRef("linux"),
			Name: getRef("Ubuntu 16.04"),
			Arch: getRef("amd64"),
		},
		User: &agent.Information_User{
			Name:  getRef("root"),
			Group: getRef("root"),
		},
	})
	return nil
}

type MFiles map[string][]byte
type MArgs map[string][]string

// Init module
func initModule(files MFiles, args MArgs, name string, proto vxproto.IVXProto) (*lua.Module, *lua.State) {
	if proto == nil {
		return nil, nil
	}

	moduleSocket := proto.NewModule(name, "")
	if moduleSocket == nil {
		return nil, nil
	}

	if !proto.AddModule(moduleSocket) {
		return nil, nil
	}

	state, err := lua.NewState(files)
	if err != nil {
		return nil, nil
	}

	module, err := lua.NewModule(args, state, moduleSocket)
	if err != nil {
		return nil, nil
	}

	luar.Register(state.L, "", luar.Map{
		"print": fmt.Println,
	})

	return module, state
}

// Run main logic of module
func runModule(module *lua.Module) string {
	if module == nil {
		return "internal error"
	}
	module.Start()
	return module.GetResult()
}

func main() {
	arg1 := []string{"a", "b", "c", "d"}
	arg2 := []string{"e"}
	arg3 := []string{}
	arg4 := []string{"f", "g"}
	args := map[string][]string{
		"arg1": arg1,
		"arg2": arg2,
		"arg3": arg3,
		"arg4": arg4,
	}
	files := map[string][]byte{
		"main.lua": []byte(`
			local arg_keys = {}
			for k, _ in pairs(__args) do
				table.insert(arg_keys, k)
			end
			table.sort(arg_keys)
			for i, k in ipairs(arg_keys) do
				v = __args[k]
				print(i, k, table.getn(v))
				for j, p in pairs(v) do
					print(j, p)
				end
			end
			return "success"
		`),
	}

	proto := vxproto.New(&FakeMainModule{})
	module, _ := initModule(files, args, "test_module", proto)
	fmt.Println("Result: ", runModule(module))
	module.Close()
	proto.Close()
}
Output:

1 arg1 4
1 a
2 b
3 c
4 d
2 arg2 1
1 e
3 arg3 0
4 arg4 2
1 f
2 g
Result:  success
Example (Imc)

Run IMC test with the API functions

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"

	"sync"

	"time"

	"github.com/vxcontrol/luar"
	"github.com/vxcontrol/vxcommon/agent"
	"github.com/vxcontrol/vxcommon/lua"
	"github.com/vxcontrol/vxcommon/vxproto"
)

func randString(nchars int) string {
	rbytes := make([]byte, nchars)
	if _, err := rand.Read(rbytes); err != nil {
		return ""
	}

	return hex.EncodeToString(rbytes)
}

// getRef is function for returning referense of string
func getRef(str string) *string {
	return &str
}

type FakeMainModule struct{}

func (mModule *FakeMainModule) DefaultRecvPacket(packet *vxproto.Packet) error {
	return nil
}

func (mModule *FakeMainModule) HasAgentIDValid(agentID string, agentType vxproto.AgentType) bool {
	return true
}

func (mModule *FakeMainModule) HasAgentInfoValid(agentID string, info *agent.Information) bool {
	return true
}

func (mModule *FakeMainModule) OnConnect(socket vxproto.IAgentSocket) error {
	seconds := time.Now().Unix()
	stoken := randString(20)
	socket.SetAuthReq(&agent.AuthenticationRequest{
		Timestamp: &seconds,
		Atoken:    getRef(""),
	})
	socket.SetAuthResp(&agent.AuthenticationResponse{
		Atoken: getRef(socket.GetSource()),
		Stoken: getRef(stoken),
	})
	socket.SetInfo(&agent.Information{
		Os: &agent.Information_OS{
			Type: getRef("linux"),
			Name: getRef("Ubuntu 16.04"),
			Arch: getRef("amd64"),
		},
		User: &agent.Information_User{
			Name:  getRef("root"),
			Group: getRef("root"),
		},
	})
	return nil
}

type MFiles map[string][]byte
type MArgs map[string][]string

// Init module
func initModule(files MFiles, args MArgs, name string, proto vxproto.IVXProto) (*lua.Module, *lua.State) {
	if proto == nil {
		return nil, nil
	}

	moduleSocket := proto.NewModule(name, "")
	if moduleSocket == nil {
		return nil, nil
	}

	if !proto.AddModule(moduleSocket) {
		return nil, nil
	}

	state, err := lua.NewState(files)
	if err != nil {
		return nil, nil
	}

	module, err := lua.NewModule(args, state, moduleSocket)
	if err != nil {
		return nil, nil
	}

	luar.Register(state.L, "", luar.Map{
		"print": fmt.Println,
	})

	return module, state
}

// Run main logic of module
func runModule(module *lua.Module) string {
	if module == nil {
		return "internal error"
	}
	module.Start()
	return module.GetResult()
}

func main() {
	var wg sync.WaitGroup
	mname1 := []string{"test_module1", "sender"}
	mname2 := []string{"test_module2", "receiver"}
	args1 := map[string][]string{
		"dst_module": mname2,
	}
	args2 := map[string][]string{
		"dst_module": mname1,
	}
	files := map[string][]byte{
		"main.lua": []byte(`
			local imc_token = __imc.make_token("", __args["dst_module"][1])
			__api.set_recv_timeout(1000)

			local this_imc_token = __imc.get_token()
			if type(this_imc_token) ~= "string" or #this_imc_token ~= 40 then
				return "failed"
			end
			if __imc.is_exist(imc_token) == false then
				return "failed"
			end
			local agentID, modName, isExist = __imc.get_info(imc_token)
			if agentID ~= "" or modName ~= __args["dst_module"][1] or isExist ~= true then
				return "failed"
			end

			if __args["dst_module"][2] == "sender" then
				__api.await(100)
				if __api.send_data_to(imc_token, "test_data") == false then
					return "failed"
				end
				
				__api.await(100)
				if __api.send_data_to(imc_token, "test_data_direct") == false then
					return "failed"
				end
			end

			if __args["dst_module"][2] == "receiver" then
				local src, data, res = __api.recv_data()
				if src ~= imc_token or data ~= "test_data" or res ~= true then
					return "failed"
				end
	
				data, res = __api.recv_data_from(imc_token)
				if data ~= "test_data_direct" or res ~= true then
					return "failed"
				end
			end

			return "success"
		`),
	}

	proto := vxproto.New(&FakeMainModule{})
	module1, _ := initModule(files, args1, mname1[0], proto)
	module2, _ := initModule(files, args2, mname2[0], proto)

	wg.Add(1)
	go func() {
		fmt.Println("Result1: ", runModule(module1))
		wg.Done()
	}()
	wg.Add(1)
	go func() {
		fmt.Println("Result2: ", runModule(module2))
		wg.Done()
	}()
	wg.Wait()
	module1.Close()
	module2.Close()
	proto.Close()
}
Output:

Result1:  success
Result2:  success
Example (Module_await)

Run simple test with await function (1 second)

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"

	"time"

	"github.com/vxcontrol/luar"
	"github.com/vxcontrol/vxcommon/agent"
	"github.com/vxcontrol/vxcommon/lua"
	"github.com/vxcontrol/vxcommon/vxproto"
)

func randString(nchars int) string {
	rbytes := make([]byte, nchars)
	if _, err := rand.Read(rbytes); err != nil {
		return ""
	}

	return hex.EncodeToString(rbytes)
}

// getRef is function for returning referense of string
func getRef(str string) *string {
	return &str
}

type FakeMainModule struct{}

func (mModule *FakeMainModule) DefaultRecvPacket(packet *vxproto.Packet) error {
	return nil
}

func (mModule *FakeMainModule) HasAgentIDValid(agentID string, agentType vxproto.AgentType) bool {
	return true
}

func (mModule *FakeMainModule) HasAgentInfoValid(agentID string, info *agent.Information) bool {
	return true
}

func (mModule *FakeMainModule) OnConnect(socket vxproto.IAgentSocket) error {
	seconds := time.Now().Unix()
	stoken := randString(20)
	socket.SetAuthReq(&agent.AuthenticationRequest{
		Timestamp: &seconds,
		Atoken:    getRef(""),
	})
	socket.SetAuthResp(&agent.AuthenticationResponse{
		Atoken: getRef(socket.GetSource()),
		Stoken: getRef(stoken),
	})
	socket.SetInfo(&agent.Information{
		Os: &agent.Information_OS{
			Type: getRef("linux"),
			Name: getRef("Ubuntu 16.04"),
			Arch: getRef("amd64"),
		},
		User: &agent.Information_User{
			Name:  getRef("root"),
			Group: getRef("root"),
		},
	})
	return nil
}

type MFiles map[string][]byte
type MArgs map[string][]string

// Init module
func initModule(files MFiles, args MArgs, name string, proto vxproto.IVXProto) (*lua.Module, *lua.State) {
	if proto == nil {
		return nil, nil
	}

	moduleSocket := proto.NewModule(name, "")
	if moduleSocket == nil {
		return nil, nil
	}

	if !proto.AddModule(moduleSocket) {
		return nil, nil
	}

	state, err := lua.NewState(files)
	if err != nil {
		return nil, nil
	}

	module, err := lua.NewModule(args, state, moduleSocket)
	if err != nil {
		return nil, nil
	}

	luar.Register(state.L, "", luar.Map{
		"print": fmt.Println,
	})

	return module, state
}

// Run main logic of module
func runModule(module *lua.Module) string {
	if module == nil {
		return "internal error"
	}
	module.Start()
	return module.GetResult()
}

func main() {
	args := map[string][]string{}
	files := map[string][]byte{
		"main.lua": []byte(`
			print(__api.get_name())
			__api.await(1000) -- 1 sec
			return "success"
		`),
	}

	proto := vxproto.New(&FakeMainModule{})
	module, _ := initModule(files, args, "test_module", proto)
	fmt.Println("Result: ", runModule(module))
	module.Close()
	proto.Close()
}
Output:

test_module
Result:  success
Example (Module_await_inf)

Run simple test with await function (infinity)

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"

	"sync"

	"time"

	"github.com/vxcontrol/luar"
	"github.com/vxcontrol/vxcommon/agent"
	"github.com/vxcontrol/vxcommon/lua"
	"github.com/vxcontrol/vxcommon/vxproto"
)

func randString(nchars int) string {
	rbytes := make([]byte, nchars)
	if _, err := rand.Read(rbytes); err != nil {
		return ""
	}

	return hex.EncodeToString(rbytes)
}

// getRef is function for returning referense of string
func getRef(str string) *string {
	return &str
}

type FakeMainModule struct{}

func (mModule *FakeMainModule) DefaultRecvPacket(packet *vxproto.Packet) error {
	return nil
}

func (mModule *FakeMainModule) HasAgentIDValid(agentID string, agentType vxproto.AgentType) bool {
	return true
}

func (mModule *FakeMainModule) HasAgentInfoValid(agentID string, info *agent.Information) bool {
	return true
}

func (mModule *FakeMainModule) OnConnect(socket vxproto.IAgentSocket) error {
	seconds := time.Now().Unix()
	stoken := randString(20)
	socket.SetAuthReq(&agent.AuthenticationRequest{
		Timestamp: &seconds,
		Atoken:    getRef(""),
	})
	socket.SetAuthResp(&agent.AuthenticationResponse{
		Atoken: getRef(socket.GetSource()),
		Stoken: getRef(stoken),
	})
	socket.SetInfo(&agent.Information{
		Os: &agent.Information_OS{
			Type: getRef("linux"),
			Name: getRef("Ubuntu 16.04"),
			Arch: getRef("amd64"),
		},
		User: &agent.Information_User{
			Name:  getRef("root"),
			Group: getRef("root"),
		},
	})
	return nil
}

type MFiles map[string][]byte
type MArgs map[string][]string

// Init module
func initModule(files MFiles, args MArgs, name string, proto vxproto.IVXProto) (*lua.Module, *lua.State) {
	if proto == nil {
		return nil, nil
	}

	moduleSocket := proto.NewModule(name, "")
	if moduleSocket == nil {
		return nil, nil
	}

	if !proto.AddModule(moduleSocket) {
		return nil, nil
	}

	state, err := lua.NewState(files)
	if err != nil {
		return nil, nil
	}

	module, err := lua.NewModule(args, state, moduleSocket)
	if err != nil {
		return nil, nil
	}

	luar.Register(state.L, "", luar.Map{
		"print": fmt.Println,
	})

	return module, state
}

// Run main logic of module
func runModule(module *lua.Module) string {
	if module == nil {
		return "internal error"
	}
	module.Start()
	return module.GetResult()
}

func main() {
	args := map[string][]string{}
	files := map[string][]byte{
		"main.lua": []byte(`
			print(__api.get_name())
			__api.await(-1)
			return "success"
		`),
	}

	var wg sync.WaitGroup
	proto := vxproto.New(&FakeMainModule{})
	module, _ := initModule(files, args, "test_module", proto)
	wg.Add(1)
	go func() {
		fmt.Println("Result: ", runModule(module))
		wg.Done()
	}()

	time.Sleep(time.Second)
	module.Close()
	proto.Close()
	wg.Wait()
}
Output:

test_module
Result:  success

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module is struct that used for internal communication logic with Lua state

func NewModule

func NewModule(args map[string][]string, state *State, socket vxproto.IModuleSocket) (*Module, error)

NewModule is function which constructed Module object

func (*Module) Close

func (m *Module) Close()

Close is function which release lua state for module

func (*Module) ControlMsg

func (m *Module) ControlMsg(mtype, data string) bool

ControlMsg is function for send control message to module state

func (*Module) GetResult

func (m *Module) GetResult() string

GetResult is nonblocked function which return result from module

func (*Module) IsClose

func (m *Module) IsClose() bool

IsClose is nonblocked function which check a state of module

func (*Module) SetAgents

func (m *Module) SetAgents(agents map[string]*vxproto.AgentInfo)

SetAgents is function for storing agent list into module state

func (*Module) Start

func (m *Module) Start()

Start is function which prepare state for module

func (*Module) Stop

func (m *Module) Stop()

Stop is function which set close state for module

type State

type State struct {
	L *lua.State
	// contains filtered or unexported fields
}

State is context of lua module

func NewState

func NewState(files map[string][]byte) (*State, error)

NewState is function which constructed State object

func (*State) Exec

func (s *State) Exec() (string, error)

Exec is blocked function for data execution

func (*State) IsClose

func (s *State) IsClose() bool

IsClose is nonblocked function which check a state of module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL