MM-40818: Refactor product initialization to happen late (#19658)
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 ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
768fe43d3a
Коммит
ab8de49f0a
@@ -153,7 +153,7 @@ func TestSyncLdap(t *testing.T) {
|
|||||||
includeRemovedMembers = args[1].(bool)
|
includeRemovedMembers = args[1].(bool)
|
||||||
ready <- true
|
ready <- true
|
||||||
}
|
}
|
||||||
th.App.Srv().Ldap = ldapMock
|
th.App.Channels().Ldap = ldapMock
|
||||||
|
|
||||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||||
_, err := client.SyncLdap(false)
|
_, err := client.SyncLdap(false)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func TestSamlCompleteCSRFPass(t *testing.T) {
|
|||||||
func TestSamlResetId(t *testing.T) {
|
func TestSamlResetId(t *testing.T) {
|
||||||
th := SetupEnterprise(t).InitBasic()
|
th := SetupEnterprise(t).InitBasic()
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
th.App.Srv().Saml = &mocks.SamlInterface{}
|
th.App.Channels().Saml = &mocks.SamlInterface{}
|
||||||
|
|
||||||
user := th.BasicUser
|
user := th.BasicUser
|
||||||
_, appErr := th.App.UpdateUserAuth(user.Id, &model.UserAuth{
|
_, appErr := th.App.UpdateUserAuth(user.Id, &model.UserAuth{
|
||||||
|
|||||||
@@ -95,11 +95,7 @@ func generateSupportPacket(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
now := time.Now()
|
now := time.Now()
|
||||||
outputZipFilename := fmt.Sprintf("mattermost_support_packet_%s.zip", now.Format("2006-01-02-03-04"))
|
outputZipFilename := fmt.Sprintf("mattermost_support_packet_%s.zip", now.Format("2006-01-02-03-04"))
|
||||||
|
|
||||||
fileStorageBackend, fileBackendErr := c.App.FileBackend()
|
fileStorageBackend := c.App.FileBackend()
|
||||||
if fileBackendErr != nil {
|
|
||||||
c.Err = fileBackendErr
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// We do this incase we get concurrent requests, we will always have a unique directory.
|
// We do this incase we get concurrent requests, we will always have a unique directory.
|
||||||
// This is to avoid the situation where we try to write to the same directory while we are trying to delete it (further down)
|
// This is to avoid the situation where we try to write to the same directory while we are trying to delete it (further down)
|
||||||
|
|||||||
@@ -57,20 +57,6 @@ func TestGetPing(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, model.StatusOk, status)
|
assert.Equal(t, model.StatusOk, status)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("unhealthy", func(t *testing.T) {
|
|
||||||
oldDriver := th.App.Config().FileSettings.DriverName
|
|
||||||
badDriver := "badDriverName"
|
|
||||||
th.App.Config().FileSettings.DriverName = &badDriver
|
|
||||||
defer func() {
|
|
||||||
th.App.Config().FileSettings.DriverName = oldDriver
|
|
||||||
}()
|
|
||||||
|
|
||||||
status, resp, err := client.GetPingWithServerStatus()
|
|
||||||
require.Error(t, err)
|
|
||||||
CheckInternalErrorStatus(t, resp)
|
|
||||||
assert.Equal(t, model.StatusUnhealthy, status)
|
|
||||||
})
|
|
||||||
}, "with server status")
|
}, "with server status")
|
||||||
|
|
||||||
th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
|
th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
|
||||||
|
|||||||
@@ -6503,7 +6503,7 @@ func TestPatchAndUpdateWithProviderAttributes(t *testing.T) {
|
|||||||
mock.Anything, // *model.User
|
mock.Anything, // *model.User
|
||||||
mock.Anything, // *model.Patch
|
mock.Anything, // *model.Patch
|
||||||
).Return("")
|
).Return("")
|
||||||
th.App.Srv().Ldap = ldapMock
|
th.App.Channels().Ldap = ldapMock
|
||||||
// CheckProviderAttributes should be called for both Patch and Update
|
// CheckProviderAttributes should be called for both Patch and Update
|
||||||
th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{})
|
th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{})
|
||||||
ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1)
|
ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1)
|
||||||
@@ -6524,7 +6524,7 @@ func TestPatchAndUpdateWithProviderAttributes(t *testing.T) {
|
|||||||
ldapMock.Mock.On(
|
ldapMock.Mock.On(
|
||||||
"CheckProviderAttributes", mock.Anything, mock.Anything, mock.Anything,
|
"CheckProviderAttributes", mock.Anything, mock.Anything, mock.Anything,
|
||||||
).Return("")
|
).Return("")
|
||||||
th.App.Srv().Ldap = ldapMock
|
th.App.Channels().Ldap = ldapMock
|
||||||
th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{})
|
th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{})
|
||||||
ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1)
|
ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1)
|
||||||
th.SystemAdminClient.UpdateUser(user)
|
th.SystemAdminClient.UpdateUser(user)
|
||||||
@@ -6538,7 +6538,7 @@ func TestPatchAndUpdateWithProviderAttributes(t *testing.T) {
|
|||||||
samlMock.Mock.On(
|
samlMock.Mock.On(
|
||||||
"CheckProviderAttributes", mock.Anything, mock.Anything, mock.Anything,
|
"CheckProviderAttributes", mock.Anything, mock.Anything, mock.Anything,
|
||||||
).Return("")
|
).Return("")
|
||||||
th.App.Srv().Saml = samlMock
|
th.App.Channels().Saml = samlMock
|
||||||
th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{})
|
th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{})
|
||||||
samlMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1)
|
samlMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1)
|
||||||
th.SystemAdminClient.UpdateUser(user)
|
th.SystemAdminClient.UpdateUser(user)
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func (a *App) SearchEngine() *searchengine.Broker {
|
|||||||
return a.ch.srv.SearchEngine
|
return a.ch.srv.SearchEngine
|
||||||
}
|
}
|
||||||
func (a *App) Ldap() einterfaces.LdapInterface {
|
func (a *App) Ldap() einterfaces.LdapInterface {
|
||||||
return a.ch.srv.Ldap
|
return a.ch.Ldap
|
||||||
}
|
}
|
||||||
func (a *App) MessageExport() einterfaces.MessageExportInterface {
|
func (a *App) MessageExport() einterfaces.MessageExportInterface {
|
||||||
return a.ch.MessageExport
|
return a.ch.MessageExport
|
||||||
@@ -119,10 +119,10 @@ func (a *App) Metrics() einterfaces.MetricsInterface {
|
|||||||
return a.ch.srv.Metrics
|
return a.ch.srv.Metrics
|
||||||
}
|
}
|
||||||
func (a *App) Notification() einterfaces.NotificationInterface {
|
func (a *App) Notification() einterfaces.NotificationInterface {
|
||||||
return a.ch.srv.Notification
|
return a.ch.Notification
|
||||||
}
|
}
|
||||||
func (a *App) Saml() einterfaces.SamlInterface {
|
func (a *App) Saml() einterfaces.SamlInterface {
|
||||||
return a.ch.srv.Saml
|
return a.ch.Saml
|
||||||
}
|
}
|
||||||
func (a *App) Cloud() einterfaces.CloudInterface {
|
func (a *App) Cloud() einterfaces.CloudInterface {
|
||||||
return a.ch.srv.Cloud
|
return a.ch.srv.Cloud
|
||||||
|
|||||||
@@ -527,7 +527,7 @@ type AppIface interface {
|
|||||||
ExportPermissions(w io.Writer) error
|
ExportPermissions(w io.Writer) error
|
||||||
ExtractContentFromFileInfo(fileInfo *model.FileInfo) error
|
ExtractContentFromFileInfo(fileInfo *model.FileInfo) error
|
||||||
FetchSamlMetadataFromIdp(url string) ([]byte, *model.AppError)
|
FetchSamlMetadataFromIdp(url string) ([]byte, *model.AppError)
|
||||||
FileBackend() (filestore.FileBackend, *model.AppError)
|
FileBackend() filestore.FileBackend
|
||||||
FileExists(path string) (bool, *model.AppError)
|
FileExists(path string) (bool, *model.AppError)
|
||||||
FileModTime(path string) (time.Time, *model.AppError)
|
FileModTime(path string) (time.Time, *model.AppError)
|
||||||
FileSize(path string) (int64, *model.AppError)
|
FileSize(path string) (int64, *model.AppError)
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ type Channels struct {
|
|||||||
Compliance einterfaces.ComplianceInterface
|
Compliance einterfaces.ComplianceInterface
|
||||||
DataRetention einterfaces.DataRetentionInterface
|
DataRetention einterfaces.DataRetentionInterface
|
||||||
MessageExport einterfaces.MessageExportInterface
|
MessageExport einterfaces.MessageExportInterface
|
||||||
|
Saml einterfaces.SamlInterface
|
||||||
|
Notification einterfaces.NotificationInterface
|
||||||
|
Ldap einterfaces.LdapInterface
|
||||||
|
|
||||||
// These are used to prevent concurrent upload requests
|
// These are used to prevent concurrent upload requests
|
||||||
// for a given upload session which could cause inconsistencies
|
// for a given upload session which could cause inconsistencies
|
||||||
@@ -145,6 +148,24 @@ func NewChannels(s *Server, services map[ServiceKey]interface{}) (*Channels, err
|
|||||||
if accountMigrationInterface != nil {
|
if accountMigrationInterface != nil {
|
||||||
ch.AccountMigration = accountMigrationInterface(New(ServerConnector(ch)))
|
ch.AccountMigration = accountMigrationInterface(New(ServerConnector(ch)))
|
||||||
}
|
}
|
||||||
|
if ldapInterface != nil {
|
||||||
|
ch.Ldap = ldapInterface(New(ServerConnector(ch)))
|
||||||
|
}
|
||||||
|
if notificationInterface != nil {
|
||||||
|
ch.Notification = notificationInterface(New(ServerConnector(ch)))
|
||||||
|
}
|
||||||
|
if samlInterfaceNew != nil {
|
||||||
|
ch.Saml = samlInterfaceNew(New(ServerConnector(ch)))
|
||||||
|
if err := ch.Saml.ConfigureSP(); err != nil {
|
||||||
|
mlog.Error("An error occurred while configuring SAML Service Provider", mlog.Err(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
ch.AddConfigListener(func(_, _ *model.Config) {
|
||||||
|
if err := ch.Saml.ConfigureSP(); err != nil {
|
||||||
|
mlog.Error("An error occurred while configuring SAML Service Provider", mlog.Err(err))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
var imgErr error
|
var imgErr error
|
||||||
ch.imgDecoder, imgErr = imaging.NewDecoder(imaging.DecoderOptions{
|
ch.imgDecoder, imgErr = imaging.NewDecoder(imaging.DecoderOptions{
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func (s *Server) ConfigStore() *configWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Config() *model.Config {
|
func (a *App) Config() *model.Config {
|
||||||
return a.Srv().Config()
|
return a.ch.cfgSvc.Config()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} {
|
func (s *Server) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} {
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ package app
|
|||||||
import (
|
import (
|
||||||
"github.com/mattermost/mattermost-server/v6/einterfaces"
|
"github.com/mattermost/mattermost-server/v6/einterfaces"
|
||||||
ejobs "github.com/mattermost/mattermost-server/v6/einterfaces/jobs"
|
ejobs "github.com/mattermost/mattermost-server/v6/einterfaces/jobs"
|
||||||
"github.com/mattermost/mattermost-server/v6/model"
|
|
||||||
"github.com/mattermost/mattermost-server/v6/services/searchengine"
|
"github.com/mattermost/mattermost-server/v6/services/searchengine"
|
||||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var accountMigrationInterface func(*App) einterfaces.AccountMigrationInterface
|
var accountMigrationInterface func(*App) einterfaces.AccountMigrationInterface
|
||||||
@@ -65,9 +63,9 @@ func RegisterJobsElasticsearchIndexerInterface(f func(*Server) ejobs.IndexerJobI
|
|||||||
jobsElasticsearchIndexerInterface = f
|
jobsElasticsearchIndexerInterface = f
|
||||||
}
|
}
|
||||||
|
|
||||||
var jobsLdapSyncInterface func(*Server) ejobs.LdapSyncInterface
|
var jobsLdapSyncInterface func(*App) ejobs.LdapSyncInterface
|
||||||
|
|
||||||
func RegisterJobsLdapSyncInterface(f func(*Server) ejobs.LdapSyncInterface) {
|
func RegisterJobsLdapSyncInterface(f func(*App) ejobs.LdapSyncInterface) {
|
||||||
jobsLdapSyncInterface = f
|
jobsLdapSyncInterface = f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,9 +75,9 @@ func RegisterJobsCloudInterface(f func(*Server) ejobs.CloudJobInterface) {
|
|||||||
jobsCloudInterface = f
|
jobsCloudInterface = f
|
||||||
}
|
}
|
||||||
|
|
||||||
var ldapInterface func(*Server) einterfaces.LdapInterface
|
var ldapInterface func(*App) einterfaces.LdapInterface
|
||||||
|
|
||||||
func RegisterLdapInterface(f func(*Server) einterfaces.LdapInterface) {
|
func RegisterLdapInterface(f func(*App) einterfaces.LdapInterface) {
|
||||||
ldapInterface = f
|
ldapInterface = f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,15 +99,15 @@ func RegisterMetricsInterface(f func(*Server) einterfaces.MetricsInterface) {
|
|||||||
metricsInterface = f
|
metricsInterface = f
|
||||||
}
|
}
|
||||||
|
|
||||||
var samlInterfaceNew func(*Server) einterfaces.SamlInterface
|
var samlInterfaceNew func(*App) einterfaces.SamlInterface
|
||||||
|
|
||||||
func RegisterNewSamlInterface(f func(*Server) einterfaces.SamlInterface) {
|
func RegisterNewSamlInterface(f func(*App) einterfaces.SamlInterface) {
|
||||||
samlInterfaceNew = f
|
samlInterfaceNew = f
|
||||||
}
|
}
|
||||||
|
|
||||||
var notificationInterface func(*Server) einterfaces.NotificationInterface
|
var notificationInterface func(*App) einterfaces.NotificationInterface
|
||||||
|
|
||||||
func RegisterNotificationInterface(f func(*Server) einterfaces.NotificationInterface) {
|
func RegisterNotificationInterface(f func(*App) einterfaces.NotificationInterface) {
|
||||||
notificationInterface = f
|
notificationInterface = f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,27 +133,6 @@ func (s *Server) initEnterprise() {
|
|||||||
s.LicenseManager = licenseInterface(s)
|
s.LicenseManager = licenseInterface(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ldapInterface != nil {
|
|
||||||
s.Ldap = ldapInterface(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
if notificationInterface != nil {
|
|
||||||
s.Notification = notificationInterface(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
if samlInterfaceNew != nil {
|
|
||||||
mlog.Debug("Loading SAML2 library")
|
|
||||||
s.Saml = samlInterfaceNew(s)
|
|
||||||
if err := s.Saml.ConfigureSP(); err != nil {
|
|
||||||
mlog.Error("An error occurred while configuring SAML Service Provider", mlog.Err(err))
|
|
||||||
}
|
|
||||||
s.AddConfigListener(func(_, cfg *model.Config) {
|
|
||||||
if err := s.Saml.ConfigureSP(); err != nil {
|
|
||||||
mlog.Error("An error occurred while configuring SAML Service Provider", mlog.Err(err))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if cloudInterface != nil {
|
if cloudInterface != nil {
|
||||||
s.Cloud = cloudInterface(s)
|
s.Cloud = cloudInterface(s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func TestSAMLSettings(t *testing.T) {
|
|||||||
saml2.Mock.On("ConfigureSP").Return(nil)
|
saml2.Mock.On("ConfigureSP").Return(nil)
|
||||||
saml2.Mock.On("GetMetadata").Return("samlTwo", nil)
|
saml2.Mock.On("GetMetadata").Return("samlTwo", nil)
|
||||||
if tc.setNewInterface {
|
if tc.setNewInterface {
|
||||||
RegisterNewSamlInterface(func(_ *Server) einterfaces.SamlInterface {
|
RegisterNewSamlInterface(func(_ *App) einterfaces.SamlInterface {
|
||||||
return saml2
|
return saml2
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -89,10 +89,10 @@ func TestSAMLSettings(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.isNil {
|
if tc.isNil {
|
||||||
assert.Nil(t, th.App.Srv().Saml)
|
assert.Nil(t, th.App.Channels().Saml)
|
||||||
} else {
|
} else {
|
||||||
assert.NotNil(t, th.App.Srv().Saml)
|
assert.NotNil(t, th.App.Channels().Saml)
|
||||||
metadata, err := th.App.Srv().Saml.GetMetadata()
|
metadata, err := th.App.Channels().Saml.GetMetadata()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, tc.metadata, metadata)
|
assert.Equal(t, tc.metadata, metadata)
|
||||||
}
|
}
|
||||||
|
|||||||
70
app/file.go
70
app/file.go
@@ -47,7 +47,7 @@ const (
|
|||||||
maxContentExtractionSize = 1024 * 1024 // 1MB
|
maxContentExtractionSize = 1024 * 1024 // 1MB
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *App) FileBackend() (filestore.FileBackend, *model.AppError) {
|
func (a *App) FileBackend() filestore.FileBackend {
|
||||||
return a.Srv().FileBackend()
|
return a.Srv().FileBackend()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,11 +72,7 @@ func connectionTestErrorToAppError(connTestErr error) *model.AppError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) TestFileStoreConnection() *model.AppError {
|
func (a *App) TestFileStoreConnection() *model.AppError {
|
||||||
backend, err := a.FileBackend()
|
nErr := a.FileBackend().TestConnection()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nErr := backend.TestConnection()
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return connectionTestErrorToAppError(nErr)
|
return connectionTestErrorToAppError(nErr)
|
||||||
}
|
}
|
||||||
@@ -101,11 +97,7 @@ func (a *App) ReadFile(path string) ([]byte, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) fileReader(path string) (filestore.ReadCloseSeeker, *model.AppError) {
|
func (s *Server) fileReader(path string) (filestore.ReadCloseSeeker, *model.AppError) {
|
||||||
backend, err := s.FileBackend()
|
result, nErr := s.FileBackend().Reader(path)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
result, nErr := backend.Reader(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return nil, model.NewAppError("FileReader", "api.file.file_reader.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("FileReader", "api.file.file_reader.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -122,11 +114,7 @@ func (a *App) FileExists(path string) (bool, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) fileExists(path string) (bool, *model.AppError) {
|
func (s *Server) fileExists(path string) (bool, *model.AppError) {
|
||||||
backend, err := s.FileBackend()
|
result, nErr := s.FileBackend().FileExists(path)
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
result, nErr := backend.FileExists(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return false, model.NewAppError("FileExists", "api.file.file_exists.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return false, model.NewAppError("FileExists", "api.file.file_exists.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -134,11 +122,7 @@ func (s *Server) fileExists(path string) (bool, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) FileSize(path string) (int64, *model.AppError) {
|
func (a *App) FileSize(path string) (int64, *model.AppError) {
|
||||||
backend, err := a.FileBackend()
|
size, nErr := a.FileBackend().FileSize(path)
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
size, nErr := backend.FileSize(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return 0, model.NewAppError("FileSize", "api.file.file_size.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return 0, model.NewAppError("FileSize", "api.file.file_size.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -146,11 +130,7 @@ func (a *App) FileSize(path string) (int64, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) FileModTime(path string) (time.Time, *model.AppError) {
|
func (a *App) FileModTime(path string) (time.Time, *model.AppError) {
|
||||||
backend, err := a.FileBackend()
|
modTime, nErr := a.FileBackend().FileModTime(path)
|
||||||
if err != nil {
|
|
||||||
return time.Time{}, err
|
|
||||||
}
|
|
||||||
modTime, nErr := backend.FileModTime(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return time.Time{}, model.NewAppError("FileModTime", "api.file.file_mod_time.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return time.Time{}, model.NewAppError("FileModTime", "api.file.file_mod_time.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -159,11 +139,7 @@ func (a *App) FileModTime(path string) (time.Time, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) MoveFile(oldPath, newPath string) *model.AppError {
|
func (a *App) MoveFile(oldPath, newPath string) *model.AppError {
|
||||||
backend, err := a.FileBackend()
|
nErr := a.FileBackend().MoveFile(oldPath, newPath)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nErr := backend.MoveFile(oldPath, newPath)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return model.NewAppError("MoveFile", "api.file.move_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return model.NewAppError("MoveFile", "api.file.move_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -175,12 +151,7 @@ func (a *App) WriteFile(fr io.Reader, path string) (int64, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) writeFile(fr io.Reader, path string) (int64, *model.AppError) {
|
func (s *Server) writeFile(fr io.Reader, path string) (int64, *model.AppError) {
|
||||||
backend, err := s.FileBackend()
|
result, nErr := s.FileBackend().WriteFile(fr, path)
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result, nErr := backend.WriteFile(fr, path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return result, model.NewAppError("WriteFile", "api.file.write_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return result, model.NewAppError("WriteFile", "api.file.write_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -188,12 +159,7 @@ func (s *Server) writeFile(fr io.Reader, path string) (int64, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) AppendFile(fr io.Reader, path string) (int64, *model.AppError) {
|
func (a *App) AppendFile(fr io.Reader, path string) (int64, *model.AppError) {
|
||||||
backend, err := a.FileBackend()
|
result, nErr := a.FileBackend().AppendFile(fr, path)
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result, nErr := backend.AppendFile(fr, path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return result, model.NewAppError("AppendFile", "api.file.append_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return result, model.NewAppError("AppendFile", "api.file.append_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -205,11 +171,7 @@ func (a *App) RemoveFile(path string) *model.AppError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) removeFile(path string) *model.AppError {
|
func (s *Server) removeFile(path string) *model.AppError {
|
||||||
backend, err := s.FileBackend()
|
nErr := s.FileBackend().RemoveFile(path)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nErr := backend.RemoveFile(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return model.NewAppError("RemoveFile", "api.file.remove_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return model.NewAppError("RemoveFile", "api.file.remove_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -221,11 +183,7 @@ func (a *App) ListDirectory(path string) ([]string, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) listDirectory(path string) ([]string, *model.AppError) {
|
func (s *Server) listDirectory(path string) ([]string, *model.AppError) {
|
||||||
backend, err := s.FileBackend()
|
paths, nErr := s.FileBackend().ListDirectory(path)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
paths, nErr := backend.ListDirectory(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return nil, model.NewAppError("ListDirectory", "api.file.list_directory.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("ListDirectory", "api.file.list_directory.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -234,11 +192,7 @@ func (s *Server) listDirectory(path string) ([]string, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) RemoveDirectory(path string) *model.AppError {
|
func (a *App) RemoveDirectory(path string) *model.AppError {
|
||||||
backend, err := a.FileBackend()
|
nErr := a.FileBackend().RemoveDirectory(path)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nErr := backend.RemoveDirectory(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return model.NewAppError("RemoveDirectory", "api.file.remove_directory.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return model.NewAppError("RemoveDirectory", "api.file.remove_directory.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ func (a *App) BuildPushNotificationMessage(contentsConfig string, post *model.Po
|
|||||||
|
|
||||||
var msg *model.PushNotification
|
var msg *model.PushNotification
|
||||||
|
|
||||||
notificationInterface := a.Srv().Notification
|
notificationInterface := a.ch.Notification
|
||||||
if (notificationInterface == nil || notificationInterface.CheckLicense() != nil) && contentsConfig == model.IdLoadedNotification {
|
if (notificationInterface == nil || notificationInterface.CheckLicense() != nil) && contentsConfig == model.IdLoadedNotification {
|
||||||
contentsConfig = model.GenericNotification
|
contentsConfig = model.GenericNotification
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4013,7 +4013,7 @@ func (a *OpenTracingAppLayer) FetchSamlMetadataFromIdp(url string) ([]byte, *mod
|
|||||||
return resultVar0, resultVar1
|
return resultVar0, resultVar1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) FileBackend() (filestore.FileBackend, *model.AppError) {
|
func (a *OpenTracingAppLayer) FileBackend() filestore.FileBackend {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.FileBackend")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.FileBackend")
|
||||||
|
|
||||||
@@ -4025,14 +4025,9 @@ func (a *OpenTracingAppLayer) FileBackend() (filestore.FileBackend, *model.AppEr
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
resultVar0, resultVar1 := a.app.FileBackend()
|
resultVar0 := a.app.FileBackend()
|
||||||
|
|
||||||
if resultVar1 != nil {
|
return resultVar0
|
||||||
span.LogFields(spanlog.Error(resultVar1))
|
|
||||||
ext.Error.Set(span, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultVar0, resultVar1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) FileExists(path string) (bool, *model.AppError) {
|
func (a *OpenTracingAppLayer) FileExists(path string) (bool, *model.AppError) {
|
||||||
|
|||||||
123
app/server.go
123
app/server.go
@@ -159,6 +159,7 @@ type Server struct {
|
|||||||
searchLicenseListenerId string
|
searchLicenseListenerId string
|
||||||
loggerLicenseListenerId string
|
loggerLicenseListenerId string
|
||||||
configStore *configWrapper
|
configStore *configWrapper
|
||||||
|
filestore filestore.FileBackend
|
||||||
|
|
||||||
telemetryService *telemetry.TelemetryService
|
telemetryService *telemetry.TelemetryService
|
||||||
userService *users.UserService
|
userService *users.UserService
|
||||||
@@ -184,10 +185,7 @@ type Server struct {
|
|||||||
Cluster einterfaces.ClusterInterface
|
Cluster einterfaces.ClusterInterface
|
||||||
Cloud einterfaces.CloudInterface
|
Cloud einterfaces.CloudInterface
|
||||||
Metrics einterfaces.MetricsInterface
|
Metrics einterfaces.MetricsInterface
|
||||||
Notification einterfaces.NotificationInterface
|
|
||||||
LicenseManager einterfaces.LicenseInterface
|
LicenseManager einterfaces.LicenseInterface
|
||||||
Saml einterfaces.SamlInterface
|
|
||||||
Ldap einterfaces.LdapInterface
|
|
||||||
|
|
||||||
CacheProvider cache.Provider
|
CacheProvider cache.Provider
|
||||||
|
|
||||||
@@ -257,27 +255,8 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
mlog.Info("Server is initializing...", mlog.String("go_version", runtime.Version()))
|
mlog.Info("Server is initializing...", mlog.String("go_version", runtime.Version()))
|
||||||
|
|
||||||
s.httpService = httpservice.MakeHTTPService(s)
|
s.httpService = httpservice.MakeHTTPService(s)
|
||||||
s.licenseWrapper = &licenseWrapper{
|
|
||||||
srv: s,
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceMap := map[ServiceKey]interface{}{
|
// Step 3: Search Engine
|
||||||
ConfigKey: s.configStore,
|
|
||||||
LicenseKey: s.licenseWrapper,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: Initialize products.
|
|
||||||
// Depends on s.httpService.
|
|
||||||
for name, initializer := range products {
|
|
||||||
prod, err2 := initializer(s, serviceMap)
|
|
||||||
if err2 != nil {
|
|
||||||
return nil, errors.Wrapf(err2, "error initializing product: %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.products[name] = prod
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4: Search Engine
|
|
||||||
// Depends on Step 1 (config).
|
// Depends on Step 1 (config).
|
||||||
searchEngine := searchengine.NewBroker(s.Config())
|
searchEngine := searchengine.NewBroker(s.Config())
|
||||||
bleveEngine := bleveengine.NewBleveEngine(s.Config())
|
bleveEngine := bleveengine.NewBleveEngine(s.Config())
|
||||||
@@ -287,12 +266,11 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
searchEngine.RegisterBleveEngine(bleveEngine)
|
searchEngine.RegisterBleveEngine(bleveEngine)
|
||||||
s.SearchEngine = searchEngine
|
s.SearchEngine = searchEngine
|
||||||
|
|
||||||
// Step 5: Init Enterprise
|
// Step 4: Init Enterprise
|
||||||
// Depends on step 3 (s.Channels() must be non-nil)
|
// Depends on step 3 (s.SearchEngine must be non-nil)
|
||||||
// and step 4 (s.SearchEngine must be non-nil)
|
|
||||||
s.initEnterprise()
|
s.initEnterprise()
|
||||||
|
|
||||||
// Step 6: Cache provider.
|
// Step 5: Cache provider.
|
||||||
// At the moment we only have this implementation
|
// At the moment we only have this implementation
|
||||||
// in the future the cache provider will be built based on the loaded config
|
// in the future the cache provider will be built based on the loaded config
|
||||||
s.CacheProvider = cache.NewProvider()
|
s.CacheProvider = cache.NewProvider()
|
||||||
@@ -300,12 +278,8 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
return nil, errors.Wrapf(err2, "Unable to connect to cache provider")
|
return nil, errors.Wrapf(err2, "Unable to connect to cache provider")
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is important to initialize the hub only after the global logger is set
|
// Step 6: Store.
|
||||||
// to avoid race conditions while logging from inside the hub.
|
// Depends on Step 1 (config), 4 (metrics, cluster) and 5 (cacheProvider).
|
||||||
s.HubStart()
|
|
||||||
|
|
||||||
// Step 7: Store.
|
|
||||||
// Depends on Step 1 (config), 5 (metrics, cluster) and 6 (cacheProvider).
|
|
||||||
if s.newStore == nil {
|
if s.newStore == nil {
|
||||||
s.newStore = func() (store.Store, error) {
|
s.newStore = func() (store.Store, error) {
|
||||||
s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.Metrics)
|
s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.Metrics)
|
||||||
@@ -347,6 +321,42 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
return nil, errors.Wrap(err, "cannot create store")
|
return nil, errors.Wrap(err, "cannot create store")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if model.BuildEnterpriseReady == "true" {
|
||||||
|
s.LoadLicense()
|
||||||
|
}
|
||||||
|
|
||||||
|
license := s.License()
|
||||||
|
// Step 7: Initialize filestore
|
||||||
|
backend, err := filestore.NewFileBackend(s.Config().FileSettings.ToFileBackendSettings(license != nil && *license.Features.Compliance))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to initialize filebackend")
|
||||||
|
}
|
||||||
|
s.filestore = backend
|
||||||
|
|
||||||
|
s.licenseWrapper = &licenseWrapper{
|
||||||
|
srv: s,
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceMap := map[ServiceKey]interface{}{
|
||||||
|
ConfigKey: s.configStore,
|
||||||
|
LicenseKey: s.licenseWrapper,
|
||||||
|
}
|
||||||
|
// Step 8: Initialize products.
|
||||||
|
// Depends on s.httpService.
|
||||||
|
for name, initializer := range products {
|
||||||
|
prod, err2 := initializer(s, serviceMap)
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, errors.Wrapf(err2, "error initializing product: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.products[name] = prod
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is important to initialize the hub only after the global logger is set
|
||||||
|
// to avoid race conditions while logging from inside the hub.
|
||||||
|
// Step 9: Hub depends on s.Channels() (step 8)
|
||||||
|
s.HubStart()
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Everything below this is not order sensitive and safe to be moved around.
|
// Everything below this is not order sensitive and safe to be moved around.
|
||||||
// If you are adding a new field that is non-channels specific, please add
|
// If you are adding a new field that is non-channels specific, please add
|
||||||
@@ -503,10 +513,6 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
}
|
}
|
||||||
s.EmailService = emailService
|
s.EmailService = emailService
|
||||||
|
|
||||||
if model.BuildEnterpriseReady == "true" {
|
|
||||||
s.LoadLicense()
|
|
||||||
}
|
|
||||||
|
|
||||||
s.setupFeatureFlags()
|
s.setupFeatureFlags()
|
||||||
|
|
||||||
s.initJobs()
|
s.initJobs()
|
||||||
@@ -560,7 +566,6 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
mlog.Info("Printing current working", mlog.String("directory", pwd))
|
mlog.Info("Printing current working", mlog.String("directory", pwd))
|
||||||
mlog.Info("Loaded config", mlog.String("source", s.configStore.String()))
|
mlog.Info("Loaded config", mlog.String("source", s.configStore.String()))
|
||||||
|
|
||||||
license := s.License()
|
|
||||||
allowAdvancedLogging := license != nil && *license.Features.AdvancedLogging
|
allowAdvancedLogging := license != nil && *license.Features.AdvancedLogging
|
||||||
|
|
||||||
if s.Audit == nil {
|
if s.Audit == nil {
|
||||||
@@ -1172,18 +1177,13 @@ func (s *Server) Start() error {
|
|||||||
mlog.Error("Mail server connection test is failed", mlog.Err(err))
|
mlog.Error("Mail server connection test is failed", mlog.Err(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
backend, appErr := s.FileBackend()
|
err := s.FileBackend().TestConnection()
|
||||||
if appErr != nil {
|
if err != nil {
|
||||||
mlog.Error("Problem with file storage settings", mlog.Err(appErr))
|
if _, ok := err.(*filestore.S3FileBackendNoBucketError); ok {
|
||||||
} else {
|
err = s.FileBackend().(*filestore.S3FileBackend).MakeBucket()
|
||||||
err := backend.TestConnection()
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(*filestore.S3FileBackendNoBucketError); ok {
|
mlog.Error("Problem with file storage settings", mlog.Err(err))
|
||||||
err = backend.(*filestore.S3FileBackend).MakeBucket()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
mlog.Error("Problem with file storage settings", mlog.Err(err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1227,9 +1227,9 @@ func (s *Server) Start() error {
|
|||||||
if *s.Config().RateLimitSettings.Enable {
|
if *s.Config().RateLimitSettings.Enable {
|
||||||
mlog.Info("RateLimiter is enabled")
|
mlog.Info("RateLimiter is enabled")
|
||||||
|
|
||||||
rateLimiter, err := NewRateLimiter(&s.Config().RateLimitSettings, s.Config().ServiceSettings.TrustedProxyIPHeader)
|
rateLimiter, err2 := NewRateLimiter(&s.Config().RateLimitSettings, s.Config().ServiceSettings.TrustedProxyIPHeader)
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
return err
|
return err2
|
||||||
}
|
}
|
||||||
|
|
||||||
s.RateLimiter = rateLimiter
|
s.RateLimiter = rateLimiter
|
||||||
@@ -1850,13 +1850,8 @@ func (s *Server) stopSearchEngine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) FileBackend() (filestore.FileBackend, *model.AppError) {
|
func (s *Server) FileBackend() filestore.FileBackend {
|
||||||
license := s.License()
|
return s.filestore
|
||||||
backend, err := filestore.NewFileBackend(s.Config().FileSettings.ToFileBackendSettings(license != nil && *license.Features.Compliance))
|
|
||||||
if err != nil {
|
|
||||||
return nil, model.NewAppError("FileBackend", "api.file.no_driver.app_error", nil, err.Error(), http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return backend, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) TotalWebsocketConnections() int {
|
func (s *Server) TotalWebsocketConnections() int {
|
||||||
@@ -1904,7 +1899,7 @@ func (s *Server) initJobs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if jobsLdapSyncInterface != nil {
|
if jobsLdapSyncInterface != nil {
|
||||||
builder := jobsLdapSyncInterface(s)
|
builder := jobsLdapSyncInterface(New(ServerConnector(s.Channels())))
|
||||||
s.Jobs.RegisterJobType(model.JobTypeLdapSync, builder.MakeWorker(), builder.MakeScheduler())
|
s.Jobs.RegisterJobType(model.JobTypeLdapSync, builder.MakeWorker(), builder.MakeScheduler())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2189,7 +2184,7 @@ func (a *App) generateSupportPacketYaml() (*model.FileData, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Here we are getting information regarding LDAP
|
// Here we are getting information regarding LDAP
|
||||||
ldapInterface := a.ch.srv.Ldap
|
ldapInterface := a.ch.Ldap
|
||||||
var vendorName, vendorVersion string
|
var vendorName, vendorVersion string
|
||||||
if ldapInterface != nil {
|
if ldapInterface != nil {
|
||||||
vendorName, vendorVersion = ldapInterface.GetVendorNameAndVendorVersion()
|
vendorName, vendorVersion = ldapInterface.GetVendorNameAndVendorVersion()
|
||||||
@@ -2270,11 +2265,7 @@ func (s *Server) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppErr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ReadFile(path string) ([]byte, *model.AppError) {
|
func (s *Server) ReadFile(path string) ([]byte, *model.AppError) {
|
||||||
backend, err := s.FileBackend()
|
result, nErr := s.FileBackend().ReadFile(path)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
result, nErr := backend.ReadFile(path)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return nil, model.NewAppError("ReadFile", "api.file.read_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("ReadFile", "api.file.read_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,9 +191,7 @@ func TestStartServerNoS3Bucket(t *testing.T) {
|
|||||||
defer s.Shutdown()
|
defer s.Shutdown()
|
||||||
|
|
||||||
// ensure that a new bucket was created
|
// ensure that a new bucket was created
|
||||||
backend, appErr := s.FileBackend()
|
err = s.FileBackend().(*filestore.S3FileBackend).TestConnection()
|
||||||
require.Nil(t, appErr)
|
|
||||||
err = backend.(*filestore.S3FileBackend).TestConnection()
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ func TestHubConnIndexInactive(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReliableWebSocketSend(t *testing.T) {
|
func TestReliableWebSocketSend(t *testing.T) {
|
||||||
|
t.Skip("MM-42033")
|
||||||
testCluster := &testlib.FakeClusterInterface{}
|
testCluster := &testlib.FakeClusterInterface{}
|
||||||
|
|
||||||
th := SetupWithClusterMock(t, testCluster)
|
th := SetupWithClusterMock(t, testCluster)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user