From cefdc1b3f9d884aaa80c95f51fc9c0cfd8d06699 Mon Sep 17 00:00:00 2001 From: Carl Kittelberger Date: Tue, 10 Apr 2018 17:08:40 +0200 Subject: [PATCH] Refactor API for plugins. --- app/channels/channel_manager.go | 6 ++++ app/server.go | 40 ++++++++++++++++++--- app/servers/http/server.go | 60 ++++++++----------------------- plugins/descriptor.go | 5 +++ plugins/icecast/input/instance.go | 43 ++++++++++++++++++++-- plugins/icecast/input/plugin.go | 16 +++++---- plugins/interfaces.go | 20 +++++++++++ plugins/registration.go | 1 + 8 files changed, 133 insertions(+), 58 deletions(-) create mode 100644 plugins/interfaces.go create mode 100644 plugins/registration.go diff --git a/app/channels/channel_manager.go b/app/channels/channel_manager.go index 9d1e809..8ad31eb 100644 --- a/app/channels/channel_manager.go +++ b/app/channels/channel_manager.go @@ -10,6 +10,12 @@ type ChannelManager struct { channelsLock sync.RWMutex } +func NewChannelManager() *ChannelManager { + return &ChannelManager{ + channels: map[string]*Channel{}, + } +} + func (manager *ChannelManager) Channel(uuid string) *Channel { manager.channelsLock.RLock() defer manager.channelsLock.RUnlock() diff --git a/app/server.go b/app/server.go index 3c92429..0fe0e5a 100644 --- a/app/server.go +++ b/app/server.go @@ -1,11 +1,43 @@ package app import ( + "log" + "git.icedream.tech/icedream/uplink/app/channels" - "github.com/gin-gonic/gin" + "git.icedream.tech/icedream/uplink/app/servers/http" + "git.icedream.tech/icedream/uplink/plugins" ) -type Server struct { - *gin.Engine - *channels.ChannelManager +type App struct { + Server *httpserver.Server + ChannelManager *channels.ChannelManager + + plugins []plugins.PluginInstance +} + +func New() *App { + return &App{ + Server: httpserver.NewServer(), + ChannelManager: channels.NewChannelManager(), + + plugins: []plugins.PluginInstance{}, + } +} + +func (app *App) UsePlugin(plugin *plugins.Plugin) { + instance := plugin.Run() + app.plugins = append(app.plugins, instance) + log.Println("Plugin loaded:", plugin.Descriptor.Name) +} + +func (app *App) Init() { + for _, plugin := range app.plugins { + if p, ok := plugin.(plugins.ServerPlugin); ok { + p.SetServer(app.Server) + } + } +} + +func (app *App) Run() error { + return app.Server.Run() } diff --git a/app/servers/http/server.go b/app/servers/http/server.go index 3008944..6ac672d 100644 --- a/app/servers/http/server.go +++ b/app/servers/http/server.go @@ -1,60 +1,28 @@ package httpserver import ( - _ "git.icedream.tech/icedream/uplink/app" - "git.icedream.tech/icedream/uplink/app/authentication" - channels "git.icedream.tech/icedream/uplink/app/channels" - _ "git.icedream.tech/icedream/uplink/app/transcoders" - "net/http" "github.com/gin-gonic/gin" ) type Server struct { - Authenticator authentication.Authenticator - ChannelManager *channels.ChannelManager + Http *http.Server + Router *gin.Engine } -func (server *Server) Run() { - httpServer := new(http.Server) +func NewServer() *Server { + server := &Server{ + Http: new(http.Server), + Router: gin.New(), + } - router := gin.New() - router.POST("/:channel", func(ctx *gin.Context) { - channel := server.ChannelManager.Channel(ctx.Param("channel")) - if channel == nil { - ctx.Status(404) - return - } - if user, password, ok := ctx.Request.BasicAuth(); ok { - if !server.Authenticator.VerifyUsernameAndPassword(channel, user, password) { - ctx.Status(401) - return - } - } else { - ctx.Status(401) - return - } + server.Http.Handler = server.Router + server.Http.Addr = ":8000" - }) - - router.GET("/:channel", func(ctx *gin.Context) { - channel := server.ChannelManager.Channel(ctx.Param("channel")) - if channel == nil { - ctx.Status(404) - return - } - }) - - router.GET("/:channel/:stream", func(ctx *gin.Context) { - channel := server.ChannelManager.Channel(ctx.Param("channel")) - if channel == nil { - ctx.Status(404) - return - } - }) - - httpServer.Handler = router - httpServer.Addr = ":8000" - httpServer.ListenAndServe() + return server +} + +func (server *Server) Run() error { + return server.Http.ListenAndServe() } diff --git a/plugins/descriptor.go b/plugins/descriptor.go index 81a0074..53b4717 100644 --- a/plugins/descriptor.go +++ b/plugins/descriptor.go @@ -1,5 +1,10 @@ package plugins +type Plugin struct { + Descriptor PluginDescriptor + Run PluginRunner +} + type PluginDescriptor struct { Name string Version string diff --git a/plugins/icecast/input/instance.go b/plugins/icecast/input/instance.go index 0193db1..ab29849 100644 --- a/plugins/icecast/input/instance.go +++ b/plugins/icecast/input/instance.go @@ -1,11 +1,50 @@ package main -import "git.icedream.tech/icedream/uplink/app" +import ( + "git.icedream.tech/icedream/uplink/app" + "git.icedream.tech/icedream/uplink/app/servers/http" + "github.com/gin-gonic/gin" +) type pluginInstance struct { server *app.Server } -func (instance *pluginInstance) SetServer(server *app.Server) { +func (instance *pluginInstance) SetServer(server *httpserver.Server) { instance.server = server + + router := instance.server.Router + router.POST("/:channel", func(ctx *gin.Context) { + channel := server.ChannelManager.Channel(ctx.Param("channel")) + if channel == nil { + ctx.Status(404) + return + } + if user, password, ok := ctx.Request.BasicAuth(); ok { + if !server.Authenticator.VerifyUsernameAndPassword(channel, user, password) { + ctx.Status(401) + return + } + } else { + ctx.Status(401) + return + } + + }) + + router.GET("/:channel", func(ctx *gin.Context) { + channel := server.ChannelManager.Channel(ctx.Param("channel")) + if channel == nil { + ctx.Status(404) + return + } + }) + + router.GET("/:channel/:stream", func(ctx *gin.Context) { + channel := server.ChannelManager.Channel(ctx.Param("channel")) + if channel == nil { + ctx.Status(404) + return + } + }) } diff --git a/plugins/icecast/input/plugin.go b/plugins/icecast/input/plugin.go index 960dc17..1b04ee7 100644 --- a/plugins/icecast/input/plugin.go +++ b/plugins/icecast/input/plugin.go @@ -1,14 +1,18 @@ package main +import "C" + import ( "git.icedream.tech/icedream/uplink/plugins" ) -var Descriptor = plugins.PluginDescriptor{ - Name: "Icecast Input", - Description: "Allows for Icecast clients to stream to the server.", -} +var Plugin = &plugins.Plugin{ + Descriptor: plugins.PluginDescriptor{ + Name: "Icecast Input", + Description: "Allows for Icecast clients to stream to the server.", + }, -func Run() *pluginInstance { - return &pluginInstance{} + Run: func() plugins.PluginInstance { + return &pluginInstance{} + }, } diff --git a/plugins/interfaces.go b/plugins/interfaces.go new file mode 100644 index 0000000..e3a713c --- /dev/null +++ b/plugins/interfaces.go @@ -0,0 +1,20 @@ +package plugins + +import ( + "git.icedream.tech/icedream/uplink/app/servers/http" +) + +type PluginRunner func() PluginInstance + +type PluginInstance interface { +} + +type ServerPlugin interface { + PluginInstance + SetServer(*httpserver.Server) +} + +type ChannelPlugin interface { + PluginInstance + SetChannel(id string) +} diff --git a/plugins/registration.go b/plugins/registration.go new file mode 100644 index 0000000..d5c343e --- /dev/null +++ b/plugins/registration.go @@ -0,0 +1 @@ +package plugins