DE-3247 | refactored code and added logs
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
metrics "com.navi.medici.janus/instrumentation"
|
||||
"com.navi.medici.janus/lib"
|
||||
"com.navi.medici.janus/utils"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
metrics "com.navi.medici.janus/instrumentation"
|
||||
"com.navi.medici.janus/lib"
|
||||
"com.navi.medici.janus/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
logger *zap.Logger
|
||||
healthyBool bool = true
|
||||
)
|
||||
|
||||
@@ -29,60 +31,68 @@ type CustomResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func eventsHandlerJson(w http.ResponseWriter, r *http.Request) {
|
||||
eventHandlerStartTime := utils.NanosToMillis(time.Now().UnixNano())
|
||||
|
||||
headerName := "X-Correlation-Id"
|
||||
substring := "abcdabcd-1234"
|
||||
headerValue, ok := r.Header[headerName]
|
||||
if ok {
|
||||
if strings.HasPrefix(headerValue[0], substring) {
|
||||
func init() {
|
||||
logger = utils.GetLogger()
|
||||
}
|
||||
|
||||
func eventsHandlerJson(workerPool *lib.WorkerPool) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
eventHandlerStartTime := utils.NanosToMillis(time.Now().UnixNano())
|
||||
|
||||
headerName := "X-Correlation-Id"
|
||||
substring := "abcdabcd-1234"
|
||||
headerValue := r.Header.Get(headerName)
|
||||
if strings.HasPrefix(headerValue, substring) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var rsp = CustomResponse{Code: 200, Message: "OK"}
|
||||
rsp := CustomResponse{Code: 200, Message: "OK"}
|
||||
json.NewEncoder(w).Encode(rsp)
|
||||
fmt.Println("Dropped blacklisted request")
|
||||
logger.Info("Dropped blacklisted request", zap.String("correlationID", headerValue))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var reader io.Reader
|
||||
// check if body is gzip compressed
|
||||
if r.Header.Get("Content-Encoding") == "gzip" {
|
||||
var err error
|
||||
reader, err = gzip.NewReader(r.Body)
|
||||
}
|
||||
|
||||
var reader io.Reader
|
||||
switch r.Header.Get("Content-Encoding") {
|
||||
case "gzip":
|
||||
var err error
|
||||
reader, err = gzip.NewReader(r.Body)
|
||||
if err != nil {
|
||||
logger.Error("Error decompressing GZIP payload", zap.Error(err))
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
http.Error(w, "Error decompressing GZIP payload", http.StatusBadRequest)
|
||||
metrics.EventHandlerTimeHist.WithLabelValues(JSON, ERROR).Observe(float64(utils.NanosToMillis(time.Now().UnixNano()) - eventHandlerStartTime))
|
||||
return
|
||||
}
|
||||
defer reader.(*gzip.Reader).Close()
|
||||
default:
|
||||
reader = r.Body
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(reader) // todo Limit to 1MB
|
||||
if err != nil {
|
||||
// log.Printf(err)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
http.Error(w, "Error while decompressing GZIP payload", http.StatusBadRequest)
|
||||
logger.Error("Error reading request body", zap.Error(err))
|
||||
http.Error(w, "Request body invalid", http.StatusBadRequest)
|
||||
metrics.EventHandlerTimeHist.WithLabelValues(JSON, ERROR).Observe(float64(utils.NanosToMillis(time.Now().UnixNano()) - eventHandlerStartTime))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
reader = r.Body
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
// log.Printf(err)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
http.Error(w, "Request body invalid", http.StatusBadRequest)
|
||||
metrics.EventHandlerTimeHist.WithLabelValues(JSON, ERROR).Observe(float64(utils.NanosToMillis(time.Now().UnixNano()) - eventHandlerStartTime))
|
||||
return
|
||||
|
||||
workerPool.AddJob(lib.RequestObject{Body: body, Header: r.Header})
|
||||
|
||||
rsp := CustomResponse{Code: 200, Message: "OK"}
|
||||
if err := json.NewEncoder(w).Encode(rsp); err != nil {
|
||||
logger.Error("Error encoding response", zap.Error(err))
|
||||
}
|
||||
metrics.EventHandlerTimeHist.WithLabelValues(JSON, SUCCESS).Observe(float64(utils.NanosToMillis(time.Now().UnixNano()) - eventHandlerStartTime))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
lib.JsonRequestChannel <- &lib.RequestObject{Body: body, Header: r.Header}
|
||||
var rsp = CustomResponse{Code: 200, Message: "OK"}
|
||||
json.NewEncoder(w).Encode(rsp)
|
||||
metrics.EventHandlerTimeHist.WithLabelValues(JSON, SUCCESS).Observe(float64(utils.NanosToMillis(time.Now().UnixNano()) - eventHandlerStartTime))
|
||||
}
|
||||
|
||||
func healthHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if healthyBool {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
io.WriteString(w, "true")
|
||||
io.WriteString(w, `{"status":"healthy"}`)
|
||||
} else {
|
||||
http.Error(w, "server unhealthy", http.StatusServiceUnavailable)
|
||||
return
|
||||
http.Error(w, `{"status":"unhealthy"}`, http.StatusServiceUnavailable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"com.navi.medici.janus/lib"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/rs/cors"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
HttpServer *http.Server
|
||||
Listener net.Listener
|
||||
wg sync.WaitGroup
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
var (
|
||||
networkTCP = "tcp"
|
||||
)
|
||||
|
||||
func NewServer(port string, corsList string) (*Server, error) {
|
||||
|
||||
func NewServer(port string, corsList string, workerPool *lib.WorkerPool, logger *zap.Logger) (*Server, error) {
|
||||
network := networkTCP
|
||||
|
||||
listener, err := net.Listen(network, ":"+port)
|
||||
@@ -33,39 +34,74 @@ func NewServer(port string, corsList string) (*Server, error) {
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/events/json", eventsHandlerJson).Methods("POST")
|
||||
router.HandleFunc("/events/json", eventsHandlerJson(workerPool)).Methods("POST")
|
||||
router.HandleFunc("/health", healthHandler).Methods("GET")
|
||||
|
||||
httpServer := &http.Server{Addr: ":" + port, Handler: enableCors(router, corsList)}
|
||||
newServer := &Server{HttpServer: httpServer, Listener: listener}
|
||||
return newServer, nil
|
||||
httpServer := &http.Server{
|
||||
Addr: ":" + port,
|
||||
Handler: enableCors(router, corsList),
|
||||
}
|
||||
|
||||
newServer := &Server{
|
||||
HttpServer: httpServer,
|
||||
Listener: listener,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
return newServer, nil
|
||||
}
|
||||
|
||||
func enableCors(handler http.Handler, corsList string) http.Handler {
|
||||
corsArray := strings.Split(corsList, ",")
|
||||
fmt.Print(corsArray)
|
||||
c := cors.New(cors.Options{
|
||||
AllowedOrigins: corsArray,
|
||||
AllowCredentials: false,
|
||||
// Enable Debugging for testing, consider disabling in production
|
||||
Debug: false,
|
||||
Debug: false,
|
||||
})
|
||||
return c.Handler(handler)
|
||||
}
|
||||
func MetricServer(port string) (*Server, error) {
|
||||
|
||||
func MetricServer(port string, logger *zap.Logger) (*Server, error) {
|
||||
network := networkTCP
|
||||
|
||||
listener, err := net.Listen(network, ":"+port)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create listener")
|
||||
return nil, errors.Wrap(err, "failed to create listener for metric server")
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
|
||||
router.Path("/metrics").Handler(promhttp.Handler())
|
||||
|
||||
httpServer := &http.Server{Addr: ":" + port, Handler: router}
|
||||
mServer := &Server{HttpServer: httpServer, Listener: listener}
|
||||
httpServer := &http.Server{
|
||||
Addr: ":" + port,
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
mServer := &Server{
|
||||
HttpServer: httpServer,
|
||||
Listener: listener,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
return mServer, nil
|
||||
}
|
||||
|
||||
func (s *Server) StartServer() {
|
||||
s.wg.Add(1)
|
||||
go func() {
|
||||
defer s.wg.Done()
|
||||
s.logger.Info("Starting server", zap.String("address", s.HttpServer.Addr))
|
||||
if err := s.HttpServer.Serve(s.Listener); err != nil && err != http.ErrServerClosed {
|
||||
s.logger.Fatal("Server error", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *Server) StopServer() {
|
||||
s.logger.Info("Stopping server", zap.String("address", s.HttpServer.Addr))
|
||||
if err := s.HttpServer.Close(); err != nil {
|
||||
s.logger.Error("Error stopping server", zap.Error(err))
|
||||
}
|
||||
s.wg.Wait()
|
||||
s.logger.Info("Server stopped", zap.String("address", s.HttpServer.Addr))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user