github.com/xmidt-org/webpa-common@v1.11.9/xhttp/fanout/configuration.go (about) 1 package fanout 2 3 import ( 4 "net/http" 5 "time" 6 7 gokithttp "github.com/go-kit/kit/transport/http" 8 "github.com/justinas/alice" 9 "github.com/xmidt-org/candlelight" 10 "github.com/xmidt-org/webpa-common/xhttp" 11 "github.com/xmidt-org/webpa-common/xhttp/xcontext" 12 "github.com/xmidt-org/webpa-common/xhttp/xtimeout" 13 "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" 14 ) 15 16 const ( 17 DefaultFanoutTimeout time.Duration = 45 * time.Second 18 DefaultClientTimeout time.Duration = 30 * time.Second 19 DefaultConcurrency = 1000 20 ) 21 22 // Configuration defines the configuration structure for externally configuring a fanout. 23 type Configuration struct { 24 // Endpoints are the URLs for each endpoint to fan out to. If unset, the default is supplied 25 // by application code, which is normally a set of endpoints driven by service discovery. 26 Endpoints []string `json:"endpoints,omitempty"` 27 28 // Authorization is the Basic Auth token. There is no default for this field. 29 Authorization string `json:"authorization"` 30 31 // Transport is the http.Client transport 32 Transport http.Transport `json:"transport"` 33 34 // FanoutTimeout is the timeout for the entire fanout operation. If not supplied, DefaultFanoutTimeout is used. 35 FanoutTimeout time.Duration `json:"fanoutTimeout"` 36 37 // ClientTimeout is the http.Client Timeout. If not set, DefaultClientTimeout is used. 38 ClientTimeout time.Duration `json:"clientTimeout"` 39 40 // Concurrency is the maximum number of concurrent fanouts allowed. If this is not set, DefaultConcurrency is used. 41 Concurrency int `json:"concurrency"` 42 43 // MaxRedirects defines the maximum number of redirects each fanout will allow 44 MaxRedirects int `json:"maxRedirects"` 45 46 // RedirectExcludeHeaders are the headers that will *not* be copied on a redirect 47 RedirectExcludeHeaders []string `json:"redirectExcludeHeaders,omitempty"` 48 49 // Tracing contains information to setup OpenTelemetry tracing on the fanout 50 // HTTP client. 51 Tracing candlelight.Tracing 52 } 53 54 func (c *Configuration) endpoints() []string { 55 if c != nil { 56 return c.Endpoints 57 } 58 59 return nil 60 } 61 62 func (c *Configuration) authorization() string { 63 if c != nil && len(c.Authorization) > 0 { 64 return c.Authorization 65 } 66 67 return "" 68 } 69 70 func (c *Configuration) fanoutTimeout() time.Duration { 71 if c != nil && c.FanoutTimeout > 0 { 72 return c.FanoutTimeout 73 } 74 75 return DefaultFanoutTimeout 76 } 77 78 func (c *Configuration) clientTimeout() time.Duration { 79 if c != nil && c.ClientTimeout > 0 { 80 return c.ClientTimeout 81 } 82 83 return DefaultClientTimeout 84 } 85 86 func (c *Configuration) transport() http.RoundTripper { 87 var transport http.RoundTripper = new(http.Transport) 88 if c != nil { 89 transport = otelhttp.NewTransport(transport, 90 otelhttp.WithPropagators(c.Tracing.Propagator()), 91 otelhttp.WithTracerProvider(c.Tracing.TracerProvider()), 92 ) 93 } 94 return transport 95 } 96 97 func (c *Configuration) concurrency() int { 98 if c != nil && c.Concurrency > 0 { 99 return c.Concurrency 100 } 101 102 return DefaultConcurrency 103 } 104 105 func (c *Configuration) maxRedirects() int { 106 if c != nil { 107 return c.MaxRedirects 108 } 109 110 return 0 111 } 112 113 func (c *Configuration) redirectExcludeHeaders() []string { 114 if c != nil { 115 return c.RedirectExcludeHeaders 116 } 117 118 return nil 119 } 120 121 func (c *Configuration) checkRedirect() func(*http.Request, []*http.Request) error { 122 return xhttp.CheckRedirect(xhttp.RedirectPolicy{ 123 MaxRedirects: c.maxRedirects(), 124 ExcludeHeaders: c.redirectExcludeHeaders(), 125 }) 126 } 127 128 // NewTransactor constructs an HTTP client transaction function from a set of fanout options. 129 func NewTransactor(c Configuration) func(*http.Request) (*http.Response, error) { 130 return (&http.Client{ 131 Transport: c.transport(), 132 CheckRedirect: c.checkRedirect(), 133 Timeout: c.clientTimeout(), 134 }).Do 135 } 136 137 // NewChain constructs an Alice constructor Chain from a set of fanout options and zero or 138 // more application-layer request functions. 139 func NewChain(c Configuration, rf ...gokithttp.RequestFunc) alice.Chain { 140 return alice.New( 141 xtimeout.NewConstructor(xtimeout.Options{ 142 Timeout: c.fanoutTimeout(), 143 }), 144 xcontext.Populate(rf...), 145 xhttp.Busy(c.concurrency()), 146 ) 147 }