This is an automated email from the ASF dual-hosted git repository.

tokers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 3cfc327  refactor: server manager (#1956)
3cfc327 is described below

commit 3cfc32761122ad7f15f67edcfc251d0bed2e7538
Author: bzp2010 <[email protected]>
AuthorDate: Wed Jun 30 19:12:42 2021 +0800

    refactor: server manager (#1956)
---
 api/cmd/root.go                                    | 137 ++------------------
 api/cmd/version.go                                 |  11 +-
 api/internal/core/server/http.go                   |  72 +++++++++++
 api/internal/core/server/server.go                 | 144 +++++++++++++++++++++
 .../version.go => internal/core/server/store.go}   |  34 ++---
 api/internal/utils/version.go                      |  14 +-
 api/test/shell/cli_test.sh                         |   2 +-
 7 files changed, 259 insertions(+), 155 deletions(-)

diff --git a/api/cmd/root.go b/api/cmd/root.go
index 05e16a2..b9d2aa4 100644
--- a/api/cmd/root.go
+++ b/api/cmd/root.go
@@ -17,28 +17,16 @@
 package cmd
 
 import (
-       "context"
-       "crypto/tls"
        "fmt"
-       "net"
-       "net/http"
        "os"
        "os/signal"
-       "strconv"
        "syscall"
-       "time"
 
-       "github.com/shiningrush/droplet"
        "github.com/spf13/cobra"
 
-       "github.com/apisix/manager-api/internal"
        "github.com/apisix/manager-api/internal/conf"
-       "github.com/apisix/manager-api/internal/core/storage"
-       "github.com/apisix/manager-api/internal/core/store"
-       "github.com/apisix/manager-api/internal/filter"
-       "github.com/apisix/manager-api/internal/handler"
+       "github.com/apisix/manager-api/internal/core/server"
        "github.com/apisix/manager-api/internal/log"
-       "github.com/apisix/manager-api/internal/utils"
 )
 
 var (
@@ -88,126 +76,29 @@ func manageAPI() error {
        conf.InitConf()
        log.InitLogger()
 
-       if err := utils.WritePID(conf.PIDPath, forceStart); err != nil {
-               log.Errorf("failed to write pid: %s", err)
+       s, err := server.NewServer(&server.Options{
+               ForceStart: forceStart,
+       })
+       if err != nil {
                return err
        }
-       utils.AppendToClosers(func() error {
-               if err := os.Remove(conf.PIDPath); err != nil {
-                       log.Errorf("failed to remove pid path: %s", err)
-                       return err
-               }
-               return nil
-       })
+
+       // start Manager API server
+       errSig := make(chan error, 5)
+       s.Start(errSig)
 
        // Signal received to the process externally.
        quit := make(chan os.Signal, 1)
        signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
 
-       defer func() {
-               utils.CloseAll()
-               signal.Stop(quit)
-       }()
-
-       droplet.Option.Orchestrator = func(mws []droplet.Middleware) 
[]droplet.Middleware {
-               var newMws []droplet.Middleware
-               // default middleware order: resp_reshape, auto_input, 
traffic_log
-               // We should put err_transform at second to catch all error
-               newMws = append(newMws, mws[0], 
&handler.ErrorTransformMiddleware{}, &filter.AuthenticationMiddleware{})
-               newMws = append(newMws, mws[1:]...)
-               return newMws
-       }
-
-       if err := storage.InitETCDClient(conf.ETCDConfig); err != nil {
-               log.Errorf("init etcd client fail: %w", err)
-               return err
-       }
-       if err := store.InitStores(); err != nil {
-               log.Errorf("init stores fail: %w", err)
-               return err
-       }
-
-       var server, serverSSL *http.Server
-       // For internal error handling across multiple goroutines.
-       errsig := make(chan error, 1)
-
-       // routes
-       r := internal.SetUpRouter()
-       addr := net.JoinHostPort(conf.ServerHost, strconv.Itoa(conf.ServerPort))
-       server = &http.Server{
-               Addr:         addr,
-               Handler:      r,
-               ReadTimeout:  time.Duration(1000) * time.Millisecond,
-               WriteTimeout: time.Duration(5000) * time.Millisecond,
-       }
-
-       log.Infof("The Manager API is listening on %s", addr)
-
-       go func() {
-               if err := server.ListenAndServe(); err != nil && err != 
http.ErrServerClosed {
-                       log.Errorf("listen and serv fail: %s", err)
-                       errsig <- err
-               }
-       }()
-
-       // HTTPS
-       if conf.SSLCert != "" && conf.SSLKey != "" {
-               addrSSL := net.JoinHostPort(conf.ServerHost, 
strconv.Itoa(conf.SSLPort))
-               serverSSL = &http.Server{
-                       Addr:         addrSSL,
-                       Handler:      r,
-                       ReadTimeout:  time.Duration(1000) * time.Millisecond,
-                       WriteTimeout: time.Duration(5000) * time.Millisecond,
-                       TLSConfig: &tls.Config{
-                               // Causes servers to use Go's default 
ciphersuite preferences,
-                               // which are tuned to avoid attacks. Does 
nothing on clients.
-                               PreferServerCipherSuites: true,
-                       },
-               }
-               go func() {
-                       err := serverSSL.ListenAndServeTLS(conf.SSLCert, 
conf.SSLKey)
-                       if err != nil && err != http.ErrServerClosed {
-                               log.Errorf("listen and serve for HTTPS failed: 
%s", err)
-                               errsig <- err
-                       }
-               }()
-       }
-
-       printInfo()
-
        select {
-       case err := <-errsig:
-               return err
-
        case sig := <-quit:
                log.Infof("The Manager API server receive %s and start shutting 
down", sig.String())
-
-               shutdownServer(server)
-               shutdownServer(serverSSL)
+               s.Stop()
                log.Infof("The Manager API server exited")
-               return nil
-       }
-}
-
-func shutdownServer(server *http.Server) {
-       if server != nil {
-               ctx, cancel := context.WithTimeout(context.TODO(), 
5*time.Second)
-               defer cancel()
-
-               if err := server.Shutdown(ctx); err != nil {
-                       log.Errorf("Shutting down server error: %s", err)
-               }
-       }
-}
-
-func printInfo() {
-       fmt.Fprint(os.Stdout, "The manager-api is running successfully!\n\n")
-       printVersion()
-       fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "Listen", conf.ServerHost, 
conf.ServerPort)
-       if conf.SSLCert != "" && conf.SSLKey != "" {
-               fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "HTTPS Listen", 
conf.SSLHost, conf.SSLPort)
+       case err := <-errSig:
+               log.Errorf("The Manager API server start failed: %s", 
err.Error())
+               return err
        }
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Loglevel", conf.ErrorLogLevel)
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "ErrorLogFile", conf.ErrorLogPath)
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n\n", "AccessLogFile", 
conf.AccessLogPath)
+       return nil
 }
diff --git a/api/cmd/version.go b/api/cmd/version.go
index df7abc1..c064502 100644
--- a/api/cmd/version.go
+++ b/api/cmd/version.go
@@ -17,9 +17,6 @@
 package cmd
 
 import (
-       "fmt"
-       "os"
-
        "github.com/spf13/cobra"
 
        "github.com/apisix/manager-api/internal/utils"
@@ -30,13 +27,7 @@ func newVersionCommand() *cobra.Command {
                Use:   "version",
                Short: "show manager-api version",
                Run: func(cmd *cobra.Command, args []string) {
-                       printVersion()
+                       utils.PrintVersion()
                },
        }
 }
-
-func printVersion() {
-       gitHash, version := utils.GetHashAndVersion()
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Version", version)
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "GitHash", gitHash)
-}
diff --git a/api/internal/core/server/http.go b/api/internal/core/server/http.go
new file mode 100644
index 0000000..53a4216
--- /dev/null
+++ b/api/internal/core/server/http.go
@@ -0,0 +1,72 @@
+/*
+ * 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 server
+
+import (
+       "crypto/tls"
+       "net"
+       "net/http"
+       "strconv"
+       "time"
+
+       "github.com/shiningrush/droplet"
+
+       "github.com/apisix/manager-api/internal"
+       "github.com/apisix/manager-api/internal/conf"
+       "github.com/apisix/manager-api/internal/filter"
+       "github.com/apisix/manager-api/internal/handler"
+)
+
+func (s *server) setupAPI() {
+       // orchestrator
+       droplet.Option.Orchestrator = func(mws []droplet.Middleware) 
[]droplet.Middleware {
+               var newMws []droplet.Middleware
+               // default middleware order: resp_reshape, auto_input, 
traffic_log
+               // We should put err_transform at second to catch all error
+               newMws = append(newMws, mws[0], 
&handler.ErrorTransformMiddleware{}, &filter.AuthenticationMiddleware{})
+               newMws = append(newMws, mws[1:]...)
+               return newMws
+       }
+
+       // routes
+       r := internal.SetUpRouter()
+
+       // HTTP
+       addr := net.JoinHostPort(conf.ServerHost, strconv.Itoa(conf.ServerPort))
+       s.server = &http.Server{
+               Addr:         addr,
+               Handler:      r,
+               ReadTimeout:  time.Duration(1000) * time.Millisecond,
+               WriteTimeout: time.Duration(5000) * time.Millisecond,
+       }
+
+       // HTTPS
+       if conf.SSLCert != "" && conf.SSLKey != "" {
+               addrSSL := net.JoinHostPort(conf.SSLHost, 
strconv.Itoa(conf.SSLPort))
+               s.serverSSL = &http.Server{
+                       Addr:         addrSSL,
+                       Handler:      r,
+                       ReadTimeout:  time.Duration(1000) * time.Millisecond,
+                       WriteTimeout: time.Duration(5000) * time.Millisecond,
+                       TLSConfig: &tls.Config{
+                               // Causes servers to use Go's default 
ciphersuite preferences,
+                               // which are tuned to avoid attacks. Does 
nothing on clients.
+                               PreferServerCipherSuites: true,
+                       },
+               }
+       }
+}
diff --git a/api/internal/core/server/server.go 
b/api/internal/core/server/server.go
new file mode 100644
index 0000000..07c4b1c
--- /dev/null
+++ b/api/internal/core/server/server.go
@@ -0,0 +1,144 @@
+/*
+ * 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 server
+
+import (
+       "context"
+       "fmt"
+       "net/http"
+       "os"
+       "time"
+
+       "github.com/apisix/manager-api/internal/conf"
+       "github.com/apisix/manager-api/internal/log"
+       "github.com/apisix/manager-api/internal/utils"
+)
+
+// server is the manager of Manager API, which is responsible for managing the 
life cycle of Manager API, including initialization, start, stop and so on
+type server struct {
+       server    *http.Server
+       serverSSL *http.Server
+       options   *Options
+}
+
+type Options struct {
+       ForceStart bool // force start new instance
+}
+
+// NewServer Create a server manager
+func NewServer(options *Options) (*server, error) {
+       return &server{options: options}, nil
+}
+
+func (s *server) Start(errSig chan error) {
+       // initialize server
+       err := s.init()
+       if err != nil {
+               errSig <- err
+               return
+       }
+
+       // write daemon pid file
+       err = s.writePID()
+       if err != nil {
+               errSig <- err
+               return
+       }
+
+       // print server info to stdout
+       s.printInfo()
+
+       // start HTTP server
+       log.Infof("The Manager API is listening on %s", s.server.Addr)
+       go func() {
+               err := s.server.ListenAndServe()
+               if err != nil && err != http.ErrServerClosed {
+                       log.Errorf("listen and serv fail: %s", err)
+                       errSig <- err
+               }
+       }()
+
+       // start HTTPs server
+       if conf.SSLCert != "" && conf.SSLKey != "" {
+               go func() {
+                       err := s.serverSSL.ListenAndServeTLS(conf.SSLCert, 
conf.SSLKey)
+                       if err != nil && err != http.ErrServerClosed {
+                               log.Errorf("listen and serve for HTTPS failed: 
%s", err)
+                               errSig <- err
+                       }
+               }()
+       }
+}
+
+func (s *server) Stop() {
+       utils.CloseAll()
+
+       s.shutdownServer(s.server)
+       s.shutdownServer(s.serverSSL)
+}
+
+func (s *server) init() error {
+       log.Info("Initialize Manager API store")
+       err := s.setupStore()
+       if err != nil {
+               return err
+       }
+
+       log.Info("Initialize Manager API server")
+       s.setupAPI()
+
+       return nil
+}
+
+func (s *server) writePID() error {
+       if err := utils.WritePID(conf.PIDPath, s.options.ForceStart); err != 
nil {
+               log.Errorf("failed to write pid: %s", err)
+               return err
+       }
+       utils.AppendToClosers(func() error {
+               if err := os.Remove(conf.PIDPath); err != nil {
+                       log.Errorf("failed to remove pid path: %s", err)
+                       return err
+               }
+               return nil
+       })
+
+       return nil
+}
+
+func (s *server) shutdownServer(server *http.Server) {
+       if server != nil {
+               ctx, cancel := context.WithTimeout(context.TODO(), 
5*time.Second)
+               defer cancel()
+
+               if err := server.Shutdown(ctx); err != nil {
+                       log.Errorf("Shutting down server error: %s", err)
+               }
+       }
+}
+
+func (s *server) printInfo() {
+       fmt.Fprint(os.Stdout, "The manager-api is running successfully!\n\n")
+       utils.PrintVersion()
+       fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "Listen", conf.ServerHost, 
conf.ServerPort)
+       if conf.SSLCert != "" && conf.SSLKey != "" {
+               fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "HTTPS Listen", 
conf.SSLHost, conf.SSLPort)
+       }
+       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Loglevel", conf.ErrorLogLevel)
+       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "ErrorLogFile", conf.ErrorLogPath)
+       fmt.Fprintf(os.Stdout, "%-8s: %s\n\n", "AccessLogFile", 
conf.AccessLogPath)
+}
diff --git a/api/cmd/version.go b/api/internal/core/server/store.go
similarity index 62%
copy from api/cmd/version.go
copy to api/internal/core/server/store.go
index df7abc1..6130a19 100644
--- a/api/cmd/version.go
+++ b/api/internal/core/server/store.go
@@ -14,29 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package cmd
+package server
 
 import (
-       "fmt"
-       "os"
-
-       "github.com/spf13/cobra"
-
-       "github.com/apisix/manager-api/internal/utils"
+       "github.com/apisix/manager-api/internal/conf"
+       "github.com/apisix/manager-api/internal/core/storage"
+       "github.com/apisix/manager-api/internal/core/store"
+       "github.com/apisix/manager-api/internal/log"
 )
 
-func newVersionCommand() *cobra.Command {
-       return &cobra.Command{
-               Use:   "version",
-               Short: "show manager-api version",
-               Run: func(cmd *cobra.Command, args []string) {
-                       printVersion()
-               },
+func (s *server) setupStore() error {
+       if err := storage.InitETCDClient(conf.ETCDConfig); err != nil {
+               log.Errorf("init etcd client fail: %w", err)
+               return err
        }
-}
-
-func printVersion() {
-       gitHash, version := utils.GetHashAndVersion()
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Version", version)
-       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "GitHash", gitHash)
+       if err := store.InitStores(); err != nil {
+               log.Errorf("init stores fail: %w", err)
+               return err
+       }
+       return nil
 }
diff --git a/api/internal/utils/version.go b/api/internal/utils/version.go
index d4bec4a..c061156 100644
--- a/api/internal/utils/version.go
+++ b/api/internal/utils/version.go
@@ -16,12 +16,24 @@
  */
 package utils
 
+import (
+       "fmt"
+       "os"
+)
+
 var (
        gitHash string
        version string
 )
 
-// get the hash and version
+// GetHashAndVersion get the hash and version
 func GetHashAndVersion() (string, string) {
        return gitHash, version
 }
+
+// PrintVersion print version and git hash to stdout
+func PrintVersion() {
+       gitHash, version := GetHashAndVersion()
+       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Version", version)
+       fmt.Fprintf(os.Stdout, "%-8s: %s\n", "GitHash", gitHash)
+}
diff --git a/api/test/shell/cli_test.sh b/api/test/shell/cli_test.sh
index 325b0a4..1bbb66f 100755
--- a/api/test/shell/cli_test.sh
+++ b/api/test/shell/cli_test.sh
@@ -223,7 +223,7 @@ sleep 6
 
 cat ${logfile}
 
-if [[ `grep -c "cmd/root.go" ${logfile}` -ne '1' ]]; then
+if [[ `grep -c "server/store.go" ${logfile}` -ne '1' ]]; then
     echo "failed: failed to write the correct caller"
     exit 1
 fi

Reply via email to