mirror of
https://github.com/tuna/tunasync.git
synced 2025-06-15 14:12:47 +00:00
refactor: manager server
This commit is contained in:
parent
84b7bdd713
commit
9865f28259
@ -20,7 +20,7 @@ func contextErrorLogger(c *gin.Context) {
|
|||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *managerServer) workerIDValidator(c *gin.Context) {
|
func (s *Manager) workerIDValidator(c *gin.Context) {
|
||||||
workerID := c.Param("id")
|
workerID := c.Param("id")
|
||||||
_, err := s.adapter.GetWorker(workerID)
|
_, err := s.adapter.GetWorker(workerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package manager
|
package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -14,13 +15,99 @@ const (
|
|||||||
_infoKey = "message"
|
_infoKey = "message"
|
||||||
)
|
)
|
||||||
|
|
||||||
type managerServer struct {
|
var manager *Manager
|
||||||
*gin.Engine
|
|
||||||
adapter dbAdapter
|
// A Manager represents a manager server
|
||||||
|
type Manager struct {
|
||||||
|
cfg *Config
|
||||||
|
engine *gin.Engine
|
||||||
|
adapter dbAdapter
|
||||||
|
tlsConfig *tls.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTUNASyncManager returns the manager from config
|
||||||
|
func GetTUNASyncManager(cfg *Config) *Manager {
|
||||||
|
if manager != nil {
|
||||||
|
return manager
|
||||||
|
}
|
||||||
|
|
||||||
|
// create gin engine
|
||||||
|
if !cfg.Debug {
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
}
|
||||||
|
s := &Manager{
|
||||||
|
cfg: cfg,
|
||||||
|
engine: gin.Default(),
|
||||||
|
adapter: nil,
|
||||||
|
tlsConfig: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Files.CACert != "" {
|
||||||
|
tlsConfig, err := GetTLSConfig(cfg.Files.CACert)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Error initializing TLS config: %s", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
s.tlsConfig = tlsConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Files.DBFile != "" {
|
||||||
|
adapter, err := makeDBAdapter(cfg.Files.DBType, cfg.Files.DBFile)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Error initializing DB adapter: %s", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
s.setDBAdapter(adapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// common log middleware
|
||||||
|
s.engine.Use(contextErrorLogger)
|
||||||
|
|
||||||
|
s.engine.GET("/ping", func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{_infoKey: "pong"})
|
||||||
|
})
|
||||||
|
// list jobs, status page
|
||||||
|
s.engine.GET("/jobs", s.listAllJobs)
|
||||||
|
|
||||||
|
// list workers
|
||||||
|
s.engine.GET("/workers", s.listWorkers)
|
||||||
|
// worker online
|
||||||
|
s.engine.POST("/workers", s.registerWorker)
|
||||||
|
|
||||||
|
// workerID should be valid in this route group
|
||||||
|
workerValidateGroup := s.engine.Group("/workers", s.workerIDValidator)
|
||||||
|
// get job list
|
||||||
|
workerValidateGroup.GET(":id/jobs", s.listJobsOfWorker)
|
||||||
|
// post job status
|
||||||
|
workerValidateGroup.POST(":id/jobs/:job", s.updateJobOfWorker)
|
||||||
|
|
||||||
|
// for tunasynctl to post commands
|
||||||
|
s.engine.POST("/cmd", s.handleClientCmd)
|
||||||
|
|
||||||
|
manager = s
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Manager) setDBAdapter(adapter dbAdapter) {
|
||||||
|
s.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs the manager server forever
|
||||||
|
func (s *Manager) Run() {
|
||||||
|
addr := fmt.Sprintf("%s:%d", s.cfg.Server.Addr, s.cfg.Server.Port)
|
||||||
|
if s.cfg.Server.SSLCert == "" && s.cfg.Server.SSLKey == "" {
|
||||||
|
if err := s.engine.Run(addr); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := s.engine.RunTLS(addr, s.cfg.Server.SSLCert, s.cfg.Server.SSLKey); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// listAllJobs repond with all jobs of specified workers
|
// listAllJobs repond with all jobs of specified workers
|
||||||
func (s *managerServer) listAllJobs(c *gin.Context) {
|
func (s *Manager) listAllJobs(c *gin.Context) {
|
||||||
mirrorStatusList, err := s.adapter.ListAllMirrorStatus()
|
mirrorStatusList, err := s.adapter.ListAllMirrorStatus()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("failed to list all mirror status: %s",
|
err := fmt.Errorf("failed to list all mirror status: %s",
|
||||||
@ -41,7 +128,7 @@ func (s *managerServer) listAllJobs(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// listWrokers respond with informations of all the workers
|
// listWrokers respond with informations of all the workers
|
||||||
func (s *managerServer) listWorkers(c *gin.Context) {
|
func (s *Manager) listWorkers(c *gin.Context) {
|
||||||
var workerInfos []WorkerStatus
|
var workerInfos []WorkerStatus
|
||||||
workers, err := s.adapter.ListWorkers()
|
workers, err := s.adapter.ListWorkers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,7 +150,7 @@ func (s *managerServer) listWorkers(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// registerWorker register an newly-online worker
|
// registerWorker register an newly-online worker
|
||||||
func (s *managerServer) registerWorker(c *gin.Context) {
|
func (s *Manager) registerWorker(c *gin.Context) {
|
||||||
var _worker WorkerStatus
|
var _worker WorkerStatus
|
||||||
c.BindJSON(&_worker)
|
c.BindJSON(&_worker)
|
||||||
newWorker, err := s.adapter.CreateWorker(_worker)
|
newWorker, err := s.adapter.CreateWorker(_worker)
|
||||||
@ -80,7 +167,7 @@ func (s *managerServer) registerWorker(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// listJobsOfWorker respond with all the jobs of the specified worker
|
// listJobsOfWorker respond with all the jobs of the specified worker
|
||||||
func (s *managerServer) listJobsOfWorker(c *gin.Context) {
|
func (s *Manager) listJobsOfWorker(c *gin.Context) {
|
||||||
workerID := c.Param("id")
|
workerID := c.Param("id")
|
||||||
mirrorStatusList, err := s.adapter.ListMirrorStatus(workerID)
|
mirrorStatusList, err := s.adapter.ListMirrorStatus(workerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -94,13 +181,13 @@ func (s *managerServer) listJobsOfWorker(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, mirrorStatusList)
|
c.JSON(http.StatusOK, mirrorStatusList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *managerServer) returnErrJSON(c *gin.Context, code int, err error) {
|
func (s *Manager) returnErrJSON(c *gin.Context, code int, err error) {
|
||||||
c.JSON(code, gin.H{
|
c.JSON(code, gin.H{
|
||||||
_errorKey: err.Error(),
|
_errorKey: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *managerServer) updateJobOfWorker(c *gin.Context) {
|
func (s *Manager) updateJobOfWorker(c *gin.Context) {
|
||||||
workerID := c.Param("id")
|
workerID := c.Param("id")
|
||||||
var status MirrorStatus
|
var status MirrorStatus
|
||||||
c.BindJSON(&status)
|
c.BindJSON(&status)
|
||||||
@ -117,7 +204,7 @@ func (s *managerServer) updateJobOfWorker(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, newStatus)
|
c.JSON(http.StatusOK, newStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *managerServer) handleClientCmd(c *gin.Context) {
|
func (s *Manager) handleClientCmd(c *gin.Context) {
|
||||||
var clientCmd ClientCmd
|
var clientCmd ClientCmd
|
||||||
c.BindJSON(&clientCmd)
|
c.BindJSON(&clientCmd)
|
||||||
workerID := clientCmd.WorkerID
|
workerID := clientCmd.WorkerID
|
||||||
@ -153,44 +240,3 @@ func (s *managerServer) handleClientCmd(c *gin.Context) {
|
|||||||
// TODO: check response for success
|
// TODO: check response for success
|
||||||
c.JSON(http.StatusOK, gin.H{_infoKey: "successfully send command to worker " + workerID})
|
c.JSON(http.StatusOK, gin.H{_infoKey: "successfully send command to worker " + workerID})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *managerServer) setDBAdapter(adapter dbAdapter) {
|
|
||||||
s.adapter = adapter
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeHTTPServer(debug bool) *managerServer {
|
|
||||||
// create gin engine
|
|
||||||
if !debug {
|
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
}
|
|
||||||
s := &managerServer{
|
|
||||||
gin.Default(),
|
|
||||||
nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
// common log middleware
|
|
||||||
s.Use(contextErrorLogger)
|
|
||||||
|
|
||||||
s.GET("/ping", func(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, gin.H{_infoKey: "pong"})
|
|
||||||
})
|
|
||||||
// list jobs, status page
|
|
||||||
s.GET("/jobs", s.listAllJobs)
|
|
||||||
|
|
||||||
// list workers
|
|
||||||
s.GET("/workers", s.listWorkers)
|
|
||||||
// worker online
|
|
||||||
s.POST("/workers", s.registerWorker)
|
|
||||||
|
|
||||||
// workerID should be valid in this route group
|
|
||||||
workerValidateGroup := s.Group("/workers", s.workerIDValidator)
|
|
||||||
// get job list
|
|
||||||
workerValidateGroup.GET(":id/jobs", s.listJobsOfWorker)
|
|
||||||
// post job status
|
|
||||||
workerValidateGroup.POST(":id/jobs/:job", s.updateJobOfWorker)
|
|
||||||
|
|
||||||
// for tunasynctl to post commands
|
|
||||||
s.POST("/cmd", s.handleClientCmd)
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,7 @@ const (
|
|||||||
func TestHTTPServer(t *testing.T) {
|
func TestHTTPServer(t *testing.T) {
|
||||||
Convey("HTTP server should work", t, func(ctx C) {
|
Convey("HTTP server should work", t, func(ctx C) {
|
||||||
InitLogger(true, true, false)
|
InitLogger(true, true, false)
|
||||||
s := makeHTTPServer(false)
|
s := GetTUNASyncManager(&Config{Debug: false})
|
||||||
So(s, ShouldNotBeNil)
|
So(s, ShouldNotBeNil)
|
||||||
s.setDBAdapter(&mockDBAdapter{
|
s.setDBAdapter(&mockDBAdapter{
|
||||||
workerStore: map[string]WorkerStatus{
|
workerStore: map[string]WorkerStatus{
|
||||||
@ -35,7 +35,7 @@ func TestHTTPServer(t *testing.T) {
|
|||||||
port := rand.Intn(10000) + 20000
|
port := rand.Intn(10000) + 20000
|
||||||
baseURL := fmt.Sprintf("http://127.0.0.1:%d", port)
|
baseURL := fmt.Sprintf("http://127.0.0.1:%d", port)
|
||||||
go func() {
|
go func() {
|
||||||
s.Run(fmt.Sprintf("127.0.0.1:%d", port))
|
s.engine.Run(fmt.Sprintf("127.0.0.1:%d", port))
|
||||||
}()
|
}()
|
||||||
time.Sleep(50 * time.Microsecond)
|
time.Sleep(50 * time.Microsecond)
|
||||||
resp, err := http.Get(baseURL + "/ping")
|
resp, err := http.Get(baseURL + "/ping")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user