From f14864f8b56eb7a42d330946c520bbbada5edcb5 Mon Sep 17 00:00:00 2001 From: Wojciech Regulski <48433067+wregulski@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:34:56 +0100 Subject: [PATCH] feat(BUX-500): add X-DeploymentID header Arc client option (#84) * feat: add arc client headers * fix: fix the name of xdeployment-id header * feat: add required header for to all examples * docs: update readme --- README.md | 5 +++- broadcast/broadcast-client/arc_client_opts.go | 26 +++++++++++++++++++ broadcast/broadcast-client/client_builder.go | 9 +++++-- broadcast/internal/arc/arc_client.go | 8 +++++- broadcast/internal/arc/arc_policy_quote.go | 4 +++ broadcast/internal/arc/arc_query_tx.go | 4 +++ broadcast/internal/arc/arc_submit_tx.go | 12 ++++++--- broadcast/internal/arc/arc_submit_tx_test.go | 2 +- examples/get_fee_quote/get_fee_quote.go | 2 +- examples/get_policy_quote/get_policy_quote.go | 2 +- examples/query_transaction/query_tx.go | 2 +- .../submit_batch_txs.go | 2 +- examples/submit_transaction/submit_tx.go | 2 +- 13 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 broadcast/broadcast-client/arc_client_opts.go diff --git a/README.md b/README.md index 9a50d3e..a15ec68 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,13 @@ custom features to work with multiple nodes and retry logic. } client := broadcast_client.Builder(). - WithArc(cfg). + WithArc(cfg, &logger, broadcast_client.WithXDeploymentID("broadcast-client-example")). Build() ``` +As you can see, you can inject the logger and set the deployment id for the client. +DeploymentID is a header that will be added to each request to the node - it is used for monitoring purposes. + ### Use the method exposed by the interface ```go diff --git a/broadcast/broadcast-client/arc_client_opts.go b/broadcast/broadcast-client/arc_client_opts.go new file mode 100644 index 0000000..a01e4b8 --- /dev/null +++ b/broadcast/broadcast-client/arc_client_opts.go @@ -0,0 +1,26 @@ +package broadcast_client + +// ArcClientOptFunc defines an optional arguments that can be passed to the SubmitTransaction method. +type ArcClientOptFunc func(o *ArcClientOpts) + +type ArcClientOpts struct { + // XDeploymentID is the deployment id (id of instance using Arc API) that will be sent in the request header. + XDeploymentID string +} + +// GetApiUrl returns the API url. +func (c *ArcClientOpts) GetArcClientHeaders() map[string]string { + headers := make(map[string]string) + if c.XDeploymentID != "" { + headers["XDeployment-ID"] = c.XDeploymentID + } + + return headers +} + +// WithXDeploymentID is an option that allows you to set the deployment id (id of instance using Arc API) that will be sent in the request header. +func WithXDeploymentID(deploymentID string) ArcClientOptFunc { + return func(o *ArcClientOpts) { + o.XDeploymentID = deploymentID + } +} diff --git a/broadcast/broadcast-client/client_builder.go b/broadcast/broadcast-client/client_builder.go index 0782708..44088a1 100644 --- a/broadcast/broadcast-client/client_builder.go +++ b/broadcast/broadcast-client/client_builder.go @@ -26,9 +26,14 @@ func (cb *builder) WithHttpClient(client httpclient.HTTPInterface) *builder { // WithArc sets up the connection of the broadcast client to the Arc service using the provided ArcClientConfig. // This method can be called multiple times with different ArcClientConfigurations to establish connections to multiple Arc instances. -func (cb *builder) WithArc(config ArcClientConfig, log *zerolog.Logger) *builder { +func (cb *builder) WithArc(config ArcClientConfig, log *zerolog.Logger, opts ...ArcClientOptFunc) *builder { + options := &ArcClientOpts{} + for _, opt := range opts { + opt(options) + } + cb.factories = append(cb.factories, func() broadcast_api.Client { - return arc.NewArcClient(&config, cb.client, log) + return arc.NewArcClient(&config, cb.client, log, options) }) return cb } diff --git a/broadcast/internal/arc/arc_client.go b/broadcast/internal/arc/arc_client.go index 41dc51a..7498743 100644 --- a/broadcast/internal/arc/arc_client.go +++ b/broadcast/internal/arc/arc_client.go @@ -13,6 +13,10 @@ const ( arcSubmitBatchTxsRoute = "/v1/txs" ) +type ClientOptions interface { + GetArcClientHeaders() map[string]string +} + type Config interface { GetApiUrl() string GetToken() string @@ -21,16 +25,18 @@ type Config interface { type ArcClient struct { apiURL string token string + headers map[string]string HTTPClient httpclient.HTTPInterface Logger *zerolog.Logger } -func NewArcClient(config Config, client httpclient.HTTPInterface, log *zerolog.Logger) broadcast_api.Client { +func NewArcClient(config Config, client httpclient.HTTPInterface, log *zerolog.Logger, opts ClientOptions) broadcast_api.Client { if client == nil { client = httpclient.NewHttpClient() } arcClient := &ArcClient{ + headers: opts.GetArcClientHeaders(), apiURL: config.GetApiUrl(), token: config.GetToken(), HTTPClient: client, diff --git a/broadcast/internal/arc/arc_policy_quote.go b/broadcast/internal/arc/arc_policy_quote.go index c73652e..c41c077 100644 --- a/broadcast/internal/arc/arc_policy_quote.go +++ b/broadcast/internal/arc/arc_policy_quote.go @@ -45,6 +45,10 @@ func getPolicyQuote(ctx context.Context, arc *ArcClient) (*broadcast.PolicyQuote nil, ) + if arc.headers != nil { + pld.Headers = arc.headers + } + return httpclient.RequestModel( ctx, arc.HTTPClient.DoRequest, diff --git a/broadcast/internal/arc/arc_query_tx.go b/broadcast/internal/arc/arc_query_tx.go index 8c435b8..761dee1 100644 --- a/broadcast/internal/arc/arc_query_tx.go +++ b/broadcast/internal/arc/arc_query_tx.go @@ -43,6 +43,10 @@ func queryTransaction(ctx context.Context, arc *ArcClient, txHash string) (*broa nil, ) + if arc.headers != nil { + pld.Headers = arc.headers + } + parseResponse := func(resp *http.Response) (*broadcast.QueryTxResponse, error) { return decodeQueryResponseBody(resp, arc) } diff --git a/broadcast/internal/arc/arc_submit_tx.go b/broadcast/internal/arc/arc_submit_tx.go index 6abc4f5..bda1bae 100644 --- a/broadcast/internal/arc/arc_submit_tx.go +++ b/broadcast/internal/arc/arc_submit_tx.go @@ -103,7 +103,7 @@ func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transa arc.token, data, ) - appendSubmitTxHeaders(&pld, opts) + appendSubmitTxHeaders(&pld, opts, arc.headers) return httpclient.RequestModel( ctx, @@ -127,7 +127,7 @@ func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadca arc.token, data, ) - appendSubmitTxHeaders(&pld, opts) + appendSubmitTxHeaders(&pld, opts, arc.headers) return httpclient.RequestModel( ctx, @@ -170,7 +170,7 @@ func createSubmitBatchTxsBody(arc *ArcClient, txs []*broadcast.Transaction, txFo return data, nil } -func appendSubmitTxHeaders(pld *httpclient.HTTPRequest, opts *broadcast.TransactionOpts) { +func appendSubmitTxHeaders(pld *httpclient.HTTPRequest, opts *broadcast.TransactionOpts, clientHeaders map[string]string) { if opts == nil { return } @@ -190,6 +190,12 @@ func appendSubmitTxHeaders(pld *httpclient.HTTPRequest, opts *broadcast.Transact if statusCode, ok := broadcast.MapTxStatusToInt(opts.WaitForStatus); ok { pld.AddHeader("X-WaitForStatus", strconv.Itoa(statusCode)) } + + if len(clientHeaders) > 0 { + for key, value := range clientHeaders { + pld.AddHeader(key, value) + } + } } func decodeSubmitResponseBody(resp *http.Response) (*broadcast.SubmittedTx, error) { diff --git a/broadcast/internal/arc/arc_submit_tx_test.go b/broadcast/internal/arc/arc_submit_tx_test.go index 5294758..986897e 100644 --- a/broadcast/internal/arc/arc_submit_tx_test.go +++ b/broadcast/internal/arc/arc_submit_tx_test.go @@ -93,7 +93,7 @@ func TestSubmitTransaction(t *testing.T) { "someToken", body, ) - appendSubmitTxHeaders(&expectedPayload, nil) + appendSubmitTxHeaders(&expectedPayload, nil, client.headers) mockHttpClient.On("DoRequest", context.Background(), expectedPayload). Return(tc.httpResponse, tc.httpError).Once() diff --git a/examples/get_fee_quote/get_fee_quote.go b/examples/get_fee_quote/get_fee_quote.go index 327c1db..426a261 100644 --- a/examples/get_fee_quote/get_fee_quote.go +++ b/examples/get_fee_quote/get_fee_quote.go @@ -20,7 +20,7 @@ func main() { } client := broadcast_client.Builder(). - WithArc(gorillaCfg, &logger). + WithArc(gorillaCfg, &logger, broadcast_client.WithXDeploymentID("broadcast-client-example")). Build() feeQuotes, err := client.GetFeeQuote(context.Background()) diff --git a/examples/get_policy_quote/get_policy_quote.go b/examples/get_policy_quote/get_policy_quote.go index a7bacb3..dda8761 100644 --- a/examples/get_policy_quote/get_policy_quote.go +++ b/examples/get_policy_quote/get_policy_quote.go @@ -20,7 +20,7 @@ func main() { } client := broadcast_client.Builder(). - WithArc(gorillaCfg, &logger). + WithArc(gorillaCfg, &logger, broadcast_client.WithXDeploymentID("broadcast-client-example")). Build() policyQuotes, err := client.GetPolicyQuote(context.Background()) diff --git a/examples/query_transaction/query_tx.go b/examples/query_transaction/query_tx.go index 54bcacc..3884110 100644 --- a/examples/query_transaction/query_tx.go +++ b/examples/query_transaction/query_tx.go @@ -23,7 +23,7 @@ func main() { } client := broadcast_client.Builder(). - WithArc(cfg, &logger). + WithArc(cfg, &logger, broadcast_client.WithXDeploymentID("broadcast-client-example")). Build() result, err := client.QueryTransaction(context.Background(), txID) diff --git a/examples/submit_batch_transactions/submit_batch_txs.go b/examples/submit_batch_transactions/submit_batch_txs.go index fbd807e..024a300 100644 --- a/examples/submit_batch_transactions/submit_batch_txs.go +++ b/examples/submit_batch_transactions/submit_batch_txs.go @@ -29,7 +29,7 @@ func main() { } client := broadcast_client.Builder(). - WithArc(cfg, &logger). + WithArc(cfg, &logger, broadcast_client.WithXDeploymentID("broadcast-client-example")). Build() result, err := client.SubmitBatchTransactions(context.Background(), txs, broadcast.WithRawFormat()) diff --git a/examples/submit_transaction/submit_tx.go b/examples/submit_transaction/submit_tx.go index a3540de..c0a08d9 100644 --- a/examples/submit_transaction/submit_tx.go +++ b/examples/submit_transaction/submit_tx.go @@ -23,7 +23,7 @@ func main() { } client := broadcast_client.Builder(). - WithArc(cfg, &logger). + WithArc(cfg, &logger, broadcast_client.WithXDeploymentID("broadcast-client-example")). Build() result, err := client.SubmitTransaction(context.Background(), &tx, broadcast.WithRawFormat())