Skip to content

Commit

Permalink
Merge pull request #4 from stone-payments/feature/Migrates-to-datadog
Browse files Browse the repository at this point in the history
Feature/migrates to datadog
  • Loading branch information
anapolima authored Nov 30, 2023
2 parents f5cdcd6 + 11191eb commit cee708f
Show file tree
Hide file tree
Showing 8 changed files with 1,602 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @anapolima @andremacdowell @charllysonsouza @GilbertoVGL @gmarcial @lorytins @LuanSena
* @anapolima @charllysonsouza @edmunhoz @giorgio-larnaut @lorytins @mauricio-pagarme
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [3.0.0](https://github.com/stone-payments/merchant-go-stone-openbank/compare/v2.0.0...v3.0.0) (2023-11-27)


### Features

* Migrates from newrelic to datadog ([77ec1a0](https://github.com/stone-payments/merchant-go-stone-openbank/commit/77ec1a07a69e09a02c94d457397ac9b7e233f9ba))

## [2.0.0](https://github.com/stone-payments/merchant-go-stone-openbank/compare/v1.2.0...v2.0.0) (2023-11-27)


### Features

* Instrument newrelic agent on client ([84f5e5b](https://github.com/stone-payments/merchant-go-stone-openbank/commit/84f5e5b97c706b07c7cba26f329b539e41423ec9))
* **pix:** add create entry and refact services ([#46](https://github.com/stone-payments/merchant-go-stone-openbank/issues/46)) ([6a63a16](https://github.com/stone-payments/merchant-go-stone-openbank/commit/6a63a16ed86c43a92e25417413bad3c298ef46ce))
* Updates client to accept other error response types ([b4f47cc](https://github.com/stone-payments/merchant-go-stone-openbank/commit/b4f47cc1b2f8baa23c0029497f7cbedf03e72b4d))


### Bug Fixes

* change jwt payload b64 decoding strategy ([a977c7d](https://github.com/stone-payments/merchant-go-stone-openbank/commit/a977c7db00d93bd49492d790f273ab9892a9c002)), closes [/datatracker.ietf.org/doc/html/rfc7519#section-3](https://github.com/stone-payments//datatracker.ietf.org/doc/html/rfc7519/issues/section-3)
* consent url and path ([#45](https://github.com/stone-payments/merchant-go-stone-openbank/issues/45)) ([8b19427](https://github.com/stone-payments/merchant-go-stone-openbank/commit/8b1942754bdd83b62c36ae490dfbd1837a95f53a))
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func main() {
log.Fatal(err)
}

err := client.Authenticate()
err := client.Authenticate(context.Background())
if err != nil {
log.Fatal(err)
}
Expand Down
25 changes: 23 additions & 2 deletions authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,29 @@ import (
"strings"
"time"

"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"

jwt "github.com/golang-jwt/jwt/v4"
"github.com/google/uuid"
"golang.org/x/oauth2"
)

func (c *Client) Authenticate() error {
func (c *Client) Authenticate(sCtx context.Context) error {
ctx, span := c.newSpan(sCtx, "openbank auth", trace.SpanKindClient)
defer c.endSpan(span)

if c.validToken() {
c.setSpanStatus(span, codes.Ok, "authentication succeeded")
return nil
}

claims := c.authClaims()
tokenString, err := c.generateToken(claims)
if err != nil {
c.setSpanStatus(span, codes.Error, "error generating token")
c.spanRecordError(span, err)

return err
}

Expand All @@ -34,22 +44,31 @@ func (c *Client) Authenticate() error {

u, err := c.AccountURL.Parse("/auth/realms/stone_bank/protocol/openid-connect/token")
if err != nil {
c.setSpanStatus(span, codes.Error, "error parsing URL")
c.spanRecordError(span, err)

return err
}

req, err := http.NewRequest("POST", u.String(), strings.NewReader(data.Encode()))
if err != nil {
c.setSpanStatus(span, codes.Error, "error creating request")
c.spanRecordError(span, err)

return err
}
req.Header.Add("user-agent", c.UserAgent)
req.Header.Add("content-type", "application/x-www-form-urlencoded")
req = req.WithContext(ctx)

var token oauth2.Token
_, err = c.Do(req, &token, new(TransferError))
if err != nil {
c.setSpanStatus(span, codes.Error, "error executing request")
c.spanRecordError(span, err)

return err
}
ctx := context.Background()
config := &oauth2.Config{}
ts := config.TokenSource(ctx, &token)

Expand All @@ -58,6 +77,8 @@ func (c *Client) Authenticate() error {
c.client = oauth2.NewClient(ctx, ts)
c.token = token

c.setSpanStatus(span, codes.Ok, "authentication succeeded")

return nil
}

Expand Down
81 changes: 70 additions & 11 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package openbank

import (
"bytes"
"context"
"crypto/rsa"
"encoding/json"
"errors"
Expand All @@ -13,12 +14,14 @@ import (
"strings"
"sync"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"

"github.com/golang-jwt/jwt/v4"
"github.com/newrelic/go-agent/v3/newrelic"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2"

"github.com/stone-payments/merchant-go-stone-openbank/types"
"go.opentelemetry.io/otel/trace"
"golang.org/x/oauth2"
)

const (
Expand Down Expand Up @@ -56,6 +59,8 @@ type Client struct {
UserAgent string

token oauth2.Token

otelTracer trace.Tracer
}

func NewClient(opts ...ClientOpt) (*Client, error) {
Expand Down Expand Up @@ -107,6 +112,12 @@ func WithClientID(key string) ClientOpt {
}
}

func WithTracer(tracer trace.Tracer) ClientOpt {
return func(c *Client) {
c.otelTracer = tracer
}
}

func WithPEMPrivateKey(pk []byte) ClientOpt {
return func(c *Client) {
c.privateKeyData = pk
Expand Down Expand Up @@ -280,7 +291,7 @@ func (c *Client) NewAPIRequest(method, pathStr string, body interface{}) (*http.
return req, nil
}

//AddIdempotencyHeader add in request the header used to realize idempotent operations
// AddIdempotencyHeader add in request the header used to realize idempotent operations
func (c *Client) AddIdempotencyHeader(req *http.Request, idempotencyKey string) error {
trimmedIdempotencyKey := strings.TrimSpace(idempotencyKey)
if trimmedIdempotencyKey != "" {
Expand All @@ -294,22 +305,31 @@ func (c *Client) AddIdempotencyHeader(req *http.Request, idempotencyKey string)
}

func (c *Client) Do(req *http.Request, successResponse, errorResponse interface{}) (*Response, error) {
_, span := c.newSpan(
req.Context(),
"merchant openbank client request",
trace.SpanKindClient,
)
defer c.endSpan(span)

c.addSpanAttribute(span, attribute.String("http.request.path", req.URL.String()))
c.addSpanAttribute(span, attribute.String("http.request.protocol", req.Proto))
c.addSpanAttribute(span, attribute.String("http.request.method", req.Method))

if c.debug {
d, _ := httputil.DumpRequestOut(req, true)
c.log.Infof(">>> REQUEST:\n%s", string(d))
}

txn := newrelic.FromContext(req.Context())
defer newrelic.StartSegment(txn, "merchant openbank client request").End()

s := newrelic.StartExternalSegment(txn, req)
defer s.End()

resp, err := c.client.Do(req)
if err != nil {
c.setSpanStatus(span, codes.Error, "error executing request")
c.spanRecordError(span, err)
return nil, err
}

c.addSpanAttribute(span, attribute.Int("http.response.status_code", resp.StatusCode))

defer func() {
if rerr := resp.Body.Close(); err == nil {
err = rerr
Expand All @@ -320,18 +340,57 @@ func (c *Client) Do(req *http.Request, successResponse, errorResponse interface{
c.log.Infof("<<< RESULT:\n%s", string(dr))
}

s.Response = resp
response := &Response{Response: resp}

err = CheckResponse(resp, errorResponse)
if err != nil {
c.setSpanStatus(span, codes.Error, "client request error")
c.spanRecordError(span, err)

return response, err
}

data, err := io.ReadAll(resp.Body)
if err = parseBody(data, successResponse); err != nil {
c.setSpanStatus(span, codes.Error, "client request error")
c.spanRecordError(span, err)

return response, err
}

c.setSpanStatus(span, codes.Ok, "client request succeeded")

return response, err
}

func (c *Client) newSpan(ctx context.Context, name string, kind trace.SpanKind) (context.Context, trace.Span) {
if c.otelTracer != nil {
return c.otelTracer.Start(ctx, name, trace.WithSpanKind(kind))
}

return ctx, nil
}

func (c *Client) setSpanStatus(span trace.Span, code codes.Code, description string) {
if span != nil {
span.SetStatus(code, description)
}
}

func (c *Client) spanRecordError(span trace.Span, err error) {
if span != nil {
span.RecordError(err)
}
}

func (c *Client) endSpan(span trace.Span) {
if span != nil {
span.End()
}
}

func (c *Client) addSpanAttribute(span trace.Span, attributes ...attribute.KeyValue) {
if span != nil {
span.SetAttributes(attributes...)
}
}
3 changes: 2 additions & 1 deletion example/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -33,7 +34,7 @@ func main() {
log.Fatal(err)
}

if err := client.Authenticate(); err != nil {
if err := client.Authenticate(context.Background()); err != nil {
log.Fatal(err)
}

Expand Down
14 changes: 9 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ module github.com/stone-payments/merchant-go-stone-openbank
go 1.14

require (
github.com/golang-jwt/jwt/v4 v4.0.0
github.com/google/uuid v1.3.0
github.com/newrelic/go-agent/v3 v3.20.2
github.com/sirupsen/logrus v1.4.2
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/uuid v1.4.0
github.com/kr/pretty v0.3.1 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/sirupsen/logrus v1.9.3
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/trace v1.21.0
golang.org/x/oauth2 v0.14.0
google.golang.org/appengine v1.6.8 // indirect
gopkg.in/square/go-jose.v2 v2.6.0
)
Loading

0 comments on commit cee708f

Please sign in to comment.