Added plugins folder location in config for the server.

Created get and ser plugin files.
Created server function to load plugins.
Moved Makefile inside server folder to build and run server.
This commit is contained in:
Kelvin Clement Mwinuka
2023-07-03 08:39:19 +08:00
parent 3961b3e7f6
commit 58d6664faa
4 changed files with 158 additions and 5 deletions

View File

@@ -5,22 +5,35 @@ import (
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"net/http"
"path"
"plugin"
"strings"
"sync"
"github.com/kelvinmwinuka/memstore/serialization"
"github.com/kelvinmwinuka/memstore/utils"
)
type Plugin interface {
Name() string
Command() string
Description() string
HandleCommand(tokens []string, server interface{}) error
}
type Data struct {
mu sync.Mutex
data map[string]interface{}
}
type Server struct {
config utils.Config
data Data
config utils.Config
data Data
plugins []Plugin
}
func (server *Server) handleConnection(conn net.Conn) {
@@ -116,11 +129,69 @@ func (server *Server) StartHTTP() {
}
}
func (server *Server) LoadPlugins() {
conf := server.config
// Load plugins
pluginDirs, err := ioutil.ReadDir(conf.Plugins)
if err != nil {
log.Fatal(err)
}
for _, file := range pluginDirs {
if file.IsDir() {
switch file.Name() {
case "commands":
files, err := ioutil.ReadDir(path.Join(conf.Plugins, "commands"))
if err != nil {
log.Fatal(err)
}
for _, file := range files {
if !strings.HasSuffix(file.Name(), ".so") {
// Skip files that are not .so
continue
}
p, err := plugin.Open(path.Join(conf.Plugins, "commands", file.Name()))
if err != nil {
log.Fatal(err)
}
pluginSymbol, err := p.Lookup("Plugin")
if err != nil {
fmt.Printf("unexpected plugin symbol in plugin %s\n", file.Name())
continue
}
plugin, ok := pluginSymbol.(Plugin)
if !ok {
fmt.Printf("invalid plugin signature in plugin %s \n", file.Name())
continue
}
// Check if a plugin that handles the same command already exists
for _, loadedPlugin := range server.plugins {
if loadedPlugin.Command() == plugin.Command() {
fmt.Printf("plugin that handles %s command already exists. Please handle a different command.", plugin.Command())
}
}
server.plugins = append(server.plugins, plugin)
}
}
}
}
}
func (server *Server) Start() {
server.data.data = make(map[string]interface{})
conf := server.config
server.LoadPlugins()
if conf.TLS && (len(conf.Key) <= 0 || len(conf.Cert) <= 0) {
fmt.Println("Must provide key and certificate file paths for TLS mode.")
return
@@ -134,10 +205,9 @@ func (server *Server) Start() {
}
func main() {
conf := utils.GetConfig()
server := Server{
config: conf,
config: utils.GetConfig(),
plugins: []Plugin{},
}
server.Start()