github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/plugin/cb/middleware.go (about) 1 package cb 2 3 import ( 4 "errors" 5 "fmt" 6 "net/http" 7 8 "github.com/Knetic/govaluate" 9 "github.com/afex/hystrix-go/hystrix" 10 "github.com/felixge/httpsnoop" 11 log "github.com/sirupsen/logrus" 12 13 janusErr "github.com/hellofresh/janus/pkg/errors" 14 ) 15 16 const ( 17 defaultPredicate = "statusCode == 0 || statusCode >= 500" 18 ) 19 20 // NewCBMiddleware creates a new cb middleware 21 func NewCBMiddleware(cfg Config) func(http.Handler) http.Handler { 22 return func(handler http.Handler) http.Handler { 23 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 24 logger := log.WithFields(log.Fields{ 25 "name": cfg.Name, 26 "timeout": cfg.Timeout, 27 "max_concurrent_requests": cfg.MaxConcurrentRequests, 28 "error_percent_threshold": cfg.ErrorPercentThreshold, 29 }) 30 31 logger.Debug("Starting cb middleware") 32 if cfg.Predicate == "" { 33 cfg.Predicate = defaultPredicate 34 } 35 36 expression, err := govaluate.NewEvaluableExpression(cfg.Predicate) 37 if err != nil { 38 log.WithError(err).Error("could not create an expression with this predicate") 39 handler.ServeHTTP(w, r) 40 return 41 } 42 43 err = hystrix.Do(cfg.Name, func() error { 44 m := httpsnoop.CaptureMetrics(handler, w, r) 45 params := make(map[string]interface{}, 8) 46 params["statusCode"] = m.Code 47 params["request"] = r 48 49 result, err := expression.Evaluate(params) 50 if err != nil { 51 return errors.New("cannot evaluate the expression") 52 } 53 54 if result.(bool) { 55 return fmt.Errorf("%s %s request failed", r.Method, r.URL) 56 } 57 58 return nil 59 }, nil) 60 61 if err != nil { 62 logger.WithError(err).Error("Request failed on the cb middleware") 63 janusErr.Handler(w, r, fmt.Errorf("request failed: %w", err)) 64 } 65 }) 66 } 67 }