[MM-48883] Remove app package dependency for products (#21853)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
61317883bf
Коммит
8d90c7042f
@@ -23,6 +23,8 @@ import (
|
|||||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const ServerKey product.ServiceKey = "server"
|
||||||
|
|
||||||
// licenseSvc is added to act as a starting point for future integrated products.
|
// licenseSvc is added to act as a starting point for future integrated products.
|
||||||
// It has the same signature and functionality with the license related APIs of the plugin-api.
|
// It has the same signature and functionality with the license related APIs of the plugin-api.
|
||||||
type licenseSvc interface {
|
type licenseSvc interface {
|
||||||
@@ -86,19 +88,24 @@ type Channels struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterProduct("channels", ProductManifest{
|
product.RegisterProduct("channels", product.Manifest{
|
||||||
Initializer: func(s *Server, services map[ServiceKey]any) (Product, error) {
|
Initializer: func(services map[product.ServiceKey]any) (product.Product, error) {
|
||||||
return NewChannels(s, services)
|
return NewChannels(services)
|
||||||
},
|
},
|
||||||
Dependencies: map[ServiceKey]struct{}{
|
Dependencies: map[product.ServiceKey]struct{}{
|
||||||
ConfigKey: {},
|
ServerKey: {},
|
||||||
LicenseKey: {},
|
product.ConfigKey: {},
|
||||||
FilestoreKey: {},
|
product.LicenseKey: {},
|
||||||
|
product.FilestoreKey: {},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
|
func NewChannels(services map[product.ServiceKey]any) (*Channels, error) {
|
||||||
|
s, ok := services[ServerKey].(*Server)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("server not passed")
|
||||||
|
}
|
||||||
ch := &Channels{
|
ch := &Channels{
|
||||||
srv: s,
|
srv: s,
|
||||||
imageProxy: imageproxy.MakeImageProxy(s.platform, s.httpService, s.Log()),
|
imageProxy: imageproxy.MakeImageProxy(s.platform, s.httpService, s.Log()),
|
||||||
@@ -112,10 +119,10 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
|
|||||||
// 2. Add the field to *Channels
|
// 2. Add the field to *Channels
|
||||||
// 3. Add the service key to the slice.
|
// 3. Add the service key to the slice.
|
||||||
// 4. Add a new case in the switch statement.
|
// 4. Add a new case in the switch statement.
|
||||||
requiredServices := []ServiceKey{
|
requiredServices := []product.ServiceKey{
|
||||||
ConfigKey,
|
product.ConfigKey,
|
||||||
LicenseKey,
|
product.LicenseKey,
|
||||||
FilestoreKey,
|
product.FilestoreKey,
|
||||||
}
|
}
|
||||||
for _, svcKey := range requiredServices {
|
for _, svcKey := range requiredServices {
|
||||||
svc, ok := services[svcKey]
|
svc, ok := services[svcKey]
|
||||||
@@ -124,19 +131,19 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
|
|||||||
}
|
}
|
||||||
switch svcKey {
|
switch svcKey {
|
||||||
// Keep adding more services here
|
// Keep adding more services here
|
||||||
case ConfigKey:
|
case product.ConfigKey:
|
||||||
cfgSvc, ok := svc.(product.ConfigService)
|
cfgSvc, ok := svc.(product.ConfigService)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("Config service did not satisfy ConfigSvc interface")
|
return nil, errors.New("Config service did not satisfy ConfigSvc interface")
|
||||||
}
|
}
|
||||||
ch.cfgSvc = cfgSvc
|
ch.cfgSvc = cfgSvc
|
||||||
case FilestoreKey:
|
case product.FilestoreKey:
|
||||||
filestore, ok := svc.(filestore.FileBackend)
|
filestore, ok := svc.(filestore.FileBackend)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("Filestore service did not satisfy FileBackend interface")
|
return nil, errors.New("Filestore service did not satisfy FileBackend interface")
|
||||||
}
|
}
|
||||||
ch.filestore = filestore
|
ch.filestore = filestore
|
||||||
case LicenseKey:
|
case product.LicenseKey:
|
||||||
svc, ok := svc.(licenseSvc)
|
svc, ok := svc.(licenseSvc)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("License service did not satisfy licenseSvc interface")
|
return nil, errors.New("License service did not satisfy licenseSvc interface")
|
||||||
@@ -198,7 +205,7 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ch.routerSvc = newRouterService()
|
ch.routerSvc = newRouterService()
|
||||||
services[RouterKey] = ch.routerSvc
|
services[product.RouterKey] = ch.routerSvc
|
||||||
|
|
||||||
// Setup routes.
|
// Setup routes.
|
||||||
pluginsRoute := ch.srv.Router.PathPrefix("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}").Subrouter()
|
pluginsRoute := ch.srv.Router.PathPrefix("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}").Subrouter()
|
||||||
@@ -206,29 +213,29 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
|
|||||||
pluginsRoute.HandleFunc("/public/{public_file:.*}", ch.ServePluginPublicRequest)
|
pluginsRoute.HandleFunc("/public/{public_file:.*}", ch.ServePluginPublicRequest)
|
||||||
pluginsRoute.HandleFunc("/{anything:.*}", ch.ServePluginRequest)
|
pluginsRoute.HandleFunc("/{anything:.*}", ch.ServePluginRequest)
|
||||||
|
|
||||||
services[PostKey] = &postServiceWrapper{
|
services[product.PostKey] = &postServiceWrapper{
|
||||||
app: &App{ch: ch},
|
app: &App{ch: ch},
|
||||||
}
|
}
|
||||||
|
|
||||||
services[PermissionsKey] = &permissionsServiceWrapper{
|
services[product.PermissionsKey] = &permissionsServiceWrapper{
|
||||||
app: &App{ch: ch},
|
app: &App{ch: ch},
|
||||||
}
|
}
|
||||||
|
|
||||||
services[TeamKey] = &teamServiceWrapper{
|
services[product.TeamKey] = &teamServiceWrapper{
|
||||||
app: &App{ch: ch},
|
app: &App{ch: ch},
|
||||||
}
|
}
|
||||||
|
|
||||||
services[BotKey] = &botServiceWrapper{
|
services[product.BotKey] = &botServiceWrapper{
|
||||||
app: &App{ch: ch},
|
app: &App{ch: ch},
|
||||||
}
|
}
|
||||||
|
|
||||||
services[HooksKey] = &hooksService{
|
services[product.HooksKey] = &hooksService{
|
||||||
ch: ch,
|
ch: ch,
|
||||||
}
|
}
|
||||||
|
|
||||||
services[UserKey] = &App{ch: ch}
|
services[product.UserKey] = &App{ch: ch}
|
||||||
|
|
||||||
services[PreferencesKey] = &preferencesServiceWrapper{
|
services[product.PreferencesKey] = &preferencesServiceWrapper{
|
||||||
app: &App{ch: ch},
|
app: &App{ch: ch},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ type licenseWrapper struct {
|
|||||||
srv *Server
|
srv *Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *licenseWrapper) Name() ServiceKey {
|
func (w *licenseWrapper) Name() product.ServiceKey {
|
||||||
return LicenseKey
|
return product.LicenseKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *licenseWrapper) GetLicense() *model.License {
|
func (w *licenseWrapper) GetLicense() *model.License {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/mattermost/mattermost-server/v6/app/platform"
|
"github.com/mattermost/mattermost-server/v6/app/platform"
|
||||||
"github.com/mattermost/mattermost-server/v6/config"
|
"github.com/mattermost/mattermost-server/v6/config"
|
||||||
"github.com/mattermost/mattermost-server/v6/model"
|
"github.com/mattermost/mattermost-server/v6/model"
|
||||||
|
"github.com/mattermost/mattermost-server/v6/product"
|
||||||
fmocks "github.com/mattermost/mattermost-server/v6/shared/filestore/mocks"
|
fmocks "github.com/mattermost/mattermost-server/v6/shared/filestore/mocks"
|
||||||
"github.com/mattermost/mattermost-server/v6/shared/i18n"
|
"github.com/mattermost/mattermost-server/v6/shared/i18n"
|
||||||
"github.com/mattermost/mattermost-server/v6/store/storetest/mocks"
|
"github.com/mattermost/mattermost-server/v6/store/storetest/mocks"
|
||||||
@@ -1440,7 +1441,7 @@ func TestPushNotificationRace(t *testing.T) {
|
|||||||
Return(&model.Preference{Value: "test"}, nil)
|
Return(&model.Preference{Value: "test"}, nil)
|
||||||
mockStore.On("Preference").Return(&mockPreferenceStore)
|
mockStore.On("Preference").Return(&mockPreferenceStore)
|
||||||
s := &Server{
|
s := &Server{
|
||||||
products: make(map[string]Product),
|
products: make(map[string]product.Product),
|
||||||
Router: mux.NewRouter(),
|
Router: mux.NewRouter(),
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
@@ -1449,12 +1450,13 @@ func TestPushNotificationRace(t *testing.T) {
|
|||||||
}, platform.SetFileStore(&fmocks.FileBackend{}))
|
}, platform.SetFileStore(&fmocks.FileBackend{}))
|
||||||
s.SetStore(mockStore)
|
s.SetStore(mockStore)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
serviceMap := map[ServiceKey]any{
|
serviceMap := map[product.ServiceKey]any{
|
||||||
ConfigKey: s.platform,
|
ServerKey: s,
|
||||||
LicenseKey: &licenseWrapper{s},
|
product.ConfigKey: s.platform,
|
||||||
FilestoreKey: s.FileBackend(),
|
product.LicenseKey: &licenseWrapper{s},
|
||||||
|
product.FilestoreKey: s.FileBackend(),
|
||||||
}
|
}
|
||||||
ch, err := NewChannels(s, serviceMap)
|
ch, err := NewChannels(serviceMap)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
s.products["channels"] = ch
|
s.products["channels"] = ch
|
||||||
|
|
||||||
|
|||||||
@@ -6,27 +6,13 @@ package app
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/v6/product"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Product interface {
|
|
||||||
Start() error
|
|
||||||
Stop() error
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProductManifest struct {
|
|
||||||
Initializer func(*Server, map[ServiceKey]any) (Product, error)
|
|
||||||
Dependencies map[ServiceKey]struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var products = make(map[string]ProductManifest)
|
|
||||||
|
|
||||||
func RegisterProduct(name string, m ProductManifest) {
|
|
||||||
products[name] = m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) initializeProducts(
|
func (s *Server) initializeProducts(
|
||||||
productMap map[string]ProductManifest,
|
productMap map[string]product.Manifest,
|
||||||
serviceMap map[ServiceKey]any,
|
serviceMap map[product.ServiceKey]any,
|
||||||
) error {
|
) error {
|
||||||
// create a product map to consume
|
// create a product map to consume
|
||||||
pmap := make(map[string]struct{})
|
pmap := make(map[string]struct{})
|
||||||
@@ -57,7 +43,7 @@ func (s *Server) initializeProducts(
|
|||||||
|
|
||||||
// some products can register themselves/their services
|
// some products can register themselves/their services
|
||||||
initializer := manifest.Initializer
|
initializer := manifest.Initializer
|
||||||
prod, err := initializer(s, serviceMap)
|
prod, err := initializer(serviceMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error initializing product %q: %w", product, err)
|
return fmt.Errorf("error initializing product %q: %w", product, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package app
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/v6/product"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ const (
|
|||||||
|
|
||||||
type productA struct{}
|
type productA struct{}
|
||||||
|
|
||||||
func newProductA(s *Server, m map[ServiceKey]any) (Product, error) {
|
func newProductA(m map[product.ServiceKey]any) (product.Product, error) {
|
||||||
m[testSrvKey1] = nil
|
m[testSrvKey1] = nil
|
||||||
return &productA{}, nil
|
return &productA{}, nil
|
||||||
}
|
}
|
||||||
@@ -26,7 +27,7 @@ func (p *productA) Stop() error { return nil }
|
|||||||
|
|
||||||
type productB struct{}
|
type productB struct{}
|
||||||
|
|
||||||
func newProductB(s *Server, m map[ServiceKey]any) (Product, error) {
|
func newProductB(m map[product.ServiceKey]any) (product.Product, error) {
|
||||||
m[testSrvKey2] = nil
|
m[testSrvKey2] = nil
|
||||||
return &productB{}, nil
|
return &productB{}, nil
|
||||||
}
|
}
|
||||||
@@ -36,35 +37,35 @@ func (p *productB) Stop() error { return nil }
|
|||||||
|
|
||||||
func TestInitializeProducts(t *testing.T) {
|
func TestInitializeProducts(t *testing.T) {
|
||||||
t.Run("2 products and no circular dependency", func(t *testing.T) {
|
t.Run("2 products and no circular dependency", func(t *testing.T) {
|
||||||
serviceMap := map[ServiceKey]any{
|
serviceMap := map[product.ServiceKey]any{
|
||||||
ConfigKey: nil,
|
product.ConfigKey: nil,
|
||||||
LicenseKey: nil,
|
product.LicenseKey: nil,
|
||||||
FilestoreKey: nil,
|
product.FilestoreKey: nil,
|
||||||
ClusterKey: nil,
|
product.ClusterKey: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
products := map[string]ProductManifest{
|
products := map[string]product.Manifest{
|
||||||
"productA": {
|
"productA": {
|
||||||
Initializer: newProductA,
|
Initializer: newProductA,
|
||||||
Dependencies: map[ServiceKey]struct{}{
|
Dependencies: map[product.ServiceKey]struct{}{
|
||||||
ConfigKey: {},
|
product.ConfigKey: {},
|
||||||
LicenseKey: {},
|
product.LicenseKey: {},
|
||||||
FilestoreKey: {},
|
product.FilestoreKey: {},
|
||||||
ClusterKey: {},
|
product.ClusterKey: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"productB": {
|
"productB": {
|
||||||
Initializer: newProductB,
|
Initializer: newProductB,
|
||||||
Dependencies: map[ServiceKey]struct{}{
|
Dependencies: map[product.ServiceKey]struct{}{
|
||||||
ConfigKey: {},
|
product.ConfigKey: {},
|
||||||
testSrvKey1: {},
|
testSrvKey1: {},
|
||||||
FilestoreKey: {},
|
product.FilestoreKey: {},
|
||||||
ClusterKey: {},
|
product.ClusterKey: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
products: make(map[string]Product),
|
products: make(map[string]product.Product),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.initializeProducts(products, serviceMap)
|
err := server.initializeProducts(products, serviceMap)
|
||||||
@@ -73,36 +74,36 @@ func TestInitializeProducts(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("2 products and circular dependency", func(t *testing.T) {
|
t.Run("2 products and circular dependency", func(t *testing.T) {
|
||||||
serviceMap := map[ServiceKey]any{
|
serviceMap := map[product.ServiceKey]any{
|
||||||
ConfigKey: nil,
|
product.ConfigKey: nil,
|
||||||
LicenseKey: nil,
|
product.LicenseKey: nil,
|
||||||
FilestoreKey: nil,
|
product.FilestoreKey: nil,
|
||||||
ClusterKey: nil,
|
product.ClusterKey: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
products := map[string]ProductManifest{
|
products := map[string]product.Manifest{
|
||||||
"productA": {
|
"productA": {
|
||||||
Initializer: newProductA,
|
Initializer: newProductA,
|
||||||
Dependencies: map[ServiceKey]struct{}{
|
Dependencies: map[product.ServiceKey]struct{}{
|
||||||
ConfigKey: {},
|
product.ConfigKey: {},
|
||||||
LicenseKey: {},
|
product.LicenseKey: {},
|
||||||
FilestoreKey: {},
|
product.FilestoreKey: {},
|
||||||
ClusterKey: {},
|
product.ClusterKey: {},
|
||||||
testSrvKey2: {},
|
testSrvKey2: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"productB": {
|
"productB": {
|
||||||
Initializer: newProductB,
|
Initializer: newProductB,
|
||||||
Dependencies: map[ServiceKey]struct{}{
|
Dependencies: map[product.ServiceKey]struct{}{
|
||||||
ConfigKey: {},
|
product.ConfigKey: {},
|
||||||
testSrvKey1: {},
|
testSrvKey1: {},
|
||||||
FilestoreKey: {},
|
product.FilestoreKey: {},
|
||||||
ClusterKey: {},
|
product.ClusterKey: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
products: make(map[string]Product),
|
products: make(map[string]product.Product),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.initializeProducts(products, serviceMap)
|
err := server.initializeProducts(products, serviceMap)
|
||||||
@@ -110,19 +111,19 @@ func TestInitializeProducts(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("2 products and one w/o any dependency", func(t *testing.T) {
|
t.Run("2 products and one w/o any dependency", func(t *testing.T) {
|
||||||
serviceMap := map[ServiceKey]any{
|
serviceMap := map[product.ServiceKey]any{
|
||||||
ConfigKey: nil,
|
product.ConfigKey: nil,
|
||||||
LicenseKey: nil,
|
product.LicenseKey: nil,
|
||||||
FilestoreKey: nil,
|
product.FilestoreKey: nil,
|
||||||
ClusterKey: nil,
|
product.ClusterKey: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
products := map[string]ProductManifest{
|
products := map[string]product.Manifest{
|
||||||
"productA": {
|
"productA": {
|
||||||
Initializer: newProductA,
|
Initializer: newProductA,
|
||||||
Dependencies: map[ServiceKey]struct{}{
|
Dependencies: map[product.ServiceKey]struct{}{
|
||||||
ConfigKey: {},
|
product.ConfigKey: {},
|
||||||
LicenseKey: {},
|
product.LicenseKey: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"productB": {
|
"productB": {
|
||||||
@@ -130,7 +131,7 @@ func TestInitializeProducts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
server := &Server{
|
server := &Server{
|
||||||
products: make(map[string]Product),
|
products: make(map[string]product.Product),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.initializeProducts(products, serviceMap)
|
err := server.initializeProducts(products, serviceMap)
|
||||||
|
|||||||
@@ -75,30 +75,6 @@ import (
|
|||||||
// declaring this as var to allow overriding in tests
|
// declaring this as var to allow overriding in tests
|
||||||
var SentryDSN = "placeholder_sentry_dsn"
|
var SentryDSN = "placeholder_sentry_dsn"
|
||||||
|
|
||||||
type ServiceKey string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelKey ServiceKey = "channel"
|
|
||||||
ConfigKey ServiceKey = "config"
|
|
||||||
LicenseKey ServiceKey = "license"
|
|
||||||
FilestoreKey ServiceKey = "filestore"
|
|
||||||
FileInfoStoreKey ServiceKey = "fileinfostore"
|
|
||||||
ClusterKey ServiceKey = "cluster"
|
|
||||||
CloudKey ServiceKey = "cloud"
|
|
||||||
PostKey ServiceKey = "post"
|
|
||||||
TeamKey ServiceKey = "team"
|
|
||||||
UserKey ServiceKey = "user"
|
|
||||||
PermissionsKey ServiceKey = "permissions"
|
|
||||||
RouterKey ServiceKey = "router"
|
|
||||||
BotKey ServiceKey = "bot"
|
|
||||||
LogKey ServiceKey = "log"
|
|
||||||
HooksKey ServiceKey = "hooks"
|
|
||||||
KVStoreKey ServiceKey = "kvstore"
|
|
||||||
StoreKey ServiceKey = "storekey"
|
|
||||||
SystemKey ServiceKey = "systemkey"
|
|
||||||
PreferencesKey ServiceKey = "preferenceskey"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// RootRouter is the starting point for all HTTP requests to the server.
|
// RootRouter is the starting point for all HTTP requests to the server.
|
||||||
RootRouter *mux.Router
|
RootRouter *mux.Router
|
||||||
@@ -160,7 +136,7 @@ type Server struct {
|
|||||||
|
|
||||||
tracer *tracing.Tracer
|
tracer *tracing.Tracer
|
||||||
|
|
||||||
products map[string]Product
|
products map[string]product.Product
|
||||||
|
|
||||||
hooksManager *product.HooksManager
|
hooksManager *product.HooksManager
|
||||||
}
|
}
|
||||||
@@ -187,7 +163,7 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
RootRouter: rootRouter,
|
RootRouter: rootRouter,
|
||||||
LocalRouter: localRouter,
|
LocalRouter: localRouter,
|
||||||
timezones: timezones.New(),
|
timezones: timezones.New(),
|
||||||
products: make(map[string]Product),
|
products: make(map[string]product.Product),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
@@ -262,24 +238,25 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
// ensure app implements `product.UserService`
|
// ensure app implements `product.UserService`
|
||||||
var _ product.UserService = (*App)(nil)
|
var _ product.UserService = (*App)(nil)
|
||||||
|
|
||||||
serviceMap := map[ServiceKey]any{
|
serviceMap := map[product.ServiceKey]any{
|
||||||
ChannelKey: &channelsWrapper{srv: s},
|
ServerKey: s,
|
||||||
ConfigKey: s.platform,
|
product.ChannelKey: &channelsWrapper{srv: s},
|
||||||
LicenseKey: s.licenseWrapper,
|
product.ConfigKey: s.platform,
|
||||||
FilestoreKey: s.platform.FileBackend(),
|
product.LicenseKey: s.licenseWrapper,
|
||||||
FileInfoStoreKey: &fileInfoWrapper{srv: s},
|
product.FilestoreKey: s.platform.FileBackend(),
|
||||||
ClusterKey: s.platform,
|
product.FileInfoStoreKey: &fileInfoWrapper{srv: s},
|
||||||
UserKey: New(ServerConnector(s.Channels())),
|
product.ClusterKey: s.platform,
|
||||||
LogKey: s.platform.Log(),
|
product.UserKey: New(ServerConnector(s.Channels())),
|
||||||
CloudKey: &cloudWrapper{cloud: s.Cloud},
|
product.LogKey: s.platform.Log(),
|
||||||
KVStoreKey: s.platform,
|
product.CloudKey: &cloudWrapper{cloud: s.Cloud},
|
||||||
StoreKey: store.NewStoreServiceAdapter(s.Store()),
|
product.KVStoreKey: s.platform,
|
||||||
SystemKey: &systemServiceAdapter{server: s},
|
product.StoreKey: store.NewStoreServiceAdapter(s.Store()),
|
||||||
|
product.SystemKey: &systemServiceAdapter{server: s},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Initialize products.
|
// Step 4: Initialize products.
|
||||||
// Depends on s.httpService.
|
// Depends on s.httpService.
|
||||||
err = s.initializeProducts(products, serviceMap)
|
err = s.initializeProducts(product.GetProducts(), serviceMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to initialize products")
|
return nil, errors.Wrap(err, "failed to initialize products")
|
||||||
}
|
}
|
||||||
|
|||||||
24
product/product.go
Обычный файл
24
product/product.go
Обычный файл
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
package product
|
||||||
|
|
||||||
|
type Product interface {
|
||||||
|
Start() error
|
||||||
|
Stop() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Manifest struct {
|
||||||
|
Initializer func(map[ServiceKey]any) (Product, error)
|
||||||
|
Dependencies map[ServiceKey]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var products = make(map[string]Manifest)
|
||||||
|
|
||||||
|
func RegisterProduct(name string, m Manifest) {
|
||||||
|
products[name] = m
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProducts() map[string]Manifest {
|
||||||
|
return products
|
||||||
|
}
|
||||||
28
product/service.go
Обычный файл
28
product/service.go
Обычный файл
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
package product
|
||||||
|
|
||||||
|
type ServiceKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ChannelKey ServiceKey = "channel"
|
||||||
|
ConfigKey ServiceKey = "config"
|
||||||
|
LicenseKey ServiceKey = "license"
|
||||||
|
FilestoreKey ServiceKey = "filestore"
|
||||||
|
FileInfoStoreKey ServiceKey = "fileinfostore"
|
||||||
|
ClusterKey ServiceKey = "cluster"
|
||||||
|
CloudKey ServiceKey = "cloud"
|
||||||
|
PostKey ServiceKey = "post"
|
||||||
|
TeamKey ServiceKey = "team"
|
||||||
|
UserKey ServiceKey = "user"
|
||||||
|
PermissionsKey ServiceKey = "permissions"
|
||||||
|
RouterKey ServiceKey = "router"
|
||||||
|
BotKey ServiceKey = "bot"
|
||||||
|
LogKey ServiceKey = "log"
|
||||||
|
HooksKey ServiceKey = "hooks"
|
||||||
|
KVStoreKey ServiceKey = "kvstore"
|
||||||
|
StoreKey ServiceKey = "storekey"
|
||||||
|
SystemKey ServiceKey = "systemkey"
|
||||||
|
PreferencesKey ServiceKey = "preferenceskey"
|
||||||
|
)
|
||||||
Ссылка в новой задаче
Block a user