This is more of a general refactor of the initialization process which should allow us to pass services more easily. The changes are minimal to keep the scope limited. For now, the objective is to pass the file service to the Channels product. For that, it was required to move some of the enterprise interfaces under Channels from Server. We also create a filestore field in the server to avoid creating filestore reference every time we make a filestore operation. This will be later passed on to the Channels product. Also removed an unnecessary test. The test was working so far because we were creating the filebackend every time for every request. But we should go via UpdateConfig call which would fail, were we to assign an invalid filestore name. So we were actually testing for a different thing. Therefore, removed the test. ```release-note NONE ```
176 строки
5.2 KiB
Go
176 строки
5.2 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/mattermost/mattermost-server/v6/einterfaces"
|
|
"github.com/mattermost/mattermost-server/v6/model"
|
|
"github.com/mattermost/mattermost-server/v6/services/httpservice"
|
|
"github.com/mattermost/mattermost-server/v6/services/imageproxy"
|
|
"github.com/mattermost/mattermost-server/v6/services/searchengine"
|
|
"github.com/mattermost/mattermost-server/v6/services/timezones"
|
|
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
|
"github.com/mattermost/mattermost-server/v6/shared/templates"
|
|
"github.com/mattermost/mattermost-server/v6/utils"
|
|
)
|
|
|
|
// App is a pure functional component that does not have any fields, except Server.
|
|
// It is a request-scoped struct constructed every time a request hits the server,
|
|
// and its only purpose is to provide business logic to Server via its methods.
|
|
type App struct {
|
|
ch *Channels
|
|
}
|
|
|
|
func New(options ...AppOption) *App {
|
|
app := &App{}
|
|
|
|
for _, option := range options {
|
|
option(app)
|
|
}
|
|
|
|
return app
|
|
}
|
|
|
|
func (a *App) TelemetryId() string {
|
|
return a.Srv().TelemetryId()
|
|
}
|
|
|
|
func (s *Server) TemplatesContainer() *templates.Container {
|
|
return s.htmlTemplateWatcher
|
|
}
|
|
|
|
func (a *App) Handle404(w http.ResponseWriter, r *http.Request) {
|
|
ipAddress := utils.GetIPAddress(r, a.Config().ServiceSettings.TrustedProxyIPHeader)
|
|
mlog.Debug("not found handler triggered", mlog.String("path", r.URL.Path), mlog.Int("code", 404), mlog.String("ip", ipAddress))
|
|
|
|
if *a.Config().ServiceSettings.WebserverMode == "disabled" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
utils.RenderWebAppError(a.Config(), w, r, model.NewAppError("Handle404", "api.context.404.app_error", nil, "", http.StatusNotFound), a.AsymmetricSigningKey())
|
|
}
|
|
|
|
func (s *Server) getSystemInstallDate() (int64, *model.AppError) {
|
|
systemData, err := s.Store.System().GetByName(model.SystemInstallationDateKey)
|
|
if err != nil {
|
|
return 0, model.NewAppError("getSystemInstallDate", "app.system.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
value, err := strconv.ParseInt(systemData.Value, 10, 64)
|
|
if err != nil {
|
|
return 0, model.NewAppError("getSystemInstallDate", "app.system_install_date.parse_int.app_error", nil, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
return value, nil
|
|
}
|
|
|
|
func (s *Server) getFirstServerRunTimestamp() (int64, *model.AppError) {
|
|
systemData, err := s.Store.System().GetByName(model.SystemFirstServerRunTimestampKey)
|
|
if err != nil {
|
|
return 0, model.NewAppError("getFirstServerRunTimestamp", "app.system.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
value, err := strconv.ParseInt(systemData.Value, 10, 64)
|
|
if err != nil {
|
|
return 0, model.NewAppError("getFirstServerRunTimestamp", "app.system_install_date.parse_int.app_error", nil, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
return value, nil
|
|
}
|
|
|
|
func (a *App) Channels() *Channels {
|
|
return a.ch
|
|
}
|
|
func (a *App) Srv() *Server {
|
|
return a.ch.srv
|
|
}
|
|
func (a *App) Log() *mlog.Logger {
|
|
return a.ch.srv.Log
|
|
}
|
|
func (a *App) NotificationsLog() *mlog.Logger {
|
|
return a.ch.srv.NotificationsLog
|
|
}
|
|
|
|
func (a *App) AccountMigration() einterfaces.AccountMigrationInterface {
|
|
return a.ch.AccountMigration
|
|
}
|
|
func (a *App) Cluster() einterfaces.ClusterInterface {
|
|
return a.ch.srv.Cluster
|
|
}
|
|
func (a *App) Compliance() einterfaces.ComplianceInterface {
|
|
return a.ch.Compliance
|
|
}
|
|
func (a *App) DataRetention() einterfaces.DataRetentionInterface {
|
|
return a.ch.DataRetention
|
|
}
|
|
func (a *App) SearchEngine() *searchengine.Broker {
|
|
return a.ch.srv.SearchEngine
|
|
}
|
|
func (a *App) Ldap() einterfaces.LdapInterface {
|
|
return a.ch.Ldap
|
|
}
|
|
func (a *App) MessageExport() einterfaces.MessageExportInterface {
|
|
return a.ch.MessageExport
|
|
}
|
|
func (a *App) Metrics() einterfaces.MetricsInterface {
|
|
return a.ch.srv.Metrics
|
|
}
|
|
func (a *App) Notification() einterfaces.NotificationInterface {
|
|
return a.ch.Notification
|
|
}
|
|
func (a *App) Saml() einterfaces.SamlInterface {
|
|
return a.ch.Saml
|
|
}
|
|
func (a *App) Cloud() einterfaces.CloudInterface {
|
|
return a.ch.srv.Cloud
|
|
}
|
|
func (a *App) HTTPService() httpservice.HTTPService {
|
|
return a.ch.srv.httpService
|
|
}
|
|
func (a *App) ImageProxy() *imageproxy.ImageProxy {
|
|
return a.ch.imageProxy
|
|
}
|
|
func (a *App) Timezones() *timezones.Timezones {
|
|
return a.ch.srv.timezones
|
|
}
|
|
func (a *App) License() *model.License {
|
|
return a.Srv().License()
|
|
}
|
|
|
|
func (a *App) DBHealthCheckWrite() error {
|
|
currentTime := strconv.FormatInt(time.Now().Unix(), 10)
|
|
|
|
return a.Srv().Store.System().SaveOrUpdate(&model.System{
|
|
Name: a.dbHealthCheckKey(),
|
|
Value: currentTime,
|
|
})
|
|
}
|
|
|
|
func (a *App) DBHealthCheckDelete() error {
|
|
_, err := a.Srv().Store.System().PermanentDeleteByName(a.dbHealthCheckKey())
|
|
return err
|
|
}
|
|
|
|
func (a *App) dbHealthCheckKey() string {
|
|
return fmt.Sprintf("health_check_%s", a.GetClusterId())
|
|
}
|
|
|
|
func (a *App) CheckIntegrity() <-chan model.IntegrityCheckResult {
|
|
return a.Srv().Store.CheckIntegrity()
|
|
}
|
|
|
|
func (a *App) SetChannels(ch *Channels) {
|
|
a.ch = ch
|
|
}
|
|
|
|
func (a *App) SetServer(srv *Server) {
|
|
a.ch.srv = srv
|
|
}
|
|
|
|
func (a *App) UpdateExpiredDNDStatuses() ([]*model.Status, error) {
|
|
return a.Srv().Store.Status().UpdateExpiredDNDStatuses()
|
|
}
|