From 9bc09fcbb70c85f4aa771b4cb174286e15ab4be0 Mon Sep 17 00:00:00 2001 From: libotony Date: Wed, 11 Sep 2024 16:34:08 +0800 Subject: [PATCH] leverage api uitls in admin server (#839) --- api/admin.go | 46 +++++++++++++---------------------------- api/admin_server.go | 5 +++-- api/admin_test.go | 11 ++++------ cmd/thor/flags.go | 2 +- cmd/thor/main.go | 8 ++++---- cmd/thor/utils.go | 50 --------------------------------------------- 6 files changed, 26 insertions(+), 96 deletions(-) diff --git a/api/admin.go b/api/admin.go index 50542ee8f..afd299cfa 100644 --- a/api/admin.go +++ b/api/admin.go @@ -6,10 +6,11 @@ package api import ( - "encoding/json" "log/slog" "net/http" + "github.com/pkg/errors" + "github.com/vechain/thor/v2/api/utils" "github.com/vechain/thor/v2/log" ) @@ -21,35 +22,20 @@ type logLevelResponse struct { CurrentLevel string `json:"currentLevel"` } -type errorResponse struct { - ErrorMessage string `json:"errorMessage"` -} - -func writeError(w http.ResponseWriter, errCode int, errMsg string) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(errCode) - json.NewEncoder(w).Encode(errorResponse{ - ErrorMessage: errMsg, - }) -} - -func getLogLevelHandler(logLevel *slog.LevelVar) http.HandlerFunc { - return func(w http.ResponseWriter, _ *http.Request) { - response := logLevelResponse{ +func getLogLevelHandler(logLevel *slog.LevelVar) utils.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) error { + return utils.WriteJSON(w, logLevelResponse{ CurrentLevel: logLevel.Level().String(), - } - if err := json.NewEncoder(w).Encode(response); err != nil { - writeError(w, http.StatusInternalServerError, "Failed to encode response") - } + }) } } -func postLogLevelHandler(logLevel *slog.LevelVar) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { +func postLogLevelHandler(logLevel *slog.LevelVar) utils.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) error { var req logLevelRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - writeError(w, http.StatusBadRequest, "Invalid request body") - return + + if err := utils.ParseJSON(r.Body, &req); err != nil { + return utils.BadRequest(errors.WithMessage(err, "Invalid request body")) } switch req.Level { @@ -66,15 +52,11 @@ func postLogLevelHandler(logLevel *slog.LevelVar) http.HandlerFunc { case "crit": logLevel.Set(log.LevelCrit) default: - writeError(w, http.StatusBadRequest, "Invalid verbosity level") - return + return utils.BadRequest(errors.New("Invalid verbosity level")) } - w.Header().Set("Content-Type", "application/json") - response := logLevelResponse{ + return utils.WriteJSON(w, logLevelResponse{ CurrentLevel: logLevel.Level().String(), - } - w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(response) + }) } } diff --git a/api/admin_server.go b/api/admin_server.go index 1984f9c3f..26054e908 100644 --- a/api/admin_server.go +++ b/api/admin_server.go @@ -14,6 +14,7 @@ import ( "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/pkg/errors" + "github.com/vechain/thor/v2/api/utils" "github.com/vechain/thor/v2/co" ) @@ -23,12 +24,12 @@ func HTTPHandler(logLevel *slog.LevelVar) http.Handler { sub.Path("/loglevel"). Methods(http.MethodGet). Name("get-log-level"). - HandlerFunc(getLogLevelHandler(logLevel)) + HandlerFunc(utils.WrapHandlerFunc(getLogLevelHandler(logLevel))) sub.Path("/loglevel"). Methods(http.MethodPost). Name("post-log-level"). - HandlerFunc(postLogLevelHandler(logLevel)) + HandlerFunc(utils.WrapHandlerFunc(postLogLevelHandler(logLevel))) return handlers.CompressHandler(router) } diff --git a/api/admin_test.go b/api/admin_test.go index c30e2ae32..be2847cbf 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -11,7 +11,10 @@ import ( "log/slog" "net/http" "net/http/httptest" + "strings" "testing" + + "github.com/stretchr/testify/assert" ) type TestCase struct { @@ -89,13 +92,7 @@ func TestLogLevelHandler(t *testing.T) { t.Errorf("handler returned unexpected log level: got %v want %v", response.CurrentLevel, tt.expectedLevel) } } else { - var response errorResponse - if err := json.NewDecoder(rr.Body).Decode(&response); err != nil { - t.Fatalf("could not decode response: %v", err) - } - if response.ErrorMessage != tt.expectedErrorMsg { - t.Errorf("handler returned unexpected error message: got %v want %v", response.ErrorMessage, tt.expectedErrorMsg) - } + assert.Equal(t, tt.expectedErrorMsg, strings.Trim(rr.Body.String(), "\n")) } }) } diff --git a/cmd/thor/flags.go b/cmd/thor/flags.go index 0a512319f..4b18f22ad 100644 --- a/cmd/thor/flags.go +++ b/cmd/thor/flags.go @@ -153,7 +153,7 @@ var ( enableAdminFlag = cli.BoolFlag{ Name: "enable-admin", - Usage: "enables admin service", + Usage: "enables admin server", } adminAddrFlag = cli.StringFlag{ Name: "admin-addr", diff --git a/cmd/thor/main.go b/cmd/thor/main.go index e1ead8caf..4b934bc13 100644 --- a/cmd/thor/main.go +++ b/cmd/thor/main.go @@ -204,8 +204,6 @@ func defaultAction(ctx *cli.Context) error { } defer func() { log.Info("closing main database..."); mainDB.Close() }() - skipLogs := ctx.Bool(skipLogsFlag.Name) - logDB, err := openLogDB(instanceDir) if err != nil { return err @@ -224,6 +222,7 @@ func defaultAction(ctx *cli.Context) error { printStartupMessage1(gene, repo, master, instanceDir, forkConfig) + skipLogs := ctx.Bool(skipLogsFlag.Name) if !skipLogs { if err := syncLogDB(exitSignal, repo, logDB, ctx.Bool(verifyLogsFlag.Name)); err != nil { return err @@ -377,8 +376,9 @@ func soloAction(ctx *cli.Context) error { return err } - skipLogs := ctx.Bool(skipLogsFlag.Name) + printStartupMessage1(gene, repo, nil, instanceDir, forkConfig) + skipLogs := ctx.Bool(skipLogsFlag.Name) if !skipLogs { if err := syncLogDB(exitSignal, repo, logDB, ctx.Bool(verifyLogsFlag.Name)); err != nil { return err @@ -435,7 +435,7 @@ func soloAction(ctx *cli.Context) error { return errors.New("block-interval cannot be zero") } - printSoloStartupMessage(gene, repo, instanceDir, apiURL, forkConfig, metricsURL, adminURL) + printStartupMessage2(gene, apiURL, "", metricsURL, adminURL) optimizer := optimizer.New(mainDB, repo, !ctx.Bool(disablePrunerFlag.Name)) defer func() { log.Info("stopping optimizer..."); optimizer.Stop() }() diff --git a/cmd/thor/utils.go b/cmd/thor/utils.go index d755cf732..5c6799354 100644 --- a/cmd/thor/utils.go +++ b/cmd/thor/utils.go @@ -664,56 +664,6 @@ func printStartupMessage2( ) } -func printSoloStartupMessage( - gene *genesis.Genesis, - repo *chain.Repository, - dataDir string, - apiURL string, - forkConfig thor.ForkConfig, - metricsURL string, - adminURL string, -) { - bestBlock := repo.BestBlockSummary() - - info := fmt.Sprintf(`Starting %v - Network [ %v %v ] - Best block [ %v #%v @%v ] - Forks [ %v ] - Data dir [ %v ] - API portal [ %v ] - Metrics [ %v ] - Admin [ %v ] -`, - common.MakeName("Thor solo", fullVersion()), - gene.ID(), gene.Name(), - bestBlock.Header.ID(), bestBlock.Header.Number(), time.Unix(int64(bestBlock.Header.Timestamp()), 0), - forkConfig, - dataDir, - apiURL, - func() string { - if metricsURL == "" { - return "Disabled" - } - return metricsURL - }(), - func() string { - if adminURL == "" { - return "Disabled" - } - return adminURL - }(), - ) - - if gene.ID() == devNetGenesisID { - info += `┌──────────────────┬───────────────────────────────────────────────────────────────────────────────┐ -│ Mnemonic Words │ denial kitchen pet squirrel other broom bar gas better priority spoil cross │ -└──────────────────┴───────────────────────────────────────────────────────────────────────────────┘ -` - } - - fmt.Print(info) -} - func openMemMainDB() *muxdb.MuxDB { return muxdb.NewMem() }