github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/vent/service/server.go (about)

     1  package service
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"net/http"
     7  
     8  	"github.com/hyperledger/burrow/logging"
     9  	"github.com/hyperledger/burrow/vent/config"
    10  )
    11  
    12  // Server exposes HTTP endpoints for the service
    13  type Server struct {
    14  	Config   *config.VentConfig
    15  	Log      *logging.Logger
    16  	Consumer *Consumer
    17  	mux      *http.ServeMux
    18  	stopCh   chan bool
    19  }
    20  
    21  // NewServer returns a new HTTP server
    22  func NewServer(cfg *config.VentConfig, log *logging.Logger, consumer *Consumer) *Server {
    23  	// setup handlers
    24  	mux := http.NewServeMux()
    25  
    26  	mux.HandleFunc("/health", healthHandler(consumer))
    27  
    28  	return &Server{
    29  		Config:   cfg,
    30  		Log:      log,
    31  		Consumer: consumer,
    32  		mux:      mux,
    33  		stopCh:   make(chan bool, 1),
    34  	}
    35  }
    36  
    37  // Run starts the HTTP server
    38  func (s *Server) Run() {
    39  	s.Log.InfoMsg("Starting HTTP Server")
    40  
    41  	// start http server
    42  	httpServer := &http.Server{Addr: s.Config.HTTPListenAddress, Handler: s}
    43  
    44  	go func() {
    45  		s.Log.InfoMsg("HTTP Server listening", "address", s.Config.HTTPListenAddress)
    46  		httpServer.ListenAndServe()
    47  	}()
    48  
    49  	// wait for stop signal
    50  	<-s.stopCh
    51  
    52  	s.Log.InfoMsg("Shutting down HTTP Server...")
    53  
    54  	httpServer.Shutdown(context.Background())
    55  }
    56  
    57  // ServeHTTP dispatches the HTTP requests using the Server Mux
    58  func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
    59  	s.mux.ServeHTTP(resp, req)
    60  }
    61  
    62  // Shutdown gracefully shuts down the HTTP Server
    63  func (s *Server) Shutdown() {
    64  	s.stopCh <- true
    65  }
    66  
    67  func healthHandler(consumer *Consumer) func(resp http.ResponseWriter, req *http.Request) {
    68  	return func(resp http.ResponseWriter, req *http.Request) {
    69  		err := consumer.Health()
    70  		if err != nil {
    71  			resp.WriteHeader(http.StatusServiceUnavailable)
    72  		} else {
    73  			resp.WriteHeader(http.StatusOK)
    74  			bs, err := json.Marshal(consumer.StatusMessage(req.Context()))
    75  			if err == nil {
    76  				resp.Header().Set("Content-Type", "application/json")
    77  				resp.Write(bs)
    78  			}
    79  		}
    80  	}
    81  }