Skip to content

Commit 7e93f4d

Browse files
authored
Merge pull request #175 from kaleido-io/config-ffreq-header
[ffapi] [ffresty] Allow for Configuring Request Header for Distributed Trace Logging
2 parents db05736 + eedc099 commit 7e93f4d

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

pkg/ffapi/handler.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,24 @@ import (
3939
"github.com/sirupsen/logrus"
4040
)
4141

42-
const FFRequestIDHeader = "X-FireFly-Request-ID"
42+
const DefaultRequestIDHeader = "X-FireFly-Request-ID"
43+
44+
var (
45+
requestIDHeader = DefaultRequestIDHeader
46+
)
47+
48+
// RequestIDHeader returns the header name used to pass the request ID for
49+
// ffapi server and ffresty client requests.
50+
func RequestIDHeader() string {
51+
return requestIDHeader
52+
}
53+
54+
// SetRequestIDHeader configures the header used to pass the request ID between
55+
// ffapi server and ffresty client requests. Should be set at initialization of
56+
// a process.
57+
func SetRequestIDHeader(header string) {
58+
requestIDHeader = header
59+
}
4360

4461
type (
4562
CtxHeadersKey struct{}
@@ -343,7 +360,7 @@ func (hs *HandlerFactory) APIWrapper(handler HandlerFunction) http.HandlerFunc {
343360

344361
reqTimeout := hs.getTimeout(req)
345362
ctx, cancel := context.WithTimeout(req.Context(), reqTimeout)
346-
httpReqID := req.Header.Get(FFRequestIDHeader)
363+
httpReqID := req.Header.Get(RequestIDHeader())
347364
if httpReqID == "" {
348365
httpReqID = fftypes.ShortID()
349366
}

pkg/ffapi/handler_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,26 @@ func TestRouteServePOST201WithParams(t *testing.T) {
108108
assert.Equal(t, "true", r.QP["param2"])
109109
assert.Equal(t, "false", r.QP["param3"])
110110
assert.Equal(t, []string{"x", "y"}, r.QAP["param4"])
111+
assert.Equal(t, "12345", r.Req.Context().Value(CtxFFRequestIDKey{}).(string))
112+
assert.Equal(t, "custom-value", r.Req.Context().Value(CtxHeadersKey{}).(http.Header).Get("X-Custom-Header"))
111113
return map[string]interface{}{"output1": "value2"}, nil
112114
},
113115
}}, "", nil)
114116
defer done()
117+
SetRequestIDHeader("x-unittest-req-id") // tests custom req header
118+
defer func() {
119+
SetRequestIDHeader(DefaultRequestIDHeader) // reverts this for other tests
120+
}()
115121

116122
b, _ := json.Marshal(map[string]interface{}{"input1": "value1"})
117-
res, err := http.Post(fmt.Sprintf("http://%s/test/stuff?param1=thing&param2&param3=false&param4=x&param4=y", s.Addr()), "application/json", bytes.NewReader(b))
123+
124+
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s/test/stuff?param1=thing&param2&param3=false&param4=x&param4=y", s.Addr()), bytes.NewReader(b))
125+
require.NoError(t, err)
126+
req.Header.Set("Content-Type", "application/json")
127+
req.Header.Set("X-Custom-Header", "custom-value") // tests custom header
128+
req.Header.Set("x-unittest-req-id", "12345") // tests custom req header
129+
130+
res, err := http.DefaultClient.Do(req)
118131
assert.NoError(t, err)
119132
assert.Equal(t, 201, res.StatusCode)
120133
var resJSON map[string]interface{}
@@ -134,13 +147,19 @@ func TestRouteServePOST201WithParamsLargeNumber(t *testing.T) {
134147
JSONOutputCodes: []int{201},
135148
JSONHandler: func(r *APIRequest) (output interface{}, err error) {
136149
assert.Equal(t, r.Input, map[string]interface{}{"largeNumberParam": json.Number("10000000000000000000000000001")})
150+
assert.Equal(t, "12345", r.Req.Context().Value(CtxFFRequestIDKey{}).(string))
137151
// Echo the input back as the response
138152
return r.Input, nil
139153
},
140154
}}, "", nil)
141155
defer done()
142156

143-
res, err := http.Post(fmt.Sprintf("http://%s/test/stuff", s.Addr()), "application/json", bytes.NewReader([]byte(largeParamLiteral)))
157+
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s/test/stuff", s.Addr()), bytes.NewReader([]byte(largeParamLiteral)))
158+
require.NoError(t, err)
159+
req.Header.Set("Content-Type", "application/json")
160+
req.Header.Set(DefaultRequestIDHeader, "12345") // tests client setting req header
161+
162+
res, err := http.DefaultClient.Do(req)
144163
assert.NoError(t, err)
145164
assert.Equal(t, 201, res.StatusCode)
146165
var resJSON map[string]interface{}

pkg/ffresty/ffresty.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ func NewWithConfig(ctx context.Context, ffrestyConfig Config) (client *resty.Cli
305305
// If an X-FireFlyRequestID was set on the context, pass that header on this request too
306306
ffRequestID := rCtx.Value(ffapi.CtxFFRequestIDKey{})
307307
if ffRequestID != nil {
308-
req.Header.Set(ffapi.FFRequestIDHeader, ffRequestID.(string))
308+
req.Header.Set(ffapi.RequestIDHeader(), ffRequestID.(string))
309309
}
310310

311311
if ffrestyConfig.OnBeforeRequest != nil {

pkg/ffresty/ffresty_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ func TestPassthroughHeaders(t *testing.T) {
558558

559559
httpmock.RegisterResponder("GET", "http://localhost:12345/test",
560560
func(req *http.Request) (*http.Response, error) {
561-
assert.Equal(t, "customReqID", req.Header.Get(ffapi.FFRequestIDHeader))
561+
assert.Equal(t, "customReqID", req.Header.Get(ffapi.RequestIDHeader()))
562562
assert.Equal(t, "headervalue", req.Header.Get("someheader"))
563563
assert.Equal(t, "custom value", req.Header.Get("X-Custom-Header"))
564564
assert.Equal(t, "Basic dXNlcjpwYXNz", req.Header.Get("Authorization"))

0 commit comments

Comments
 (0)