Skip to content
This repository has been archived by the owner on Oct 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #34 from bancodobrasil/develop
Browse files Browse the repository at this point in the history
Version: v0.3.0
  • Loading branch information
ralphg6 authored Mar 30, 2022
2 parents 41b7c3b + 1bf7a13 commit f69f5ed
Show file tree
Hide file tree
Showing 32 changed files with 2,841 additions and 237 deletions.
3 changes: 3 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FEATWS_RULLER_PORT=8000
FEATWS_RULLER_RESOURCE_LOADER_URL=https://myrepo.com/{knowledgeBase}/{version}/rules.grl
FEATWS_RULLER_RESOURCE_LOADER_HEADERS=PRIVATE-TOKEN:123123d12d12d1
43 changes: 43 additions & 0 deletions .github/workflows/cd-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: CI/CD to Heroku

on:
push:
branches: [ develop ]

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

jobs:

deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.LATEST_GO_VERSION }}

- name: "Fetch dependencies"
run: go mod download

- name: Build
run: go build -v ./...

- run: |
REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}')
echo "REPOSITORY_NAME=$REPOSITORY_NAME" >> $GITHUB_ENV
shell: bash
- name: Deploy to Heroku
uses: akhileshns/heroku-deploy@v3.12.12 # This is the action
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}}
heroku_app_name: ${{env.REPOSITORY_NAME}} #Must be unique in Heroku
heroku_email: ${{secrets.HEROKU_EMAIL}}
usedocker: true

#- name: Test
# run: go test -v ./...
6 changes: 3 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Go
on:
push:
pull_request:
branches: [ main ]
branches: [ develop, master ]

env:
LATEST_GO_VERSION: "1.17"
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 ./...
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ featws-ruller
*.grl
config.yaml
example.json
*.exe
*.exe
*.env
*.out
17 changes: 8 additions & 9 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
"version": "0.2.0",
"configurations": [
{
"name": "Launch file",
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${file}"
"mode": "auto",
"program": "${workspaceFolder}"
},
/*{
"name": "Launch Package",
{
"name": "Launch file",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"args": ["./config.yaml", "../featws-compiler/__tests__/cases/0039 - nested_4_feature_with_condition/rules.grl"]
}*/
"mode": "debug",
"program": "${file}"
}
]
}
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ FROM alpine:3.15

COPY --from=BUILD /app/ruller /bin/

CMD [ "ruller", "/app/config.yml" ]
CMD [ "ruller" ]



6 changes: 0 additions & 6 deletions config.yaml-sample

This file was deleted.

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

import (
"fmt"
"net/http"
"os"
"strings"

"github.com/spf13/viper"
)

//Config ...
type Config struct {
ResourceLoaderType string `mapstructure:"FEATWS_RULLER_RESOURCE_LOADER_TYPE"`
ResourceLoaderURL string `mapstructure:"FEATWS_RULLER_RESOURCE_LOADER_URL"`
ResourceLoaderHeaders http.Header
ResourceLoaderHeadersStr string `mapstructure:"FEATWS_RULLER_RESOURCE_LOADER_HEADERS"`

Port string `mapstructure:"PORT"`
DefaultRules string `mapstructure:"FEATWS_RULLER_DEFAULT_RULES"`
DisableSSLVerify bool `mapstructure:"FEATWS_DISABLE_SSL_VERIFY"`

ResolverBridgeURL string `mapstructure:"FEATWS_RULLER_RESOLVER_BRIDGE_URL"`
ResolverBridgeHeaders http.Header
ResolverBridgeHeadersStr string `mapstructure:"FEATWS_RULLER_RESOLVER_BRIDGE_HEADERS"`
}

var config = &Config{}

var loaded = false

//LoadConfig ...
func LoadConfig() (err error) {
viper.AddConfigPath("./")
viper.SetConfigFile(".env")
viper.SetConfigType("env")

viper.AutomaticEnv()

viper.SetDefault("FEATWS_RULLER_RESOURCE_LOADER_TYPE", "http")
viper.SetDefault("FEATWS_RULLER_RESOURCE_LOADER_URL", "")
viper.SetDefault("FEATWS_RULLER_RESOURCE_LOADER_HEADERS", "")
viper.SetDefault("FEATWS_RULLER_RESOLVER_BRIDGE_URL", "")
viper.SetDefault("FEATWS_RULLER_RESOLVER_BRIDGE_HEADERS", "")
viper.SetDefault("FEATWS_RULLER_DEFAULT_RULES", "")
viper.SetDefault("PORT", "8000")
viper.SetDefault("FEATWS_DISABLE_SSL_VERIFY", false)

err = viper.ReadInConfig()
if err != nil {
if err2, ok := err.(*os.PathError); !ok {
err = err2
return
}
}

err = viper.Unmarshal(config)

config.ResourceLoaderHeaders = make(http.Header)
resourceLoaderHeaders := strings.Split(config.ResourceLoaderHeadersStr, ",")
for _, value := range resourceLoaderHeaders {
entries := strings.Split(value, ":")
if len(entries) == 2 {
config.ResourceLoaderHeaders.Set(entries[0], entries[1])
}
}

config.ResolverBridgeHeaders = make(http.Header)
resolverBridgeHeaders := strings.Split(config.ResolverBridgeHeadersStr, ",")
for _, value := range resolverBridgeHeaders {
entries := strings.Split(value, ":")
if len(entries) == 2 {
config.ResolverBridgeHeaders.Set(entries[0], entries[1])
}
}

return
}

//GetConfig ...
func GetConfig() *Config {
if !loaded {
err := LoadConfig()
loaded = true
if err != nil {
panic(fmt.Sprintf("load config error: %s", err))
}
}
return config
}
15 changes: 15 additions & 0 deletions controllers/home.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"
)

//HomeHandler ...
func HomeHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.String(http.StatusOK, "FeatWS Works!!!")
}

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

import (
"net/http"
"net/http/httptest"
"net/url"
"testing"

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

func mockGin() (*gin.Context, *httptest.ResponseRecorder) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)

// test request, must instantiate a request first
req := &http.Request{
URL: &url.URL{},
Header: make(http.Header), // if you need to test headers
}
// finally set the request to the gin context
c.Request = req

return c, w
}

func TestHomeHandler(t *testing.T) {
c, r := mockGin()
HomeHandler()(c)
gotStatus := r.Result().Status
expectedStatus := "200 OK"

if gotStatus != expectedStatus {
t.Error("got error on request homeHandler func")
}

gotBody := r.Body.String()
expectedBody := "FeatWS Works!!!"

if gotBody != expectedBody {
t.Error("got error on request homeHandler func")
}

}
96 changes: 96 additions & 0 deletions controllers/v1/evalHandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package v1

import (
"encoding/json"
"fmt"
"net/http"
"sync"

"github.com/bancodobrasil/featws-ruller/services"
"github.com/bancodobrasil/featws-ruller/types"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)

// DefaultKnowledgeBaseName its default name of Knowledge Base
const DefaultKnowledgeBaseName = "default"

// DefaultKnowledgeBaseVersion its default version of Knowledge Base
const DefaultKnowledgeBaseVersion = "latest"

//LoadMutex ...
var loadMutex sync.Mutex

//EvalHandler ...
func EvalHandler() gin.HandlerFunc {
return func(c *gin.Context) {
knowledgeBaseName := c.Param("knowledgeBase")
if knowledgeBaseName == "" {
knowledgeBaseName = DefaultKnowledgeBaseName
}

version := c.Param("version")
if version == "" {
version = DefaultKnowledgeBaseVersion
}

log.Printf("Eval with %s %s\n", knowledgeBaseName, version)

loadMutex.Lock()

knowledgeBase := services.EvalService.GetKnowledgeLibrary().GetKnowledgeBase(knowledgeBaseName, version)

if !knowledgeBase.ContainsRuleEntry("DefaultValues") {

err := services.EvalService.LoadRemoteGRL(knowledgeBaseName, version)
if err != nil {
log.Errorf("Erro on load: %v", err)
c.String(http.StatusInternalServerError, "Error on load knowledgeBase and/or version")
// w.WriteHeader(http.StatusservicesUnavailable)
// encoder := json.NewEncoder(w)
// encoder.Encode(err)
loadMutex.Unlock()
return
}

knowledgeBase = services.EvalService.GetKnowledgeLibrary().GetKnowledgeBase(knowledgeBaseName, version)

if !knowledgeBase.ContainsRuleEntry("DefaultValues") {
c.Status(http.StatusNotFound)
fmt.Fprint(c.Writer, "KnowledgeBase or version not founded!")
loadMutex.Unlock()
return
}
}

loadMutex.Unlock()

decoder := json.NewDecoder(c.Request.Body)
var t map[string]interface{}
err := decoder.Decode(&t)
if err != nil {
log.Errorf("Erro on json decode: %v", err)
c.Status(http.StatusInternalServerError)
fmt.Fprint(c.Writer, "Error on json decode")
return
}
log.Println(t)

ctx := types.NewContextFromMap(t)

result, err := services.EvalService.Eval(ctx, knowledgeBase)
if err != nil {
log.Errorf("Error on eval: %v", err)
c.Status(http.StatusInternalServerError)
fmt.Fprint(c.Writer, "Error on eval")
return
}

// log.Print("Context:\n\t", ctx.GetEntries(), "\n\n")
// log.Print("Features:\n\t", result.GetFeatures(), "\n\n")

c.JSON(http.StatusOK, result.GetFeatures())
//fmt.Fprintf(w, "%v", result)
}

}
Loading

0 comments on commit f69f5ed

Please sign in to comment.