Skip to content

Commit

Permalink
Merge pull request #16 from bancodobrasil/develop
Browse files Browse the repository at this point in the history
promote changes to master branch
  • Loading branch information
matheusromano authored Aug 17, 2022
2 parents 4af4e6f + 22d4def commit b00e653
Show file tree
Hide file tree
Showing 20 changed files with 1,001 additions and 105 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Go
on:
push:
pull_request:
branches: [ main ]
branches: [ develop, master ]

env:
LATEST_GO_VERSION: "1.17"
LATEST_GO_VERSION: "1.18"
GO111MODULE: "on"

jobs:
Expand All @@ -16,7 +16,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go_version: ['1.16', '1.17']
go_version: ['1.18']
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -48,5 +48,5 @@ jobs:
- name: Build
run: go build -v ./...

#- name: Test
# run: go test -v ./...
- name: Test
run: go test -v ./...
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*.dll
*.so
*.dylib
*.env

# Test binary, built with `go test -c`
*.test
Expand Down
85 changes: 70 additions & 15 deletions adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,97 @@ package adapter

import (
"os"
"path/filepath"
"strings"

"github.com/bancodobrasil/featws-resolver-adapter-go/config"
// Specificate the docs package
_ "github.com/bancodobrasil/featws-resolver-adapter-go/docs"
"github.com/bancodobrasil/featws-resolver-adapter-go/routes"
"github.com/bancodobrasil/featws-resolver-adapter-go/services"
ginMonitor "github.com/bancodobrasil/gin-monitor"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
ginlogrus "github.com/toorop/gin-logrus"
)

func setupLog() {
log.SetFormatter(&log.TextFormatter{FullTimestamp: true})
func init() {
ex, err := os.Executable()
if err != nil {
log.Fatal(err)
}
exePath := filepath.Dir(ex)
viper.AddConfigPath(exePath)
viper.SetConfigType("env")
viper.SetConfigName(".env")

log.SetOutput(os.Stdout)
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
viper.AutomaticEnv()
viper.SetDefault("EXTERNAL_HOST", "localhost:7000")
viper.SetDefault("RESOLVER_LOG_JSON", false)
viper.SetDefault("RESOLVER_LOG_LEVEL", "error")
viper.SetDefault("RESOLVER_SERVICE_NAME", "resolver-adapter-go")
if err := viper.ReadInConfig(); err == nil {
log.Infof("Using config file: %s", viper.ConfigFileUsed())
}
}

log.SetLevel(log.DebugLevel)
// Config ...
type Config struct {
Port string
}

// Config contains all settings of module
var Config = config.Config{}
// @title FeatWS Resolver Adapter

// @version 1.0

// @description Resolver Adapter Project is a library to provide resolvers to other projects

// @termsOfService http://swagger.io/terms/

// @contact.name API Support

// @contact.url http://www.swagger.io/support

// Run start the resolver server with resolverFunc
func Run(resolverFunc services.ResolverFunc) {
// @contact.email [email protected]

setupLog()
// @license.name Apache 2.0

err := config.LoadConfig(&Config)
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost:7000

// @BasePath /api/v1

// @x-extension-openapi {"example": "value on a json format"}

// Run ...
func Run(resolverFunc services.ResolverFunc, config Config) error {

InitLogger()

monitor, err := ginMonitor.New("v0.0.1-rc8", ginMonitor.DefaultErrorMessageKey, ginMonitor.DefaultBuckets)
if err != nil {
log.Fatalf("Não foi possível carregar as configurações: %s\n", err)
panic(err)
}

gin.DefaultWriter = log.StandardLogger().WriterLevel(log.DebugLevel)
gin.DefaultErrorWriter = log.StandardLogger().WriterLevel(log.ErrorLevel)

services.SetupResolver(resolverFunc)

router := gin.New()
// Register ginLogrus log format to gin
router.Use(ginlogrus.Logger(log.StandardLogger()), gin.Recovery())

// Register gin-monitor middleware
router.Use(monitor.Prometheus())
// Register metrics endpoint
router.GET("/metrics", gin.WrapH(promhttp.Handler()))
routes.SetupRoutes(router)
routes.APIRoutes(router)

port := Config.Port

router.Run(":" + port)
return router.Run(":" + config.Port)
}
187 changes: 187 additions & 0 deletions adapter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package adapter

import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"sort"
"testing"
"time"

"github.com/bancodobrasil/featws-resolver-adapter-go/types"
"github.com/stretchr/testify/assert"
)

const (
labelContextTest string = "adapter_context_test"
labelLoadTest string = "adapter_load_test"
labelLoadSystemError string = "adapter_load_system_error"
msgErrorContextMissing string = "Context missing"
msgErrorLoadSystemError string = "This resolver doesn't work for this loads %v"
msgEchoContext string = "#Echo# %s"
messageText string = "Lorem ipsum dolor sit amet"
urlResolver string = "http://localhost:7000/api/v1/resolve/"
contentType string = "application/text"
)

func TestMain(m *testing.M) {
setup()
code := m.Run()
shutdown()
os.Exit(code)
}

func setup() {
go func() {
Run(resolverTest, Config{
Port: "7000",
})
}()
// have to wait for the goroutine to start and run the server
// otherwise the main thread will complete
time.Sleep(5 * time.Millisecond)
}

func shutdown() {}

func resolverTest(ctx context.Context, resolveInput types.ResolveInput, resolveOutput *types.ResolveOutput) {
sort.Strings(resolveInput.Load)
if contains(resolveInput.Load, labelLoadTest) {
contextValue, ok := resolveInput.Context[labelContextTest]
if !ok {
resolveOutput.Errors[labelLoadTest] = msgErrorContextMissing
} else {
resolveOutput.Context[labelLoadTest] = fmt.Sprintf(msgEchoContext, contextValue)
}

} else {
resolveOutput.Errors[labelLoadSystemError] = fmt.Sprintf(msgErrorLoadSystemError, resolveInput.Load)
}
}

func contains(s []string, searchterm string) bool {
i := sort.SearchStrings(s, searchterm)
return i < len(s) && s[i] == searchterm
}

func TestAdapterSuccess(t *testing.T) {
resolveOutput := testRequest(t, labelContextTest, messageText, labelLoadTest)
assert.Equal(t, resolveOutput.Context[labelLoadTest], fmt.Sprintf(msgEchoContext, messageText))
}

func TestAdapterLabelInvalid(t *testing.T) {
resolveOutput := testRequest(t, labelContextTest, messageText, "label_invalid")
assert.Equal(t, resolveOutput.Errors[labelLoadSystemError], fmt.Sprintf(msgErrorLoadSystemError, []string{"label_invalid"}))
}

func TestAdapterContextInvalid(t *testing.T) {
resolveOutput := testRequest(t, "context_invalid", messageText, labelLoadTest)
assert.Equal(t, resolveOutput.Errors[labelLoadTest], msgErrorContextMissing)
}

func testRequest(t *testing.T, context string, data string, load string) *types.ResolveOutput {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}

client := &http.Client{Transport: tr}

body, _ := json.Marshal(types.ResolveInput{
Context: map[string]interface{}{
context: data,
},
Load: []string{load},
})

postBody := bytes.NewBuffer((body))

defer client.CloseIdleConnections()

resp, err := client.Post(urlResolver, contentType, postBody)

assert.NoError(t, err)
assert.Equal(t, "200 OK", resp.Status)

defer resp.Body.Close()

resBody, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)

resolveOutput := types.ResolveOutput{
Context: make(map[string]interface{}),
Errors: make(map[string]interface{}),
}
json.Unmarshal(resBody, &resolveOutput)

return &resolveOutput

}

// go test -bench . -run="none" -v -count=5

func BenchmarkAdapterResolver(b *testing.B) {
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
testRequestBench(labelContextTest, messageText, labelLoadTest)
}
})
}

func testRequestBench(context string, data string, load string) {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}

client := &http.Client{Transport: tr}

body, _ := json.Marshal(types.ResolveInput{
Context: map[string]interface{}{
context: data,
},
Load: []string{load},
})

postBody := bytes.NewBuffer((body))

defer client.CloseIdleConnections()

resp, err := client.Post(urlResolver, contentType, postBody)
if err != nil {
log.Fatal(err)
}

if resp.StatusCode != 200 {
log.Fatal("Http response status not equals 200")
}

defer resp.Body.Close()

resBody, err := ioutil.ReadAll(resp.Body)

if err != nil {
log.Fatal(err)
}

resolveOutput := types.ResolveOutput{
Context: make(map[string]interface{}),
Errors: make(map[string]interface{}),
}

err = json.Unmarshal(resBody, &resolveOutput)

if err != nil {
log.Fatal(err)
}

}
35 changes: 0 additions & 35 deletions config/config.go

This file was deleted.

15 changes: 15 additions & 0 deletions controllers/healthLiveHandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package controllers

import (
"net/http"

"github.com/gin-gonic/gin"
)

// HealthLiveHandler ...
func HealthLiveHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.String(http.StatusOK, "Application is live!!!")
}

}
Loading

0 comments on commit b00e653

Please sign in to comment.