code.vegaprotocol.io/vega@v0.79.0/datanode/admin/server.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package admin
    17  
    18  import (
    19  	"context"
    20  	"net"
    21  	"net/http"
    22  	"os"
    23  
    24  	"code.vegaprotocol.io/vega/logging"
    25  	"code.vegaprotocol.io/vega/paths"
    26  
    27  	"github.com/gorilla/mux"
    28  	"github.com/gorilla/rpc"
    29  	"github.com/gorilla/rpc/json"
    30  )
    31  
    32  type Server struct {
    33  	log                        *logging.Logger
    34  	cfg                        Config
    35  	srv                        *http.Server
    36  	networkHistoryAdminService *NetworkHistoryAdminService
    37  }
    38  
    39  func NewServer(log *logging.Logger, config Config, vegaPaths paths.Paths, service *NetworkHistoryAdminService) *Server {
    40  	// setup logger
    41  	log = log.Named(namedLogger)
    42  	log.SetLevel(config.Level.Get())
    43  
    44  	return &Server{
    45  		log:                        log,
    46  		cfg:                        config,
    47  		srv:                        nil,
    48  		networkHistoryAdminService: service,
    49  	}
    50  }
    51  
    52  // Start starts the RPC based API server.
    53  func (s *Server) Start(ctx context.Context) error {
    54  	s.log.Info("Starting Data Node Admin Server<>RPC based API",
    55  		logging.String("socket-path", s.cfg.Server.SocketPath),
    56  		logging.String("http-path", s.cfg.Server.HTTPPath),
    57  	)
    58  
    59  	rs := rpc.NewServer()
    60  	rs.RegisterCodec(json.NewCodec(), "application/json")
    61  	rs.RegisterCodec(json.NewCodec(), "application/json;charset=UTF-8")
    62  
    63  	if err := rs.RegisterService(s.networkHistoryAdminService, "networkhistory"); err != nil {
    64  		s.log.Panic("failed to register network history service", logging.Error(err))
    65  	}
    66  
    67  	r := mux.NewRouter()
    68  	r.Handle(s.cfg.Server.HTTPPath, rs)
    69  
    70  	// Try to remove the existing socket file just in case
    71  	if err := os.Remove(s.cfg.Server.SocketPath); err != nil {
    72  		// If we can't remove the socket and the error is not that the file doesn't exist, then we should panic
    73  		if !os.IsNotExist(err) {
    74  			s.log.Panic("failed to remove socket file", logging.Error(err))
    75  		}
    76  	}
    77  
    78  	l, err := net.Listen("unix", s.cfg.Server.SocketPath)
    79  	if err != nil {
    80  		s.log.Panic("failed to open unix socket", logging.Error(err))
    81  	}
    82  
    83  	s.srv = &http.Server{
    84  		Handler: r,
    85  	}
    86  
    87  	go func() {
    88  		<-ctx.Done()
    89  		s.Stop()
    90  	}()
    91  
    92  	s.log.Info("Data Node Admin Server<>RPC based API started")
    93  	return s.srv.Serve(l)
    94  }
    95  
    96  // Stop stops the RPC based API server.
    97  func (s *Server) Stop() {
    98  	if s.srv != nil {
    99  		s.log.Info("Stopping Data Node Admin Server<>RPC based API")
   100  		if err := s.srv.Shutdown(context.Background()); err != nil {
   101  			s.log.Error("failed to stop Data Node Admin server<>RPC based API cleanly",
   102  				logging.Error(err))
   103  		}
   104  	}
   105  }
   106  
   107  // ReloadConf update the internal configuration of the server.
   108  func (s *Server) ReloadConf(cfg Config) {
   109  	s.log.Info("reloading configuration")
   110  	if s.log.GetLevel() != cfg.Level.Get() {
   111  		s.log.Info("updating log level",
   112  			logging.String("old", s.log.GetLevel().String()),
   113  			logging.String("new", cfg.Level.String()),
   114  		)
   115  		s.log.SetLevel(cfg.Level.Get())
   116  	}
   117  
   118  	// TODO(): not updating the actual server for now, may need to look at this later
   119  	// e.g restart the http server on another port or whatever
   120  	s.cfg = cfg
   121  }