github.com/blend/go-sdk@v1.20220411.3/status/controller.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package status
     9  
    10  import (
    11  	"net/http"
    12  	"time"
    13  
    14  	"github.com/blend/go-sdk/async"
    15  	"github.com/blend/go-sdk/configmeta"
    16  	"github.com/blend/go-sdk/logger"
    17  	"github.com/blend/go-sdk/web"
    18  )
    19  
    20  // NewController returns a new controller
    21  func NewController(opts ...ControllerOption) *Controller {
    22  	controller := Controller{
    23  		Checks:         NewFreeform(),
    24  		TrackedActions: NewTrackedActionAggregator(),
    25  	}
    26  	for _, opt := range opts {
    27  		opt(&controller)
    28  	}
    29  	return &controller
    30  }
    31  
    32  // ControllerOption mutates a controller.
    33  type ControllerOption func(c *Controller)
    34  
    35  // OptConfig returns an option that sets the configmeta.
    36  func OptConfig(cfg configmeta.Meta) ControllerOption {
    37  	return func(c *Controller) {
    38  		c.Config = cfg
    39  	}
    40  }
    41  
    42  // OptLog returns an option that sets the logger.
    43  func OptLog(log logger.Log) ControllerOption {
    44  	return func(c *Controller) {
    45  		c.Checks.Log = log
    46  		c.TrackedActions.Log = log
    47  	}
    48  }
    49  
    50  // OptTimeout returns an option that sets checks timeout.
    51  func OptTimeout(timeout time.Duration) ControllerOption {
    52  	return func(c *Controller) {
    53  		c.Checks.Timeout = timeout
    54  	}
    55  }
    56  
    57  // OptUseBareMethods returns an option that sets if we should use bare methods.
    58  func OptUseBareMethods(useBareMethods bool) ControllerOption {
    59  	return func(c *Controller) {
    60  		c.UseBareMethods = useBareMethods
    61  	}
    62  }
    63  
    64  // OptCheck adds an sla check for a given service.
    65  func OptCheck(serviceName string, check Checker) ControllerOption {
    66  	return func(c *Controller) {
    67  		if c.Checks.ServiceChecks == nil {
    68  			c.Checks.ServiceChecks = make(map[string]Checker)
    69  		}
    70  		c.Checks.ServiceChecks[serviceName] = check
    71  	}
    72  }
    73  
    74  // OptMiddleware adds default middleware for the status routes.
    75  //
    76  // Middleware must be set _before_ you register the controller.
    77  func OptMiddleware(middleware ...web.Middleware) ControllerOption {
    78  	return func(c *Controller) {
    79  		c.Middleware = append(c.Middleware, middleware...)
    80  	}
    81  }
    82  
    83  // Controller is a handler for the status endpoint.
    84  //
    85  // It will register `/status/sla` and `/status/details` routes
    86  // on the given app.
    87  type Controller struct {
    88  	Config         configmeta.Meta
    89  	Checks         *Freeform
    90  	TrackedActions *TrackedActionAggregator
    91  	Middleware     []web.Middleware
    92  	UseBareMethods bool
    93  }
    94  
    95  // Register adds the controller's routes to the app.
    96  func (c Controller) Register(app *web.App) {
    97  	if c.UseBareMethods {
    98  		app.MethodBare(http.MethodGet, "/status", c.getStatus, c.Middleware...)
    99  		app.MethodBare(http.MethodGet, "/status/sla", c.getStatusSLA, c.Middleware...)
   100  		app.MethodBare(http.MethodGet, "/status/details", c.getStatusDetails, c.Middleware...)
   101  	} else {
   102  		app.GET("/status", c.getStatus, c.Middleware...)
   103  		app.GET("/status/sla", c.getStatusSLA, c.Middleware...)
   104  		app.GET("/status/details", c.getStatusDetails, c.Middleware...)
   105  	}
   106  }
   107  
   108  // Interceptor returns a new interceptor for a given serviceName.
   109  func (c Controller) Interceptor(serviceName string) async.Interceptor {
   110  	return c.TrackedActions.Interceptor(serviceName)
   111  }
   112  
   113  // GET /status
   114  func (c Controller) getStatus(r *web.Ctx) web.Result {
   115  	return web.JSON.Result(c.Config)
   116  }
   117  
   118  // GET /status/sla
   119  func (c Controller) getStatusSLA(r *web.Ctx) web.Result {
   120  	return c.Checks.Endpoint()(r)
   121  }
   122  
   123  // GET /status/details
   124  func (c Controller) getStatusDetails(r *web.Ctx) web.Result {
   125  	return c.TrackedActions.Endpoint()(r)
   126  }