Skip to content

Commit

Permalink
feat(transforms): Add support for specifying http request headers for…
Browse files Browse the repository at this point in the history
… HTTP export

Signed-off-by: Neethu Elizabeth Simon <neethu.elizabeth.simon@intel.com>
  • Loading branch information
NeethuES-intel authored Aug 15, 2023
1 parent 12f0d47 commit 29a8308
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 22 deletions.
13 changes: 13 additions & 0 deletions internal/app/configurable.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package app

import (
"encoding/json"
"fmt"
"strconv"
"strings"
Expand Down Expand Up @@ -80,6 +81,7 @@ const (
BatchByTimeAndCount = "bytimecount"
IsEventData = "iseventdata"
MergeOnSend = "mergeonsend"
HttpRequestHeaders = "httprequestheaders"
)

// Configurable contains the helper functions that return the function pointers for building the configurable function pipeline.
Expand Down Expand Up @@ -344,6 +346,17 @@ func (app *Configurable) HTTPExport(parameters map[string]string) interfaces.App

transform := transforms.NewHTTPSenderWithOptions(options)

// Unmarshal and set httpRequestHeaders
httpRequestHeaders := map[string]string{}
if parameters[HttpRequestHeaders] != "" {
if err := json.Unmarshal([]byte(parameters[HttpRequestHeaders]), &httpRequestHeaders); err != nil {
app.lc.Error("Unable to unmarshal http request headers : %s", err.Error())
return nil
}
}

transform.SetHttpRequestHeaders(httpRequestHeaders)

switch strings.ToLower(method) {
case ExportMethodPost:
return transform.HTTPPost
Expand Down
63 changes: 41 additions & 22 deletions internal/app/configurable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ func TestHTTPExport(t *testing.T) {
testSecretName := "my-secret"
testSecretValueKey := "header"

testHTTPRequestHeaders := `{
"Connection": "keep-alive",
"From": "[user@example.com](mailto:user@example.com)"
}`

testBadHTTPRequestHeaders := `{
"Connection": "keep-alive",
"From":
`

tests := []struct {
Name string
Method string
Expand All @@ -180,30 +190,35 @@ func TestHTTPExport(t *testing.T) {
HeaderName *string
SecretName *string
SecretValueKey *string
HTTPRequestHeaders *string
ExpectValid bool
}{
{"Valid Post - ony required params", ExportMethodPost, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, true},
{"Valid Post - w/o secrets", http.MethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, nil, nil, true},
{"Valid Post - with secrets", ExportMethodPost, &testUrl, &testMimeType, nil, nil, nil, &testHeaderName, &testSecretName, &testSecretValueKey, true},
{"Valid Post - with all params", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, &testContinueOnSendError, &testReturnInputData, &testHeaderName, &testSecretName, &testSecretValueKey, true},
{"Invalid Post - no url", ExportMethodPost, nil, &testMimeType, nil, nil, nil, nil, nil, nil, false},
{"Invalid Post - no mimeType", ExportMethodPost, &testUrl, nil, nil, nil, nil, nil, nil, nil, false},
{"Invalid Post - bad persistOnError", ExportMethodPost, &testUrl, &testMimeType, &testBadPersistOnError, nil, nil, nil, nil, nil, false},
{"Invalid Post - missing headerName", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, &testSecretName, &testSecretValueKey, false},
{"Invalid Post - missing secretName", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, nil, &testSecretValueKey, false},
{"Invalid Post - missing secretValueKey", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, &testSecretName, nil, false},
{"Valid Put - ony required params", ExportMethodPut, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, true},
{"Valid Put - w/o secrets", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, nil, nil, true},
{"Valid Put - with secrets", http.MethodPut, &testUrl, &testMimeType, nil, nil, nil, &testHeaderName, &testSecretName, &testSecretValueKey, true},
{"Valid Put - with all params", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, &testSecretName, &testSecretValueKey, true},
{"Invalid Put - no url", ExportMethodPut, nil, &testMimeType, nil, nil, nil, nil, nil, nil, false},
{"Invalid Put - no mimeType", ExportMethodPut, &testUrl, nil, nil, nil, nil, nil, nil, nil, false},
{"Invalid Put - bad persistOnError", ExportMethodPut, &testUrl, &testMimeType, &testBadPersistOnError, nil, nil, nil, nil, nil, false},
{"Invalid Put - bad continueOnSendError", ExportMethodPut, &testUrl, &testMimeType, nil, &testBadContinueOnSendError, nil, nil, nil, nil, false},
{"Invalid Put - bad returnInputData", ExportMethodPut, &testUrl, &testMimeType, nil, nil, &testBadReturnInputData, nil, nil, nil, false},
{"Invalid Put - missing headerName", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, &testSecretName, &testSecretValueKey, false},
{"Invalid Put - missing secretName", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, nil, &testSecretValueKey, false},
{"Invalid Put - missing secretValueKey", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, &testSecretName, nil, false},
{"Valid Post - ony required params", ExportMethodPost, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, nil, true},
{"Valid Post - w/o secrets", http.MethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, nil, nil, nil, true},
{"Valid Post - with secrets", ExportMethodPost, &testUrl, &testMimeType, nil, nil, nil, &testHeaderName, &testSecretName, &testSecretValueKey, nil, true},
{"Valid Post - with http requet headers", ExportMethodPost, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, &testHTTPRequestHeaders, true},
{"Valid Post - with all params", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, &testContinueOnSendError, &testReturnInputData, &testHeaderName, &testSecretName, &testSecretValueKey, &testHTTPRequestHeaders, true},
{"Invalid Post - no url", ExportMethodPost, nil, &testMimeType, nil, nil, nil, nil, nil, nil, nil, false},
{"Invalid Post - no mimeType", ExportMethodPost, &testUrl, nil, nil, nil, nil, nil, nil, nil, nil, false},
{"Invalid Post - bad persistOnError", ExportMethodPost, &testUrl, &testMimeType, &testBadPersistOnError, nil, nil, nil, nil, nil, nil, false},
{"Invalid Post - missing headerName", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, &testSecretName, &testSecretValueKey, nil, false},
{"Invalid Post - missing secretName", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, nil, &testSecretValueKey, nil, false},
{"Invalid Post - missing secretValueKey", ExportMethodPost, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, &testSecretName, nil, nil, false},
{"Invalid Post - unmarshal error for http requet headers", ExportMethodPost, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, &testBadHTTPRequestHeaders, false},
{"Valid Put - ony required params", ExportMethodPut, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, nil, true},
{"Valid Put - w/o secrets", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, nil, nil, nil, true},
{"Valid Put - with secrets", http.MethodPut, &testUrl, &testMimeType, nil, nil, nil, &testHeaderName, &testSecretName, &testSecretValueKey, nil, true},
{"Valid Put - with http request headers", ExportMethodPut, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, &testHTTPRequestHeaders, true},
{"Valid Put - with all params", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, &testSecretName, &testSecretValueKey, &testHTTPRequestHeaders, true},
{"Invalid Put - no url", ExportMethodPut, nil, &testMimeType, nil, nil, nil, nil, nil, nil, nil, false},
{"Invalid Put - no mimeType", ExportMethodPut, &testUrl, nil, nil, nil, nil, nil, nil, nil, nil, false},
{"Invalid Put - bad persistOnError", ExportMethodPut, &testUrl, &testMimeType, &testBadPersistOnError, nil, nil, nil, nil, nil, nil, false},
{"Invalid Put - bad continueOnSendError", ExportMethodPut, &testUrl, &testMimeType, nil, &testBadContinueOnSendError, nil, nil, nil, nil, nil, false},
{"Invalid Put - bad returnInputData", ExportMethodPut, &testUrl, &testMimeType, nil, nil, &testBadReturnInputData, nil, nil, nil, nil, false},
{"Invalid Put - missing headerName", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, nil, &testSecretName, &testSecretValueKey, nil, false},
{"Invalid Put - missing secretName", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, nil, &testSecretValueKey, nil, false},
{"Invalid Put - missing secretValueKey", ExportMethodPut, &testUrl, &testMimeType, &testPersistOnError, nil, nil, &testHeaderName, &testSecretName, nil, nil, false},
{"Invalid Put - unmarshal error for http requet headers", ExportMethodPut, &testUrl, &testMimeType, nil, nil, nil, nil, nil, nil, &testBadHTTPRequestHeaders, false},
}

for _, test := range tests {
Expand Down Expand Up @@ -243,6 +258,10 @@ func TestHTTPExport(t *testing.T) {
params[SecretValueKey] = *test.SecretValueKey
}

if test.HTTPRequestHeaders != nil {
params[HttpRequestHeaders] = *test.HTTPRequestHeaders
}

transform := configurable.HTTPExport(params)
assert.Equal(t, test.ExpectValid, transform != nil)
})
Expand Down
16 changes: 16 additions & 0 deletions pkg/transforms/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type HTTPSender struct {
secretName string
urlFormatter StringValuesFormatter
httpSizeMetrics gometrics.Histogram
httpRequestHeaders map[string]string
}

// NewHTTPSender creates, initializes and returns a new instance of HTTPSender
Expand Down Expand Up @@ -187,6 +188,12 @@ func (sender *HTTPSender) httpSend(ctx interfaces.AppFunctionContext, data inter

req.Header.Set("Content-Type", sender.mimeType)

// Set all the http request headers
for key, element := range sender.httpRequestHeaders {
req.Header.Set(key, element)

}

ctx.LoggingClient().Debugf("POSTing data to %s in pipeline '%s'", sender.url, ctx.PipelineId())

response, err := client.Do(req)
Expand Down Expand Up @@ -256,6 +263,15 @@ func (sender *HTTPSender) httpSend(ctx interfaces.AppFunctionContext, data inter
return true, responseData
}

// SetHttpRequestHeaders will set all the header parameters for the http request
func (sender *HTTPSender) SetHttpRequestHeaders(httpRequestHeaders map[string]string) {

if httpRequestHeaders != nil {
sender.httpRequestHeaders = httpRequestHeaders
}

}

func (sender *HTTPSender) determineIfUsingSecrets(ctx interfaces.AppFunctionContext) (bool, error) {
// not using secrets if both are empty
if len(sender.secretName) == 0 && len(sender.secretValueKey) == 0 {
Expand Down
40 changes: 40 additions & 0 deletions pkg/transforms/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,43 @@ func TestHTTPPutInvalidParameter(t *testing.T) {
assert.Equal(t, "marshaling input data to JSON failed, "+
"passed in data must be of type []byte, string, or support marshaling to JSON", result.(error).Error())
}

func TestHTTPPostWithHTTPRequestHeaders(t *testing.T) {

expectedHTTPRequestHeaders := map[string]string{
"Connection": "keep-alive",
"From": "[user@example.com](mailto:user@example.com)",
}

// create test server with handler
ts := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {

writer.WriteHeader(http.StatusOK)

for key, expected := range expectedHTTPRequestHeaders {
actual := request.Header.Get(key)
assert.Equal(t, expected, actual)
}

}))
defer ts.Close()

targetUrl, err := url.Parse(ts.URL)
require.NoError(t, err)

sender := NewHTTPSender(
targetUrl.String(),
"",
false)

sender.SetHttpRequestHeaders(expectedHTTPRequestHeaders)

var continuePipeline bool
var errPipeline interface{}

continuePipeline, errPipeline = sender.HTTPPost(ctx, msgStr)

assert.True(t, continuePipeline)
_, ok := errPipeline.(error)
assert.False(t, ok)
}

0 comments on commit 29a8308

Please sign in to comment.