Dump changes
This commit is contained in:
parent
e12550a643
commit
aac2ea1b74
25 changed files with 129 additions and 76 deletions
22
pkg/brainbuffer/infrastructure/config.go
Normal file
22
pkg/brainbuffer/infrastructure/config.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package infrastructure
|
||||
|
||||
import (
|
||||
"github.com/knadh/koanf"
|
||||
"github.com/knadh/koanf/providers/env"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func NewConfig() *koanf.Koanf {
|
||||
config := koanf.New(".")
|
||||
|
||||
loadValues(config)
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func loadValues(c *koanf.Koanf) {
|
||||
envProvider := env.Provider("", ".", func(s string) string {
|
||||
return strings.Replace(strings.ToLower(s), "_", ".", -1)
|
||||
})
|
||||
_ = c.Load(envProvider, nil)
|
||||
}
|
||||
18
pkg/brainbuffer/infrastructure/context.go
Normal file
18
pkg/brainbuffer/infrastructure/context.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package infrastructure
|
||||
|
||||
import (
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/knadh/koanf"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Database *pgxpool.Pool
|
||||
Config *koanf.Koanf
|
||||
}
|
||||
|
||||
func NewContext(db *pgxpool.Pool, config *koanf.Koanf) *Context {
|
||||
return &Context{
|
||||
Database: db,
|
||||
Config: config,
|
||||
}
|
||||
}
|
||||
47
pkg/brainbuffer/infrastructure/database/database.go
Normal file
47
pkg/brainbuffer/infrastructure/database/database.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/knadh/koanf"
|
||||
)
|
||||
|
||||
func NewPool(config *koanf.Koanf) *pgxpool.Pool {
|
||||
connStr, err := getConnectionString(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pool, err := pgxpool.Connect(context.Background(), connStr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return pool
|
||||
}
|
||||
|
||||
func getConnectionString(config *koanf.Koanf) (string, error) {
|
||||
username := config.String("db.username")
|
||||
if username == "" {
|
||||
return "", errors.New("database username is missing")
|
||||
}
|
||||
|
||||
password := config.String("db.password")
|
||||
if password == "" {
|
||||
return "", errors.New("database password is missing")
|
||||
}
|
||||
|
||||
name := config.String("db.name")
|
||||
if name == "" {
|
||||
return "", errors.New("database name is missing")
|
||||
}
|
||||
|
||||
host := config.String("db.host")
|
||||
if name == "" {
|
||||
return "", errors.New("database host is missing")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("postgresql://%s:%s@%s/%s", username, password, host, name), nil
|
||||
}
|
||||
27
pkg/brainbuffer/infrastructure/database/migrate.go
Normal file
27
pkg/brainbuffer/infrastructure/database/migrate.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/jackc/tern/migrate"
|
||||
)
|
||||
|
||||
func Migrate(pool *pgxpool.Pool) {
|
||||
conn, err := pool.Acquire(context.Background())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
migrator, err := migrate.NewMigrator(context.Background(), conn.Conn(), "schema_version")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = migrator.LoadMigrations("./migrations"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = migrator.Migrate(context.Background()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
29
pkg/brainbuffer/infrastructure/errors/errors.go
Normal file
29
pkg/brainbuffer/infrastructure/errors/errors.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package errors
|
||||
|
||||
type UnknownError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (err UnknownError) Error() string {
|
||||
return err.Err.Error()
|
||||
}
|
||||
|
||||
func (err UnknownError) Unwrap() error {
|
||||
return err.Err
|
||||
}
|
||||
|
||||
type NotFoundError struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (err NotFoundError) Error() string {
|
||||
return err.Message
|
||||
}
|
||||
|
||||
type AlreadyExistsError struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (err AlreadyExistsError) Error() string {
|
||||
return err.Message
|
||||
}
|
||||
34
pkg/brainbuffer/infrastructure/server/middleware.go
Normal file
34
pkg/brainbuffer/infrastructure/server/middleware.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/rs/zerolog/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Logger() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) (err error) {
|
||||
req := c.Request()
|
||||
res := c.Response()
|
||||
start := time.Now()
|
||||
if err = next(c); err != nil {
|
||||
c.Error(err)
|
||||
}
|
||||
stop := time.Now()
|
||||
|
||||
log.Info().
|
||||
Str("remote_ip", c.RealIP()).
|
||||
Str("host", req.Host).
|
||||
Str("uri", req.RequestURI).
|
||||
Str("method", req.Method).
|
||||
Str("path", req.URL.Path).
|
||||
Str("user_agent", req.UserAgent()).
|
||||
Int("status", res.Status).
|
||||
Str("latency", stop.Sub(start).String()).
|
||||
Send()
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
61
pkg/brainbuffer/infrastructure/server/server.go
Normal file
61
pkg/brainbuffer/infrastructure/server/server.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"brainbuffer/pkg/brainbuffer/domain/task"
|
||||
"brainbuffer/pkg/brainbuffer/infrastructure"
|
||||
apperrors "brainbuffer/pkg/brainbuffer/infrastructure/errors"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/knadh/koanf"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/rs/zerolog/log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func New(context *infrastructure.Context) *echo.Echo {
|
||||
server := echo.New()
|
||||
|
||||
server.HTTPErrorHandler = errorHandler(server)
|
||||
|
||||
registerHandlers(server, context.Database)
|
||||
registerMiddleware(server, context.Config)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func registerHandlers(server *echo.Echo, pool *pgxpool.Pool) {
|
||||
task.AddHandlers(server)
|
||||
}
|
||||
|
||||
func registerMiddleware(server *echo.Echo, conf *koanf.Koanf) {
|
||||
server.Use(middleware.CORS())
|
||||
|
||||
server.Use(Logger())
|
||||
|
||||
server.Use(middleware.JWTWithConfig(middleware.JWTConfig{
|
||||
Skipper: func(ctx echo.Context) bool {
|
||||
return false
|
||||
},
|
||||
SigningMethod: middleware.AlgorithmHS256,
|
||||
SigningKey: conf.Bytes("jwt.key"),
|
||||
}))
|
||||
}
|
||||
|
||||
func errorHandler(s *echo.Echo) echo.HTTPErrorHandler {
|
||||
return func(err error, c echo.Context) {
|
||||
mappedErr := err
|
||||
|
||||
switch v := err.(type) {
|
||||
case apperrors.NotFoundError:
|
||||
mappedErr = echo.NewHTTPError(http.StatusNotFound, v.Error())
|
||||
case apperrors.UnknownError:
|
||||
log.Err(v.Err).Send()
|
||||
mappedErr = echo.NewHTTPError(http.StatusInternalServerError)
|
||||
case apperrors.AlreadyExistsError:
|
||||
// TODO: Change status code to hide user identity.
|
||||
mappedErr = echo.NewHTTPError(http.StatusBadRequest, v.Error())
|
||||
}
|
||||
|
||||
s.DefaultHTTPErrorHandler(mappedErr, c)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue