Dump changes

This commit is contained in:
Andrey Chervyakov 2022-06-03 23:44:08 +06:00
parent e12550a643
commit aac2ea1b74
Signed by: cognio
GPG key ID: DAA316147EB0D58D
25 changed files with 129 additions and 76 deletions

View 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)
}

View 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,
}
}

View 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
}

View 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)
}
}

View 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
}

View 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
}
}
}

View 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)
}
}