| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package main |
| |
| import ( |
| "flag" |
| "fmt" |
| "os" |
| "os/signal" |
| "strings" |
| "syscall" |
| |
| "github.com/apache/shardingsphere-on-cloud/pitr/agent/internal/handler" |
| "github.com/apache/shardingsphere-on-cloud/pitr/agent/internal/handler/middleware" |
| "github.com/apache/shardingsphere-on-cloud/pitr/agent/internal/pkg" |
| "github.com/apache/shardingsphere-on-cloud/pitr/agent/pkg/logging" |
| "github.com/apache/shardingsphere-on-cloud/pitr/agent/pkg/responder" |
| |
| "github.com/gofiber/fiber/v2" |
| "github.com/joho/godotenv" |
| "go.uber.org/zap/zapcore" |
| ) |
| |
| const ( |
| debugLogLevel = "debug" |
| ) |
| |
| var ( |
| app *fiber.App |
| log logging.ILog |
| ) |
| |
| var ( |
| logLevel string |
| port string |
| pgData string |
| tlsCrt string |
| tlsKey string |
| envSourceFile string |
| ) |
| |
| func init() { |
| // 参数通过 flag 输入 |
| flag.StringVar(&logLevel, "log-level", "info", "optional:log level,option values:info or debug") |
| flag.StringVar(&port, "port", "443", "HTTP service port") |
| |
| flag.StringVar(&tlsCrt, "tls-crt", "", "Require:TLS certificate file path") |
| flag.StringVar(&tlsKey, "tls-key", "", "Require:TLS key file path") |
| |
| flag.StringVar(&pgData, "pgdata", "", "Optional:Get the value from cli flags or env") |
| |
| flag.StringVar(&envSourceFile, "env-source-file", "", "Optional:env source file path") |
| } |
| |
| func main() { |
| flag.Parse() |
| |
| if envSourceFile != "" { |
| err := godotenv.Load(envSourceFile) |
| if err != nil { |
| panic(fmt.Errorf("load env source file error: %s", err)) |
| } |
| } |
| |
| shell := os.Getenv("SHELL") |
| if shell == "" { |
| panic(fmt.Errorf("shell does not exist")) |
| } |
| |
| if pgData == "" { |
| pgData = os.Getenv("PGDATA") |
| if pgData == "" { |
| panic(fmt.Errorf("PGDATA: no database directory specified and environment variable PGDATA unset")) |
| } |
| } |
| |
| if _, err := os.Stat(pgData); os.IsNotExist(err) { |
| panic(fmt.Errorf("PGDATA: %s the database directory does not exist", pgData)) |
| } |
| |
| pgData = strings.Trim(pgData, " ") |
| if strings.HasSuffix(pgData, "/") { |
| dirs := strings.Split(pgData, "/") |
| dirs = dirs[0 : len(dirs)-1] |
| pgData = strings.Join(dirs, "/") |
| } |
| |
| if strings.Trim(tlsCrt, " ") == "" || strings.Trim(tlsKey, " ") == "" { |
| panic(fmt.Errorf("lack of HTTPs certificate")) |
| } |
| |
| if _, err := os.Stat(tlsCrt); os.IsNotExist(err) { |
| panic(fmt.Errorf("TLS certificate file does not exist")) |
| } |
| if _, err := os.Stat(tlsKey); os.IsNotExist(err) { |
| panic(fmt.Errorf("TLS key file does not exist")) |
| } |
| |
| var level = zapcore.InfoLevel |
| if logLevel == debugLogLevel { |
| level = zapcore.DebugLevel |
| } |
| |
| log = logging.Init(level) |
| pkg.Init(shell, pgData, log) |
| |
| SetupApp() |
| |
| go func() { |
| if err := Serve(port); err != nil { |
| panic(err) |
| } |
| }() |
| log.Info("app startup successfully.") |
| |
| quit := make(chan os.Signal, 1) |
| signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) |
| <-quit |
| |
| if app != nil { |
| if err := app.Shutdown(); err != nil { |
| log.Field(logging.ErrorKey, err.Error()).Error("http app closed failure") |
| } |
| } |
| log.Info("app windup successfully.") |
| log.Info("app has exited...") |
| } |
| |
| func SetupApp() { |
| app = fiber.New() |
| |
| app.Use( |
| middleware.Recover(logging.Log()), |
| // middleware.UniformErrResp(logging.Log()), |
| middleware.UniformRawErrResp(logging.Log()), |
| ) |
| |
| app.Get("/ping", func(ctx *fiber.Ctx) error { |
| |
| return responder.Success(ctx, "pong") |
| }) |
| |
| app.Use( |
| middleware.AccessLog(logging.Log()), |
| middleware.Logger(logging.Log()), |
| ) |
| |
| app.Route("/api", func(r fiber.Router) { |
| r.Use(middleware.RequestIDChecker()) |
| |
| r.Post("/healthz", handler.HealthCheck) |
| r.Post("/backup", handler.Backup) |
| r.Delete("/backup", handler.DeleteBackup) |
| r.Post("/restore", handler.Restore) |
| r.Post("/show", handler.Show) |
| r.Post("/show/list", handler.ShowList) |
| r.Post("/diskspace", handler.DiskSpace) |
| }) |
| |
| // 404 |
| app.Use(func(ctx *fiber.Ctx) error { |
| return responder.NotFound(ctx, "API not found") |
| }) |
| } |
| |
| // Serve run a http server on the specified port. |
| func Serve(port string) error { |
| |
| //return app.Listen(":18080") |
| return app.ListenTLS(fmt.Sprintf(":%s", port), tlsCrt, tlsKey) |
| } |