diff options
author | Corey Hulen <corey@hulen.com> | 2016-05-24 14:31:30 -0700 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2016-05-24 14:31:30 -0700 |
commit | 09863c0b80610f2f3a35cf3caa7c5b66a0c3878e (patch) | |
tree | dcce1b5c0fa62a9da2b25a99862af5ba30306901 /api | |
parent | 4ae7128ecb66cdddeb9d40a24970c6552814c18b (diff) | |
download | chat-09863c0b80610f2f3a35cf3caa7c5b66a0c3878e.tar.gz chat-09863c0b80610f2f3a35cf3caa7c5b66a0c3878e.tar.bz2 chat-09863c0b80610f2f3a35cf3caa7c5b66a0c3878e.zip |
Adding APIs to reload config, recycle db connections and ping server (#3096)
* Adding APIs to reload config, recycle db connections and ping server
* Fixing unit test
* Adding unit tests
Diffstat (limited to 'api')
-rw-r--r-- | api/admin.go | 61 | ||||
-rw-r--r-- | api/admin_test.go | 41 | ||||
-rw-r--r-- | api/api.go | 10 | ||||
-rw-r--r-- | api/general.go | 56 | ||||
-rw-r--r-- | api/general_test.go | 40 |
5 files changed, 166 insertions, 42 deletions
diff --git a/api/admin.go b/api/admin.go index c2dfa37d0..52e412976 100644 --- a/api/admin.go +++ b/api/admin.go @@ -10,11 +10,13 @@ import ( "os" "strconv" "strings" + "time" l4g "github.com/alecthomas/log4go" "github.com/gorilla/mux" "github.com/mattermost/platform/einterfaces" "github.com/mattermost/platform/model" + "github.com/mattermost/platform/store" "github.com/mattermost/platform/utils" "github.com/mssola/user_agent" ) @@ -26,9 +28,9 @@ func InitAdmin() { BaseRoutes.Admin.Handle("/audits", ApiUserRequired(getAllAudits)).Methods("GET") BaseRoutes.Admin.Handle("/config", ApiUserRequired(getConfig)).Methods("GET") BaseRoutes.Admin.Handle("/save_config", ApiUserRequired(saveConfig)).Methods("POST") + BaseRoutes.Admin.Handle("/reload_config", ApiUserRequired(reloadConfig)).Methods("GET") BaseRoutes.Admin.Handle("/test_email", ApiUserRequired(testEmail)).Methods("POST") - BaseRoutes.Admin.Handle("/client_props", ApiAppHandler(getClientConfig)).Methods("GET") - BaseRoutes.Admin.Handle("/log_client", ApiAppHandler(logClient)).Methods("POST") + BaseRoutes.Admin.Handle("/recycle_db_conn", ApiUserRequired(recycleDatabaseConnection)).Methods("GET") BaseRoutes.Admin.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET") BaseRoutes.Admin.Handle("/analytics/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET") BaseRoutes.Admin.Handle("/save_compliance_report", ApiUserRequired(saveComplianceReport)).Methods("POST") @@ -94,32 +96,6 @@ func getAllAudits(c *Context, w http.ResponseWriter, r *http.Request) { } } -func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) { - w.Write([]byte(model.MapToJson(utils.ClientCfg))) -} - -func logClient(c *Context, w http.ResponseWriter, r *http.Request) { - m := model.MapFromJson(r.Body) - - lvl := m["level"] - msg := m["message"] - - if len(msg) > 400 { - msg = msg[0:399] - } - - if lvl == "ERROR" { - err := &model.AppError{} - err.Message = msg - err.Where = "client" - c.LogError(err) - } - - rm := make(map[string]string) - rm["SUCCESS"] = "true" - w.Write([]byte(model.MapToJson(rm))) -} - func getConfig(c *Context, w http.ResponseWriter, r *http.Request) { if !c.HasSystemAdminPermissions("getConfig") { return @@ -134,6 +110,16 @@ func getConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(cfg.ToJson())) } +func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) { + if !c.HasSystemAdminPermissions("reloadConfig") { + return + } + + utils.LoadConfig(utils.CfgFileName) + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + ReturnStatusOK(w) +} + func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) { if !c.HasSystemAdminPermissions("getConfig") { return @@ -168,6 +154,25 @@ func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(model.MapToJson(rdata))) } +func recycleDatabaseConnection(c *Context, w http.ResponseWriter, r *http.Request) { + if !c.HasSystemAdminPermissions("recycleDatabaseConnection") { + return + } + + oldStore := Srv.Store + + l4g.Warn(utils.T("api.admin.recycle_db_start.warn")) + Srv.Store = store.NewSqlStore() + + time.Sleep(20 * time.Second) + oldStore.Close() + + l4g.Warn(utils.T("api.admin.recycle_db_end.warn")) + + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + ReturnStatusOK(w) +} + func testEmail(c *Context, w http.ResponseWriter, r *http.Request) { if !c.HasSystemAdminPermissions("testEmail") { return diff --git a/api/admin_test.go b/api/admin_test.go index f3d3ec4ed..16ae62f7a 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -39,20 +39,6 @@ func TestGetAllAudits(t *testing.T) { } } -func TestGetClientProperties(t *testing.T) { - th := Setup().InitBasic() - - if result, err := th.BasicClient.GetClientProperties(); err != nil { - t.Fatal(err) - } else { - props := result.Data.(map[string]string) - - if len(props["Version"]) == 0 { - t.Fatal() - } - } -} - func TestGetConfig(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() @@ -102,6 +88,21 @@ func TestGetConfig(t *testing.T) { } } +func TestReloadConfig(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + + if _, err := th.BasicClient.ReloadConfig(); err == nil { + t.Fatal("Shouldn't have permissions") + } + + if _, err := th.SystemAdminClient.ReloadConfig(); err != nil { + t.Fatal(err) + } + + utils.Cfg.TeamSettings.MaxUsersPerTeam = 50 + *utils.Cfg.TeamSettings.EnableOpenServer = true +} + func TestSaveConfig(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() @@ -118,6 +119,18 @@ func TestSaveConfig(t *testing.T) { *utils.Cfg.TeamSettings.EnableOpenServer = true } +func TestRecycleDatabaseConnection(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + + if _, err := th.BasicClient.RecycleDatabaseConnection(); err == nil { + t.Fatal("Shouldn't have permissions") + } + + if _, err := th.SystemAdminClient.RecycleDatabaseConnection(); err != nil { + t.Fatal(err) + } +} + func TestEmailTest(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() diff --git a/api/api.go b/api/api.go index 6626ef326..e62d34dcc 100644 --- a/api/api.go +++ b/api/api.go @@ -40,6 +40,8 @@ type Routes struct { Admin *mux.Router // 'api/v3/admin' + General *mux.Router // 'api/v3/general' + Preferences *mux.Router // 'api/v3/preferences' License *mux.Router // 'api/v3/license' @@ -67,6 +69,7 @@ func InitApi() { BaseRoutes.Hooks = BaseRoutes.NeedTeam.PathPrefix("/hooks").Subrouter() BaseRoutes.OAuth = BaseRoutes.ApiRoot.PathPrefix("/oauth").Subrouter() BaseRoutes.Admin = BaseRoutes.ApiRoot.PathPrefix("/admin").Subrouter() + BaseRoutes.General = BaseRoutes.ApiRoot.PathPrefix("/general").Subrouter() BaseRoutes.Preferences = BaseRoutes.ApiRoot.PathPrefix("/preferences").Subrouter() BaseRoutes.License = BaseRoutes.ApiRoot.PathPrefix("/license").Subrouter() BaseRoutes.Public = BaseRoutes.ApiRoot.PathPrefix("/public").Subrouter() @@ -79,6 +82,7 @@ func InitApi() { InitFile() InitCommand() InitAdmin() + InitGeneral() InitOAuth() InitWebhook() InitPreference() @@ -100,3 +104,9 @@ func HandleEtag(etag string, w http.ResponseWriter, r *http.Request) bool { return false } + +func ReturnStatusOK(w http.ResponseWriter) { + m := make(map[string]string) + m[model.STATUS] = model.STATUS_OK + w.Write([]byte(model.MapToJson(m))) +} diff --git a/api/general.go b/api/general.go new file mode 100644 index 000000000..0adc36d9f --- /dev/null +++ b/api/general.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package api + +import ( + "fmt" + "net/http" + + l4g "github.com/alecthomas/log4go" + + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +func InitGeneral() { + l4g.Debug(utils.T("api.general.init.debug")) + + BaseRoutes.General.Handle("/client_props", ApiAppHandler(getClientConfig)).Methods("GET") + BaseRoutes.General.Handle("/log_client", ApiAppHandler(logClient)).Methods("POST") + BaseRoutes.General.Handle("/ping", ApiAppHandler(ping)).Methods("GET") + +} + +func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) { + w.Write([]byte(model.MapToJson(utils.ClientCfg))) +} + +func logClient(c *Context, w http.ResponseWriter, r *http.Request) { + m := model.MapFromJson(r.Body) + + lvl := m["level"] + msg := m["message"] + + if len(msg) > 400 { + msg = msg[0:399] + } + + if lvl == "ERROR" { + err := &model.AppError{} + err.Message = msg + err.Id = msg + err.Where = "client" + c.LogError(err) + } + + ReturnStatusOK(w) +} + +func ping(c *Context, w http.ResponseWriter, r *http.Request) { + m := make(map[string]string) + m["version"] = model.CurrentVersion + m["server_time"] = fmt.Sprintf("%v", model.GetMillis()) + m["node_id"] = "" + w.Write([]byte(model.MapToJson(m))) +} diff --git a/api/general_test.go b/api/general_test.go new file mode 100644 index 000000000..0cc0f120f --- /dev/null +++ b/api/general_test.go @@ -0,0 +1,40 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package api + +import ( + "testing" +) + +func TestGetClientProperties(t *testing.T) { + th := Setup().InitBasic() + + if props, err := th.BasicClient.GetClientProperties(); err != nil { + t.Fatal(err) + } else { + if len(props["Version"]) == 0 { + t.Fatal() + } + } +} + +func TestLogClient(t *testing.T) { + th := Setup().InitBasic() + + if ret, _ := th.BasicClient.LogClient("this is a test"); !ret { + t.Fatal("failed to log") + } +} + +func TestGetPing(t *testing.T) { + th := Setup().InitBasic() + + if m, err := th.BasicClient.GetPing(); err != nil { + t.Fatal(err) + } else { + if len(m["version"]) == 0 { + t.Fatal() + } + } +} |