Skip to content

Instantly share code, notes, and snippets.

@arielsrv
Created November 21, 2022 16:00
Show Gist options
  • Save arielsrv/6f5454832d6dc48fd900e320a504e74f to your computer and use it in GitHub Desktop.
Save arielsrv/6f5454832d6dc48fd900e320a504e74f to your computer and use it in GitHub Desktop.
restfactory
package app
import (
"fmt"
"github.com/go-chassis/go-archaius"
"log"
"regexp"
"time"
"github.com/src/main/app/config/env"
"github.com/src/main/app/infrastructure/database"
"github.com/src/main/app/infrastructure/secrets"
"github.com/src/main/app/clients/gitlab"
"github.com/src/main/app/config"
"github.com/src/main/app/handlers"
"github.com/src/main/app/server"
"github.com/src/main/app/services"
"github.com/arielsrv/golang-toolkit/rest"
_ "github.com/go-sql-driver/mysql"
)
var secretStore = ProvideSecretStore()
var dbClient = ProvideDbClient()
var restClients = RegisterClients()
const DefaultPoolSize = 10
const DefaultPoolTimeout = 200
const DefaultSocketTimeout = 500
func RegisterClients() *RESTClientFactory {
restPoolPattern, _ := regexp.Compile(`rest\.pool\.([-_\w]+)\..+`)
pools := GetNamesInKeys(restPoolPattern)
log.Println(pools)
factory := &RESTPoolFactory{
builders: map[string]*rest.RequestBuilder{},
}
for _, name := range pools {
restPool := &rest.RequestBuilder{
Timeout: time.Millisecond * time.Duration(config.TryInt(fmt.Sprintf("rest.pool.%s.pool.timeout", name), DefaultPoolTimeout)),
ConnectTimeout: time.Millisecond * time.Duration(config.TryInt(fmt.Sprintf("rest.pool.%s.pool.connection-timeout", name), DefaultSocketTimeout)),
CustomPool: &rest.CustomPool{
MaxIdleConnsPerHost: config.TryInt(fmt.Sprintf("rest.pool.%s.pool.size", name), DefaultPoolSize),
},
}
factory.Add(restPool)
factory.Register(name, restPool)
}
restClientPattern, _ := regexp.Compile(`rest\.client\.([-_\w]+)\..+`)
clients := GetNamesInKeys(restClientPattern)
restClientFactory := RESTClientFactory{clients: map[string]*rest.RequestBuilder{}}
for _, name := range clients {
poolName := config.String(fmt.Sprintf("rest.client.%s.pool", name))
pool := factory.GetPool(poolName)
restClientFactory.Register(name, pool)
}
return &restClientFactory
}
type RESTPoolFactory struct {
restPools []rest.RequestBuilder
builders map[string]*rest.RequestBuilder
}
func (r *RESTPoolFactory) Add(rb *rest.RequestBuilder) {
r.restPools = append(r.restPools, *rb)
}
func (r *RESTPoolFactory) Register(name string, rb *rest.RequestBuilder) {
r.builders[name] = rb
}
func (r *RESTPoolFactory) GetPool(name string) *rest.RequestBuilder {
return r.builders[name]
}
type RESTPool struct {
Timeout int
ConnectTimeout int
MaxIdleConnsPerHost int
}
type RESTClient struct {
rest.RequestBuilder
}
type RESTClientFactory struct {
clients map[string]*rest.RequestBuilder
}
func (r *RESTClientFactory) Register(name string, restPool *rest.RequestBuilder) {
r.clients[name] = restPool
}
func (r *RESTClientFactory) Get(name string) *rest.RequestBuilder {
return r.clients[name]
}
func Contains(a []string, x string) bool {
for _, n := range a {
if x == n {
return true
}
}
return false
}
func GetNamesInKeys(regex *regexp.Regexp) []string {
var result []string
configs := archaius.GetConfigs()
for key, _ := range configs {
match := regex.FindStringSubmatch(key)
for i, _ := range regex.SubexpNames() {
if i > 0 && i <= len(match) {
if !Contains(result, match[1]) {
result = append(result, match[1])
}
}
}
}
return result
}
func RegisterHandlers() {
pingService := services.NewPingService()
pingHandler := handlers.NewPingHandler(pingService)
server.RegisterHandler(pingHandler)
gitLabClient := gitlab.NewGitLabClient(restClients.Get("gitlab"))
appService := services.NewAppService(gitLabClient, dbClient)
appHandler := handlers.NewAppHandler(appService)
server.RegisterHandler(appHandler)
secretService := services.NewSecretService(dbClient, appService)
secretHandler := handlers.NewSecretHandler(appService, secretService)
server.RegisterHandler(secretHandler)
snippetService := services.NewSnippetService(secretService)
snippetHandler := handlers.NewSnippetHandler(snippetService)
server.RegisterHandler(snippetHandler)
}
func getSecretValue(key string) string {
secret := secretStore.GetSecret(key)
if secret.Err != nil {
log.Fatalln(secret.Err)
}
return secret.Value
}
func ProvideSecretStore() secrets.ISecretStore {
if !env.IsDev() {
return secrets.NewSecretStore()
} else {
return secrets.NewLocalSecretStore()
}
}
func ProvideDbClient() database.IDbClient {
connectionString := getSecretValue("SECRETS_STORE_PETS-API_PROD_CONNECTION_STRING_KEY_NAME")
mySqlDbClient := database.NewMySQLClient(connectionString)
return database.NewDbClient(mySqlDbClient)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment