From 7adf3b9512cc74f70176014318c4f980c9aeda5f Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Sun, 16 Apr 2023 17:17:05 +0200 Subject: [PATCH] Refactor --- bin/entrypoint.sh | 1 + src/cmd/migrate/main.go | 6 +- src/cmd/server/main.go | 82 ++------ src/go.mod | 16 +- src/go.sum | 20 ++ src/internal/app/server/router.go | 62 ------ src/internal/app/server/server.go | 169 ---------------- src/internal/app/server/traefik_handler.go | 18 -- src/internal/config/config.go | 62 ++++++ src/internal/{app => }/database/connect.go | 0 src/internal/{app => }/server/config.go | 0 .../{app => }/server/config_handler.go | 2 +- .../{app => }/server/health_handler.go | 0 .../{app => }/server/login_handler.go | 2 +- src/internal/server/middleware.go | 33 ++++ src/internal/server/router.go | 26 +++ src/internal/server/server.go | 184 ++++++++++++++++++ src/internal/server/traefik_handler.go | 31 +++ src/internal/{app => }/service/auth.go | 2 +- src/internal/{app => }/service/jwt.go | 2 +- .../config/env.go => pkg/config/config.go} | 0 src/pkg/database/connect.go | 16 ++ src/pkg/server/config.go | 21 ++ src/pkg/server/server.go | 79 ++++++++ 24 files changed, 509 insertions(+), 325 deletions(-) delete mode 100644 src/internal/app/server/router.go delete mode 100644 src/internal/app/server/server.go delete mode 100644 src/internal/app/server/traefik_handler.go create mode 100644 src/internal/config/config.go rename src/internal/{app => }/database/connect.go (100%) rename src/internal/{app => }/server/config.go (100%) rename src/internal/{app => }/server/config_handler.go (82%) rename src/internal/{app => }/server/health_handler.go (100%) rename src/internal/{app => }/server/login_handler.go (90%) create mode 100644 src/internal/server/middleware.go create mode 100644 src/internal/server/router.go create mode 100644 src/internal/server/server.go create mode 100644 src/internal/server/traefik_handler.go rename src/internal/{app => }/service/auth.go (93%) rename src/internal/{app => }/service/jwt.go (94%) rename src/{internal/app/config/env.go => pkg/config/config.go} (100%) create mode 100644 src/pkg/database/connect.go create mode 100644 src/pkg/server/config.go create mode 100644 src/pkg/server/server.go diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 3daa03c..4b6d605 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -17,6 +17,7 @@ waitForService() waitForService "postgres-db:5432" waitForService "api-logger:24224" waitForService "api-registry:8500" +waitForService "api-gateway:5672" # waitForService "api-eventbus:5672" # run migrations diff --git a/src/cmd/migrate/main.go b/src/cmd/migrate/main.go index ebe33ad..e8575a7 100644 --- a/src/cmd/migrate/main.go +++ b/src/cmd/migrate/main.go @@ -7,7 +7,7 @@ import ( "os" "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - "git.pbiernat.dev/egommerce/identity-service/internal/app/config" + "git.pbiernat.dev/egommerce/identity-service/pkg/config" "github.com/go-pg/migrations/v8" "github.com/go-pg/pg/v10" ) @@ -40,8 +40,8 @@ func main() { loggerAddr := config.GetEnv("LOGGER_ADDR", defLoggerAddr) mTblName := config.GetEnv("MIGRATIONS_TABLE_NAME", defMigrationsTableName) - logHost, logPort := fluentd.ParseAddr(loggerAddr) - logger := fluentd.NewLogger(defAppName, logHost, logPort) + logHost, logPort, _ := fluentd.ParseAddr(loggerAddr) + logger, _ := fluentd.NewLogger(defAppName, logHost, logPort) defer logger.Close() flag.Usage = usage diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index 42097a9..f0c5503 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -3,79 +3,35 @@ package main import ( "log" "os" - "strconv" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - "git.pbiernat.dev/egommerce/identity-service/internal/app/config" - "git.pbiernat.dev/egommerce/identity-service/internal/app/database" - "git.pbiernat.dev/egommerce/identity-service/internal/app/server" - "github.com/go-redis/redis/v8" -) + baseCnf "git.pbiernat.dev/egommerce/identity-service/pkg/config" -const ( - defAppName = "identity-svc" - defAppDomain = "identity-svc" - defPathPrefix = "/identity" - defNetAddr = ":80" - defLoggerAddr = "api-logger:24224" - defRegistryAddr = "api-registry:8500" - defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" - defCacheAddr = "api-cache:6379" - defCachePassword = "12345678" - defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" - defEventBusURL = "amqp://guest:guest@api-eventbus:5672" - ebEventsExchange = "api-events" - ebEventsQueue = "identity-svc" - defKVNmspc = "dev.egommerce/service/identity-svc" + cnf "git.pbiernat.dev/egommerce/identity-service/internal/config" + svr "git.pbiernat.dev/egommerce/identity-service/internal/server" ) func main() { - if config.ErrLoadingEnvs != nil { - log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + if baseCnf.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", baseCnf.ErrLoadingEnvs) } - c := new(server.Config) - c.AppID, _ = os.Hostname() - c.AppName = config.GetEnv("APP_NAME", defAppName) - c.AppDomain = config.GetEnv("APP_DOMAIN", defAppDomain) - c.PathPrefix = config.GetEnv("APP_PATH_PREFIX", defPathPrefix) - c.NetAddr = config.GetEnv("SERVER_ADDR", defNetAddr) - c.Port, _ = strconv.Atoi(c.NetAddr[1:]) - c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) - c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) - c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) - c.CacheAddr = config.GetEnv("CACHE_ADDR", defCacheAddr) - c.CachePassword = config.GetEnv("CACHE_PASSWORD", defCachePassword) - c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) - c.EventBusExchange = ebEventsExchange - c.KVNamespace = config.GetEnv("APP_KV_NAMESPACE", defKVNmspc) + c := cnf.NewConfig("identity-server") + srv := svr.New( + c, + svr.WithCache(c), + svr.WithDatabase(c), + svr.WithLogger(c), + svr.WithRegistry(c), + ) - logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) - logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) - defer logger.Close() + while := make(chan struct{}) + err := srv.Base.Start(while, srv.Shutdown()) + <-while - // db conn - dbConn, err := database.Connect(c.DbURL) - if err != nil { // fixme: add wait-for-db... - logger.Log("Failed to connect to Database server: %v\n", err) + if err != nil { + log.Fatalf("Failed to start server. Reason: %v\n", err) os.Exit(1) } - defer dbConn.Close() - // redis conn - redis := redis.NewClient(&redis.Options{ - Addr: c.CacheAddr, - Password: c.CachePassword, - DB: 0, - }) - defer redis.Close() - - // start server - srv := server.NewServer(c, logger, dbConn, redis /*, ebCh*/) - - forever := make(chan struct{}) - srv.StartWithGracefulShutdown(forever) - <-forever - - // os.Exit(1) + os.Exit(0) } diff --git a/src/go.mod b/src/go.mod index e34633c..b3a359d 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,7 +3,7 @@ module git.pbiernat.dev/egommerce/identity-service go 1.18 require ( - git.pbiernat.dev/egommerce/go-api-pkg v0.0.136 + git.pbiernat.dev/egommerce/go-api-pkg v0.0.153 github.com/go-pg/migrations/v8 v8.1.0 github.com/go-pg/pg/v10 v10.10.7 github.com/go-redis/redis/v8 v8.11.5 @@ -15,6 +15,7 @@ require ( ) require ( + git.pbiernat.dev/egommerce/api-entities v0.0.26 // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect @@ -35,9 +36,11 @@ require ( github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgproto3/v2 v2.3.1 // indirect - github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgtype v1.13.0 // indirect + github.com/jackc/pgx/v5 v5.3.1 // indirect github.com/jackc/puddle v1.3.0 // indirect + github.com/jackc/puddle/v2 v2.2.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -56,9 +59,10 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/crypto v0.4.0 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/crypto v0.6.0 // indirect + golang.org/x/net v0.6.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect mellium.im/sasl v0.2.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index f426663..c0d110b 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +git.pbiernat.dev/egommerce/api-entities v0.0.26 h1:Avz02GINwuYWOjw1fmZIJ3QgGEIz3a5vRQZNaxxUQIk= +git.pbiernat.dev/egommerce/api-entities v0.0.26/go.mod h1:+BXvUcr6Cr6QNpJsW8BUfe1vVILdWDADNE0e3u0lNvU= git.pbiernat.dev/egommerce/go-api-pkg v0.0.136 h1:SzJRAkqJKdng/3d0V7o/R0yGh7QaZynPBn/P++on9RA= git.pbiernat.dev/egommerce/go-api-pkg v0.0.136/go.mod h1:w2N79aoumjrrcrGPJLkCwxAHtrLd7G4Uj8VOxvPooa0= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.153 h1:Hop3RNnkUHEtT78TFWV9WJHOoARE499665f7YEllN3k= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.153/go.mod h1:w2N79aoumjrrcrGPJLkCwxAHtrLd7G4Uj8VOxvPooa0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= @@ -158,6 +162,8 @@ github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= @@ -171,11 +177,15 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= @@ -337,6 +347,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -369,12 +381,16 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -411,6 +427,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -422,6 +440,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go deleted file mode 100644 index 0d8352b..0000000 --- a/src/internal/app/server/router.go +++ /dev/null @@ -1,62 +0,0 @@ -package server - -import ( - "strings" - - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/cors" -) - -var ( - defaultCORS = cors.New(cors.Config{ - AllowOrigins: "*", - AllowCredentials: true, - AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS", - AllowHeaders: "Accept, Authorization, Content-Type, Vary, X-Request-Id", - }) -) - -func SetupMiddlewares(s *Server) { - s.App.Use(defaultCORS) - s.App.Use(LoggingMiddleware(s.log)) -} - -func SetupRoutes(s *Server) { - s.App.Options("*", defaultCORS) - - s.App.Get("/health", s.HealthHandler) - s.App.Get("/config", s.ConfigHandler) - - api := s.App.Group("/api") - v1 := api.Group("/v1") - v1.Post("/login", s.LoginHandler) - v1.All("/traefik", s.TraefikHandler) -} - -// Middlewares -func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { - return func(c *fiber.Ctx) error { - path := string(c.Request().URI().Path()) - if strings.Contains(path, "/health") { - return c.Next() - } - - if strings.Contains(path, "/traefik") { - log.Log("Request: %s, Headers: %v, remote: %s, via: %s", - c.Request().URI().String(), - c.GetRespHeaders(), - c.Context().RemoteIP().String(), - string(c.Context().UserAgent())) - - return c.Next() - } - - log.Log("Request: %s, remote: %s, via: %s", - c.Request().URI().String(), - c.Context().RemoteIP().String(), - string(c.Context().UserAgent())) - - return c.Next() - } -} diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go deleted file mode 100644 index cd103f0..0000000 --- a/src/internal/app/server/server.go +++ /dev/null @@ -1,169 +0,0 @@ -package server - -import ( - "bytes" - "context" - "encoding/json" - "os" - "os/signal" - "syscall" - "time" - - "github.com/go-redis/redis/v8" - "github.com/gofiber/fiber/v2" - "github.com/jackc/pgx/v4/pgxpool" - - discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" -) - -type Server struct { - *fiber.App - conf *Config - log *fluentd.Logger - db *pgxpool.Pool - cache *redis.Client - discovery *discovery.Service - name string - addr string - kvNmspc string -} - -type Headers struct { - RequestID string `reqHeader:"x-request-id"` -} - -func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, cache *redis.Client /*, ebCh *amqp.Channel*/) *Server { - consul, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.PathPrefix, conf.Port) - if err != nil { - logger.Log("Error connecting to %s: %v", conf.RegistryAddr, err) - } - - logger.Log("Registering service with name: %s, address: %s", consul.Name, consul.Address) - err = consul.Register() - if err != nil { - logger.Log("register error: %v", err) - } - - cnf := fiber.Config{ - AppName: conf.AppName, - ServerHeader: conf.AppName, - ReadTimeout: time.Millisecond * 50, - WriteTimeout: time.Millisecond * 50, - IdleTimeout: time.Millisecond * 50, - // Prefork: true, - } - s := &Server{ - fiber.New(cnf), - conf, - logger, - db, - cache, - /*ebCh,*/ - consul, - conf.AppName, - conf.NetAddr, - conf.KVNamespace, - } - - go func(s *Server) { // Consul Catalog and KV updater - interval := time.Second * 15 - ticker := time.NewTicker(interval) - for range ticker.C { - s.updateKVConfig() - } - }(s) - - go func(s *Server) { // Server metadata cache updater - interval := time.Second * 5 - ticker := time.NewTicker(interval) - for range ticker.C { - s.cacheMetadata() - } - }(s) - - SetupMiddlewares(s) - SetupRoutes(s) - - return s -} - -func (s *Server) Start() { - err := s.Listen(s.addr) - s.log.Log("Starting error: %v", err) -} - -func (s *Server) StartWithGracefulShutdown(forever chan struct{}) { - go func() { - sigint := make(chan os.Signal, 1) - signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - <-sigint - - if err := s.gracefulShutdown(); err != nil { - s.log.Log("Server is not shutting down! Reason: %v", err) - } - - close(forever) - }() - - if err := s.Listen(s.addr); err != nil { - s.log.Log("Server is not running! Reason: %v", err) - } - - <-forever -} - -// GetRequestID Return current requets ID - works only when fiber context are running -func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { - var hdr = new(Headers) - if err := c.ReqHeaderParser(hdr); err != nil { - return "", err - } - - return hdr.RequestID, nil -} - -func (s *Server) updateKVConfig() { // FIXME: duplicated in cmd/worker/main.go - config, _, err := s.discovery.KV().Get(s.kvNmspc, nil) - if err != nil || config == nil { - return - } - - kvCnf := bytes.NewBuffer(config.Value) - decoder := json.NewDecoder(kvCnf) - if err := decoder.Decode(&s.conf); err != nil { - return - } -} - -func (s *Server) cacheMetadata() { - ctx := context.Background() - key, address := "internal__"+s.conf.AppName+"__ips", s.conf.AppID // FIXME: key name - - pos := s.cache.LPos(ctx, key, address, redis.LPosArgs{}).Val() - if pos >= 0 { - s.cache.LRem(ctx, key, 0, address) - } - - s.cache.LPush(ctx, key, address).Err() -} - -func (s *Server) clearMetadataCache() { - ctx := context.Background() - key, address := "internal__"+s.conf.AppName+"__ips", s.conf.AppID // FIXME: key name - - s.cache.LRem(ctx, key, 0, address) -} - -func (s *Server) gracefulShutdown() error { - s.log.Log("Server is going down...") - s.log.Log("Unregistering service: %s", s.discovery.GetID()) - s.discovery.Unregister() - s.clearMetadataCache() - - // s.ebCh.Close() - s.db.Close() - s.log.Close() - - return s.Shutdown() -} diff --git a/src/internal/app/server/traefik_handler.go b/src/internal/app/server/traefik_handler.go deleted file mode 100644 index a29fa29..0000000 --- a/src/internal/app/server/traefik_handler.go +++ /dev/null @@ -1,18 +0,0 @@ -package server - -import ( - "git.pbiernat.dev/egommerce/identity-service/internal/app/service" - "github.com/gofiber/fiber/v2" -) - -type TraefikAuthResponse struct { - Status string `json:"status"` -} - -func (s *Server) TraefikHandler(c *fiber.Ctx) error { - cookie := service.AuthService.Cookie("traefik", "tmp-dummy-traefik-token") - c.Cookie(cookie) - s.log.Log("Traefik action set cookie. done.") - - return c.JSON(&TraefikAuthResponse{Status: "OK"}) -} diff --git a/src/internal/config/config.go b/src/internal/config/config.go new file mode 100644 index 0000000..e452e37 --- /dev/null +++ b/src/internal/config/config.go @@ -0,0 +1,62 @@ +package common + +import ( + "os" + + cnf "git.pbiernat.dev/egommerce/identity-service/pkg/config" + srv "git.pbiernat.dev/egommerce/identity-service/pkg/server" +) + +const ( + defAppName = "identity-svc" + defAppDomain = "identity-svc" + defPathPrefix = "/identity" + defNetAddr = ":80" + defLoggerAddr = "api-logger:24224" + defRegistryAddr = "api-registry:8500" + defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" + defCacheAddr = "api-cache:6379" + defCachePassword = "12345678" + defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" + defEventBusURL = "amqp://guest:guest@api-gateway:5672" + defEbEventsExchange = "api-events" + defEbEventsQueue = "identity-svc" + defKVNmspc = "dev.egommerce/service/identity-svc" +) + +type Config struct { + Base *srv.Config + + DbURL string `json:"db_url"` + CacheAddr string `json:"cache_addr"` + CachePassword string `json:"cache_password"` + EventBusExchange string `json:"eventbus_exchange"` + EventBusQueue string `json:"eventbus_queue"` + EventBusURL string `json:"eventbus_url"` + LoggerAddr string `json:"logger_addr"` + KVNamespace string + RegistryAddr string + + // Fields with JSON mappings are available through Consul KV storage +} + +func NewConfig(name string) *Config { + c := new(Config) + c.Base = new(srv.Config) + + c.Base.AppID, _ = os.Hostname() + c.Base.AppName = name + c.Base.NetAddr = cnf.GetEnv("SERVER_ADDR", defNetAddr) + c.Base.PathPrefix = cnf.GetEnv("APP_PATH_PREFIX", defPathPrefix) + + c.CacheAddr = cnf.GetEnv("CACHE_ADDR", defCacheAddr) + c.CachePassword = cnf.GetEnv("CACHE_PASSWORD", defCachePassword) + c.DbURL = cnf.GetEnv("DATABASE_URL", defDbURL) + c.EventBusExchange = defEbEventsExchange + c.EventBusURL = cnf.GetEnv("EVENTBUS_URL", defEventBusURL) + c.KVNamespace = cnf.GetEnv("APP_KV_NAMESPACE", defKVNmspc) + c.LoggerAddr = cnf.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.RegistryAddr = cnf.GetEnv("REGISTRY_ADDR", defRegistryAddr) + + return c +} diff --git a/src/internal/app/database/connect.go b/src/internal/database/connect.go similarity index 100% rename from src/internal/app/database/connect.go rename to src/internal/database/connect.go diff --git a/src/internal/app/server/config.go b/src/internal/server/config.go similarity index 100% rename from src/internal/app/server/config.go rename to src/internal/server/config.go diff --git a/src/internal/app/server/config_handler.go b/src/internal/server/config_handler.go similarity index 82% rename from src/internal/app/server/config_handler.go rename to src/internal/server/config_handler.go index cfb9949..26c3ac1 100644 --- a/src/internal/app/server/config_handler.go +++ b/src/internal/server/config_handler.go @@ -5,5 +5,5 @@ import ( ) func (s *Server) ConfigHandler(c *fiber.Ctx) error { - return c.JSON(s.conf) + return c.JSON(s.Config) } diff --git a/src/internal/app/server/health_handler.go b/src/internal/server/health_handler.go similarity index 100% rename from src/internal/app/server/health_handler.go rename to src/internal/server/health_handler.go diff --git a/src/internal/app/server/login_handler.go b/src/internal/server/login_handler.go similarity index 90% rename from src/internal/app/server/login_handler.go rename to src/internal/server/login_handler.go index fb97e34..aec3e8d 100644 --- a/src/internal/app/server/login_handler.go +++ b/src/internal/server/login_handler.go @@ -1,7 +1,7 @@ package server import ( - "git.pbiernat.dev/egommerce/identity-service/internal/app/service" + "git.pbiernat.dev/egommerce/identity-service/internal/service" "github.com/gofiber/fiber/v2" ) diff --git a/src/internal/server/middleware.go b/src/internal/server/middleware.go new file mode 100644 index 0000000..74e2cda --- /dev/null +++ b/src/internal/server/middleware.go @@ -0,0 +1,33 @@ +package server + +import ( + "strings" + + "github.com/gofiber/fiber/v2" + + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" +) + +// "github.com/gofiber/fiber/v2" +// "github.com/gofiber/fiber/v2/middleware/cors" + +func SetupMiddleware(s *Server) { + s.Base.Use(defaultCORS) + s.Base.Use(LoggingMiddleware(s.Logger)) +} + +func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { + return func(c *fiber.Ctx) error { + path := string(c.Request().URI().Path()) + if strings.Contains(path, "/health") { + return c.Next() + } + + log.Log("Request: %s, remote: %s, via: %s", + c.Request().URI().String(), + c.Context().RemoteIP().String(), + string(c.Context().UserAgent())) + + return c.Next() + } +} diff --git a/src/internal/server/router.go b/src/internal/server/router.go new file mode 100644 index 0000000..230ced3 --- /dev/null +++ b/src/internal/server/router.go @@ -0,0 +1,26 @@ +package server + +import ( + "github.com/gofiber/fiber/v2/middleware/cors" +) + +var ( + defaultCORS = cors.New(cors.Config{ + AllowOrigins: "*", + AllowCredentials: true, + AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS", + AllowHeaders: "Accept, Authorization, Content-Type, Vary, X-Request-Id", + }) +) + +func SetupRouter(s *Server) { + s.Base.Options("*", defaultCORS) + + s.Base.Get("/health", s.HealthHandler) + s.Base.Get("/config", s.ConfigHandler) + + api := s.Base.Group("/api") + v1 := api.Group("/v1") + v1.Post("/login", s.LoginHandler) + v1.All("/traefik", s.TraefikHandler) +} diff --git a/src/internal/server/server.go b/src/internal/server/server.go new file mode 100644 index 0000000..c23913a --- /dev/null +++ b/src/internal/server/server.go @@ -0,0 +1,184 @@ +package server + +import ( + "bytes" + "context" + "encoding/json" + "log" + "os" + "strconv" + "time" + + "github.com/go-redis/redis/v8" + "github.com/jackc/pgx/v5/pgxpool" + + "git.pbiernat.dev/egommerce/go-api-pkg/consul" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + + db "git.pbiernat.dev/egommerce/identity-service/pkg/database" + srv "git.pbiernat.dev/egommerce/identity-service/pkg/server" + + cnf "git.pbiernat.dev/egommerce/identity-service/internal/config" +) + +type ( + Server struct { + Base *srv.Server + Config *cnf.Config + + Cache *redis.Client + Database *pgxpool.Pool + Logger *fluentd.Logger + Registry *consul.Service + } + + OptionFn func(*Server) error // FIXME: similar in worker +) + +func New(c *cnf.Config, opts ...OptionFn) *Server { + svr := &Server{ + Base: srv.New(c.Base), + Config: c, + } + + for _, opt := range opts { + if err := opt(svr); err != nil { + log.Fatalf("Failed to attach extension to the server. Err: %v\n", err) + } + } + + SetupMiddleware(svr) + SetupRouter(svr) + + return svr +} + +func WithCache(c *cnf.Config) OptionFn { + redis := redis.NewClient(&redis.Options{ + Addr: c.CacheAddr, + Password: c.CachePassword, + DB: 0, + }) + + return func(s *Server) error { + s.Cache = redis + + return nil + } +} + +func WithDatabase(c *cnf.Config) OptionFn { + dbConn, err := db.Connect(c.DbURL) + if err != nil { + log.Fatalf("Failed to connect to the Database: %s. Err: %v\n", c.DbURL, err) + os.Exit(1) + } + + return func(s *Server) error { + s.Database = dbConn + + return nil + } +} + +func WithLogger(c *cnf.Config) OptionFn { + return func(s *Server) error { + logHost, logPort, err := fluentd.ParseAddr(c.LoggerAddr) + if err != nil { + log.Fatalf("Failed to parse Fluentd address: %s. Err: %v", c.LoggerAddr, err) + } + + logger, err := fluentd.NewLogger(c.Base.GetAppFullName(), logHost, logPort) + if err != nil { + log.Fatalf("Failed to connect to the Fluentd on %s:%d. Err: %v", logHost, logPort, err) + } + + s.Logger = logger + + return nil + } +} + +func WithRegistry(c *cnf.Config) OptionFn { + return func(s *Server) error { + port, _ := strconv.Atoi(c.Base.NetAddr[1:]) // FIXME: can be IP:PORT which will cause error + registry, err := consul.NewService(c.RegistryAddr, c.Base.AppID, c.Base.AppName, c.Base.AppID, c.Base.AppName, c.Base.PathPrefix, port) + if err != nil { + log.Fatalf("Failed to connect to the Consul on: %s. Err: %v", c.RegistryAddr, err) + } + + err = registry.Register() + if err != nil { + log.Fatalf("Failed to register in the Consul service. Err: %v", err) + } + + s.Registry = registry + + go func() { // Consul KV updater + ticker := time.NewTicker(time.Second * 15) + for range ticker.C { + fetchKVConfig(s) // FIXME: duplicated in worker + } + }() + + go func() { // Server metadata cache updater + ticker := time.NewTicker(time.Second * 5) + for range ticker.C { + s.cacheMetadata() + } + }() + + return nil + } +} + +func (s *Server) Shutdown() srv.PurgeFn { + return func(srv *srv.Server) error { + s.Logger.Log("Server %s is going down...", s.Base.AppID) + + s.Registry.Unregister() + s.clearMetadataCache() + s.Database.Close() + s.Logger.Log("Gone.") + s.Logger.Close() + + return s.Base.Shutdown() + } +} + +// @CHECK: merge s.Config and s.Base.Config to display all config as one array/map +func fetchKVConfig(s *Server) { // @FIXME: merge duplication in server.go and worker.go + config, _, err := s.Registry.KV().Get(s.Config.KVNamespace, nil) + if err != nil || config == nil { + return + } + + kvCnf := bytes.NewBuffer(config.Value) + decoder := json.NewDecoder(kvCnf) + if err := decoder.Decode(&s.Config); err != nil { + return + } +} + +func (s *Server) cacheMetadata() { + ctx := context.Background() + key, address := s.getMetadataIPsKey(), s.Base.Config.AppID + + pos := s.Cache.LPos(ctx, key, address, redis.LPosArgs{}).Val() + if pos >= 0 { + s.Cache.LRem(ctx, key, 0, address) + } + + s.Cache.LPush(ctx, key, address).Err() +} + +func (s *Server) clearMetadataCache() { + ctx := context.Background() + key, address := s.getMetadataIPsKey(), s.Config.Base.AppID + + s.Cache.LRem(ctx, key, 0, address) +} + +func (s *Server) getMetadataIPsKey() string { + return "internal__" + s.Base.Config.AppName + "__ips" +} diff --git a/src/internal/server/traefik_handler.go b/src/internal/server/traefik_handler.go new file mode 100644 index 0000000..6d1e4ab --- /dev/null +++ b/src/internal/server/traefik_handler.go @@ -0,0 +1,31 @@ +package server + +import ( + "net/http" + + "git.pbiernat.dev/egommerce/identity-service/internal/service" + "github.com/gofiber/fiber/v2" +) + +type TraefikAuthResponse struct { + Status string `json:"status,omitempty"` + Message string `json:"msg,omitempty"` +} + +func (s *Server) TraefikHandler(c *fiber.Ctx) error { + cookie := service.AuthService.Cookie("traefik", "tmp-dummy-traefik-token") + + c.Cookie(cookie) + s.Logger.Log("Traefik action set cookie. done.") + + c.Response().Header.Add("Server", "identity-svc/traefik") + reqCookie := c.Request().Header.Cookie("basket_id") + s.Logger.Log("Request cookie: %v", reqCookie) + + return c. + Status(http.StatusOK). + JSON(&TraefikAuthResponse{Status: "OK"}) + // return c. + // Status(http.StatusUnauthorized). + // JSON(&TraefikAuthResponse{Message: "Access denied mf..."}) +} diff --git a/src/internal/app/service/auth.go b/src/internal/service/auth.go similarity index 93% rename from src/internal/app/service/auth.go rename to src/internal/service/auth.go index 9b33609..b6b68c6 100644 --- a/src/internal/app/service/auth.go +++ b/src/internal/service/auth.go @@ -4,7 +4,7 @@ import ( "errors" "strconv" - "git.pbiernat.dev/egommerce/identity-service/internal/app/config" + "git.pbiernat.dev/egommerce/identity-service/pkg/config" "github.com/gofiber/fiber/v2" ) diff --git a/src/internal/app/service/jwt.go b/src/internal/service/jwt.go similarity index 94% rename from src/internal/app/service/jwt.go rename to src/internal/service/jwt.go index f77a10d..f707d68 100644 --- a/src/internal/app/service/jwt.go +++ b/src/internal/service/jwt.go @@ -5,7 +5,7 @@ import ( "strconv" "time" - "git.pbiernat.dev/egommerce/identity-service/internal/app/config" + "git.pbiernat.dev/egommerce/identity-service/pkg/config" "github.com/golang-jwt/jwt" ) diff --git a/src/internal/app/config/env.go b/src/pkg/config/config.go similarity index 100% rename from src/internal/app/config/env.go rename to src/pkg/config/config.go diff --git a/src/pkg/database/connect.go b/src/pkg/database/connect.go new file mode 100644 index 0000000..e8c889c --- /dev/null +++ b/src/pkg/database/connect.go @@ -0,0 +1,16 @@ +package database + +import ( + "context" + + "github.com/jackc/pgx/v5/pgxpool" +) + +func Connect(connStr string) (*pgxpool.Pool, error) { + pool, err := pgxpool.New(context.Background(), connStr) + if err != nil { + return nil, err + } + + return pool, nil +} diff --git a/src/pkg/server/config.go b/src/pkg/server/config.go new file mode 100644 index 0000000..fca21d3 --- /dev/null +++ b/src/pkg/server/config.go @@ -0,0 +1,21 @@ +package server + +import ( + "fmt" + "time" +) + +type Config struct { + AppID string + AppName string + NetAddr string + PathPrefix string + + IdleTimeout time.Duration // miliseconds + ReadTimeout time.Duration // miliseconds + WriteTimeout time.Duration // miliseconds +} + +func (c *Config) GetAppFullName() string { + return fmt.Sprintf("%s_%s", c.AppName, c.AppID) +} diff --git a/src/pkg/server/server.go b/src/pkg/server/server.go new file mode 100644 index 0000000..9f76a01 --- /dev/null +++ b/src/pkg/server/server.go @@ -0,0 +1,79 @@ +package server + +import ( + "log" + "os" + "os/signal" + "syscall" + "time" + + "github.com/gofiber/fiber/v2" + + "git.pbiernat.dev/egommerce/api-entities/http" +) + +type ( + Server struct { + *fiber.App + *Config + + addr string // e.g. "127.0.0.1:8080" + // name string // e.g. "awesome-rest-api" + // kvNmspc string + } + HeaderRequestID struct { + RequestID string `reqHeader:"x-request-id"` + } + OptionFn func(*Server) error + PurgeFn func(*Server) error +) + +func New(conf *Config) *Server { + return &Server{ + App: fiber.New(fiber.Config{ + AppName: conf.AppID, + ServerHeader: conf.AppName, + ReadTimeout: conf.ReadTimeout * time.Millisecond, + WriteTimeout: conf.WriteTimeout * time.Millisecond, + IdleTimeout: conf.IdleTimeout * time.Millisecond, + }), + Config: conf, + addr: conf.NetAddr, + } +} + +func (s *Server) Start(while chan struct{}, prgFn PurgeFn) error { + go func() { + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + <-sigint + + if err := prgFn(s); err != nil { + log.Fatalf("Failed to shutdown server. Reason: %v\n", err) + } + + close(while) + }() + + err := s.Listen(s.addr) + if err != nil { + log.Fatalf("Failed to start server: %s. Reason: %v\n", s.Config.AppID, err) + close(while) + } + <-while + + return err +} + +func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { + var hdr = new(HeaderRequestID) + if err := c.ReqHeaderParser(hdr); err != nil { + return "", err + } + + return hdr.RequestID, nil +} + +func (s *Server) Error(c *fiber.Ctx, code int, msg string) error { + return c.Status(code).JSON(http.ErrorResponse{Error: msg}) +}