Add Product Interfaces (#20403)
* app: improve plugin interfaces * add documentation * improve doc * add error id * add more info to readme
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
7c1b8cd937
Коммит
39991d236b
@@ -50,6 +50,7 @@ type PrepackagedPlugin struct {
|
||||
// of active plugins.
|
||||
type Environment struct {
|
||||
registeredPlugins sync.Map
|
||||
registeredProducts sync.Map
|
||||
pluginHealthCheckJob *PluginHealthCheckJob
|
||||
logger *mlog.Logger
|
||||
metrics einterfaces.MetricsInterface
|
||||
@@ -300,6 +301,14 @@ func (env *Environment) Activate(id string) (manifest *model.Manifest, activated
|
||||
return pluginInfo.Manifest, true, nil
|
||||
}
|
||||
|
||||
func (env *Environment) AddProduct(productID string, hooks ProductHooks) {
|
||||
env.registeredProducts.Store(productID, newRegisteredProduct(productID, hooks))
|
||||
}
|
||||
|
||||
func (env *Environment) RemoveProduct(productID string) {
|
||||
env.registeredProducts.Delete(productID)
|
||||
}
|
||||
|
||||
func (env *Environment) RemovePlugin(id string) {
|
||||
if _, ok := env.registeredPlugins.Load(id); ok {
|
||||
env.registeredPlugins.Delete(id)
|
||||
@@ -481,6 +490,24 @@ func (env *Environment) RunMultiPluginHook(hookRunnerFunc func(hooks Hooks) bool
|
||||
return result
|
||||
})
|
||||
|
||||
env.registeredProducts.Range(func(key, value interface{}) bool {
|
||||
rp := value.(*registeredProduct)
|
||||
|
||||
if !rp.Implements(hookId) {
|
||||
return true
|
||||
}
|
||||
|
||||
hookStartTime := time.Now()
|
||||
result := hookRunnerFunc(rp.adapter)
|
||||
|
||||
if env.metrics != nil {
|
||||
elapsedTime := float64(time.Since(hookStartTime)) / float64(time.Second)
|
||||
env.metrics.ObservePluginMultiHookIterationDuration(rp.productID, elapsedTime)
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
if env.metrics != nil {
|
||||
elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
|
||||
env.metrics.ObservePluginMultiHookDuration(elapsedTime)
|
||||
|
||||
147
plugin/product.go
Обычный файл
147
plugin/product.go
Обычный файл
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
// ProductHooks is a subset of Hooks
|
||||
type ProductHooks interface {
|
||||
OnConfigurationChange() error
|
||||
MessageWillBePosted(ctx *Context, post *model.Post) (*model.Post, string)
|
||||
MessageWillBeUpdated(ctx *Context, newPost, oldPost *model.Post) (*model.Post, string)
|
||||
OnPluginClusterEvent(ctx *Context, ev model.PluginClusterEvent)
|
||||
OnWebSocketDisconnect(webConnID, userID string)
|
||||
OnWebSocketConnect(webConnID, userID string)
|
||||
WebSocketMessageHasBeenPosted(webConnID, userID string, req *model.WebSocketRequest)
|
||||
}
|
||||
|
||||
type registeredProduct struct {
|
||||
productID string
|
||||
implemented map[int]struct{}
|
||||
adapter Hooks
|
||||
}
|
||||
|
||||
func (rp *registeredProduct) Implements(hookId int) bool {
|
||||
_, ok := rp.implemented[hookId]
|
||||
return ok
|
||||
}
|
||||
|
||||
type hooksAdapter struct {
|
||||
productHooks ProductHooks
|
||||
}
|
||||
|
||||
func newRegisteredProduct(pluginID string, productHooks ProductHooks) *registeredProduct {
|
||||
return ®isteredProduct{
|
||||
productID: pluginID,
|
||||
implemented: map[int]struct{}{
|
||||
OnConfigurationChangeID: {},
|
||||
MessageWillBePostedID: {},
|
||||
MessageWillBeUpdatedID: {},
|
||||
OnPluginClusterEventID: {},
|
||||
OnWebSocketConnectID: {},
|
||||
OnWebSocketDisconnectID: {},
|
||||
WebSocketMessageHasBeenPostedID: {},
|
||||
},
|
||||
adapter: &hooksAdapter{
|
||||
productHooks: productHooks,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnActivate() error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) Implemented() ([]string, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnDeactivate() error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnConfigurationChange() error {
|
||||
return a.productHooks.OnConfigurationChange()
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) ServeHTTP(c *Context, w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
func (a *hooksAdapter) ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
||||
return nil, model.NewAppError("ExecuteCommand", "api.command.execute_command.start.app_error", nil, "not implemented", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) UserHasBeenCreated(c *Context, user *model.User) {}
|
||||
|
||||
func (a *hooksAdapter) UserWillLogIn(c *Context, user *model.User) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) UserHasLoggedIn(c *Context, user *model.User) {}
|
||||
|
||||
func (a *hooksAdapter) MessageWillBePosted(c *Context, post *model.Post) (*model.Post, string) {
|
||||
return a.productHooks.MessageWillBePosted(c, post)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) MessageWillBeUpdated(c *Context, newPost, oldPost *model.Post) (*model.Post, string) {
|
||||
return a.productHooks.MessageWillBeUpdated(c, newPost, oldPost)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) MessageHasBeenPosted(c *Context, post *model.Post) {}
|
||||
|
||||
func (a *hooksAdapter) MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post) {}
|
||||
|
||||
func (a *hooksAdapter) ChannelHasBeenCreated(c *Context, channel *model.Channel) {}
|
||||
|
||||
func (a *hooksAdapter) UserHasJoinedChannel(c *Context, channelMember *model.ChannelMember, actor *model.User) {
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) UserHasLeftChannel(c *Context, channelMember *model.ChannelMember, actor *model.User) {
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) UserHasJoinedTeam(c *Context, teamMember *model.TeamMember, actor *model.User) {
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) UserHasLeftTeam(c *Context, teamMember *model.TeamMember, actor *model.User) {}
|
||||
|
||||
func (a *hooksAdapter) FileWillBeUploaded(c *Context, info *model.FileInfo, file io.Reader, output io.Writer) (*model.FileInfo, string) {
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) ReactionHasBeenAdded(c *Context, reaction *model.Reaction) {}
|
||||
|
||||
func (a *hooksAdapter) ReactionHasBeenRemoved(c *Context, reaction *model.Reaction) {}
|
||||
|
||||
func (a *hooksAdapter) OnPluginClusterEvent(c *Context, ev model.PluginClusterEvent) {
|
||||
a.productHooks.OnPluginClusterEvent(c, ev)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnWebSocketConnect(webConnID, userID string) {
|
||||
a.productHooks.OnWebSocketConnect(webConnID, userID)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnWebSocketDisconnect(webConnID, userID string) {
|
||||
a.productHooks.OnWebSocketDisconnect(webConnID, userID)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) WebSocketMessageHasBeenPosted(webConnID, userID string, req *model.WebSocketRequest) {
|
||||
a.productHooks.WebSocketMessageHasBeenPosted(webConnID, userID, req)
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) RunDataRetention(nowTime, batchSize int64) (int64, error) {
|
||||
return -1, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnInstall(c *Context, event model.OnInstallEvent) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (a *hooksAdapter) OnSendDailyTelemetry() {}
|
||||
|
||||
func (a *hooksAdapter) OnCloudLimitsUpdated(limits *model.ProductLimits) {}
|
||||
Ссылка в новой задаче
Block a user