separate servers internal and external

This commit is contained in:
Pavel 2024-06-10 13:16:24 +03:00
parent 5c78187bf0
commit 9adf427501
10 changed files with 188 additions and 116 deletions

@ -3,8 +3,10 @@ JWT_ISSUER="pena-auth-service"
JWT_AUDIENCE="pena"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69\n80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B\ndA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y\n+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----"
HTTP_HOST=0.0.0.0
HTTP_PORT=8082
EXTERNAL_HTTP_HOST=0.0.0.0
EXTERNAL_HTTP_PORT=8082
INTERNAL_HTTP_HOST=0.0.0.0
INTERNAL_HTTP_PORT=8083
GRPC_HOST=0.0.0.0
GRPC_PORT=9001

@ -152,14 +152,22 @@ func Run(config *models.Config, logger *zap.Logger, build Build) (appErr error)
MiddleWare: middleWare,
})
serverHTTP := server.NewServer(server.ServerConfig{
serverExternalHTTP := server.NewServer(server.ServerConfig{
Logger: logger,
Hlog: loggerHlog,
Controllers: []server.Controller{httpControllers.CurrencyController, httpControllers.HistoryController, httpControllers.CartController, httpControllers.WalletController, httpControllers.AccountController},
JWTConfig: &config.Service.JWT,
})
serverHTTP.ListRoutes()
serverInternalHTTP := server.NewServer(server.ServerConfig{
Logger: logger,
Hlog: loggerHlog,
Controllers: []server.Controller{httpControllers.AccountInternalController},
JWTConfig: &config.Service.JWT,
})
serverExternalHTTP.ListRoutes()
serverInternalHTTP.ListRoutes()
serverGRPC, grpcErr := server.NewGRPC(server.DepsGRPC{Logger: logger})
if grpcErr != nil {
@ -169,8 +177,15 @@ func Run(config *models.Config, logger *zap.Logger, build Build) (appErr error)
serverGRPC.Register(rpcControllers)
go func() {
if err := serverHTTP.Start(config.HTTP.Host + ":" + config.HTTP.Port); err != nil {
logger.Error("Server startup error", zap.Error(err))
if err := serverExternalHTTP.Start(config.HTTP.ExternalHost + ":" + config.HTTP.ExternalPort); err != nil {
logger.Error("Server external startup error", zap.Error(err))
cancel()
}
}()
go func() {
if err := serverInternalHTTP.Start(config.HTTP.InternalHost + ":" + config.HTTP.InternalPort); err != nil {
logger.Error("Server internal startup error", zap.Error(err))
cancel()
}
}()
@ -178,7 +193,8 @@ func Run(config *models.Config, logger *zap.Logger, build Build) (appErr error)
go serverGRPC.Run(&config.GRPC)
closer.Add(mongoDB.Client().Disconnect)
closer.Add(serverHTTP.Shutdown)
closer.Add(serverExternalHTTP.Shutdown)
closer.Add(serverInternalHTTP.Shutdown)
closer.Add(serverGRPC.Stop)
closer.Add(closer.Wrap(kafkaTariffClient.Close))

@ -9,6 +9,7 @@ import (
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/grpc/payment"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/account"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/account_internal"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/cart"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/currency"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/history"
@ -20,7 +21,7 @@ type RpcControllersDeps struct {
Logger *zap.Logger
Services *Services
Repositories *Repositories
HLogger hlog.Logger
HLogger hlog.Logger
}
type RpcControllers struct {
@ -54,11 +55,12 @@ type HttpControllersDeps struct {
}
type HttpController struct {
AccountController *account.AccountController
CartController *cart.CartController
HistoryController *history.HistoryController
WalletController *wallet.WalletController
CurrencyController *currency.CurrencyController
AccountController *account.AccountController
AccountInternalController *account_internal.AccountInternalController
CartController *cart.CartController
HistoryController *history.HistoryController
WalletController *wallet.WalletController
CurrencyController *currency.CurrencyController
}
func NewHttpControllers(deps HttpControllersDeps) *HttpController {
@ -70,6 +72,12 @@ func NewHttpControllers(deps HttpControllersDeps) *HttpController {
Encrypt: deps.Encrypt,
AuthClient: deps.Clients.AuthClient,
}),
AccountInternalController: account_internal.NewAccountInternalController(
account_internal.Deps{
MiddleWare: deps.MiddleWare,
AccountRepo: deps.Repositories.AccountRepository,
Logger: deps.Logger,
}),
CartController: cart.NewCartController(cart.Deps{
MiddleWare: deps.MiddleWare,
Logger: deps.Logger,

@ -7,7 +7,6 @@ import (
"fmt"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"math"
"penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
@ -15,7 +14,6 @@ import (
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"strconv"
)
type Deps struct {
@ -77,26 +75,6 @@ func (receiver *AccountController) Update(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) SetVerificationStatus(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
}
var request models.SetAccountStatus
if err := ctx.BodyParser(&request); err != nil {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err)
}
account, err := receiver.accountRepo.SetStatus(ctx.Context(), userID, request.Status)
if err != nil {
receiver.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
return receiver.middleWare.ErrorOld(ctx, err)
}
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) Get(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
@ -180,74 +158,6 @@ func (receiver *AccountController) Create(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) DeleteCurrent(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
}
account, err := receiver.accountRepo.Remove(ctx.Context(), userID)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) GetCurrent(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
}
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) Pagination(ctx *fiber.Ctx) error {
pageStr := ctx.Query("page", "1")
limitStr := ctx.Query("limit", "100")
page, err := strconv.ParseInt(pageStr, 10, 64)
if err != nil || page < 1 {
page = 1
}
limit, err := strconv.ParseInt(limitStr, 10, 64)
if err != nil || limit < 1 {
limit = models.DefaultLimit
} else {
limit = int64(math.Min(float64(limit), float64(models.DefaultLimit)))
}
count, err := receiver.accountRepo.CountAll(ctx.Context())
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
if count == 0 {
response := models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}
return ctx.Status(fiber.StatusOK).JSON(response)
}
totalPages := int64(math.Ceil(float64(count) / float64(limit)))
accounts, err := receiver.accountRepo.FindMany(ctx.Context(), page, limit)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
response := models.PaginationResponse[models.Account]{
TotalPages: totalPages,
Records: accounts,
}
return ctx.Status(fiber.StatusOK).JSON(response)
}
func (receiver *AccountController) AccountPipe(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {

@ -8,10 +8,6 @@ func (receiver *AccountController) Register(router fiber.Router) {
router.Patch("/account", receiver.Update)
router.Post("/account", receiver.Create)
router.Get("/account/pipe", receiver.AccountPipe)
router.Delete("/account/:userId", receiver.DeleteCurrent)
router.Get("/account/:userId", receiver.GetCurrent)
router.Patch("/account/:userId", receiver.SetVerificationStatus)
router.Get("/accounts", receiver.Pagination)
}
func (receiver *AccountController) Name() string {

@ -0,0 +1,119 @@
package account_internal
import (
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"math"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"strconv"
)
type Deps struct {
MiddleWare *http.MiddleWare
AccountRepo *repository.AccountRepository
Logger *zap.Logger
}
type AccountInternalController struct {
middleWare *http.MiddleWare
accountRepo *repository.AccountRepository
logger *zap.Logger
}
func NewAccountInternalController(deps Deps) *AccountInternalController {
return &AccountInternalController{
middleWare: deps.MiddleWare,
accountRepo: deps.AccountRepo,
logger: deps.Logger,
}
}
func (receiver *AccountInternalController) SetVerificationStatus(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
}
var request models.SetAccountStatus
if err := ctx.BodyParser(&request); err != nil {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err)
}
account, err := receiver.accountRepo.SetStatus(ctx.Context(), userID, request.Status)
if err != nil {
receiver.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
return receiver.middleWare.ErrorOld(ctx, err)
}
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountInternalController) DeleteCurrent(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
}
account, err := receiver.accountRepo.Remove(ctx.Context(), userID)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountInternalController) GetCurrent(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
}
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountInternalController) Pagination(ctx *fiber.Ctx) error {
pageStr := ctx.Query("page", "1")
limitStr := ctx.Query("limit", "100")
page, err := strconv.ParseInt(pageStr, 10, 64)
if err != nil || page < 1 {
page = 1
}
limit, err := strconv.ParseInt(limitStr, 10, 64)
if err != nil || limit < 1 {
limit = models.DefaultLimit
} else {
limit = int64(math.Min(float64(limit), float64(models.DefaultLimit)))
}
count, err := receiver.accountRepo.CountAll(ctx.Context())
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
if count == 0 {
response := models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}
return ctx.Status(fiber.StatusOK).JSON(response)
}
totalPages := int64(math.Ceil(float64(count) / float64(limit)))
accounts, err := receiver.accountRepo.FindMany(ctx.Context(), page, limit)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
response := models.PaginationResponse[models.Account]{
TotalPages: totalPages,
Records: accounts,
}
return ctx.Status(fiber.StatusOK).JSON(response)
}

@ -0,0 +1,14 @@
package account_internal
import "github.com/gofiber/fiber/v2"
func (receiver *AccountInternalController) Register(router fiber.Router) {
router.Delete("/account/:userId", receiver.DeleteCurrent)
router.Get("/account/:userId", receiver.GetCurrent)
router.Patch("/account/:userId", receiver.SetVerificationStatus)
router.Get("/accounts", receiver.Pagination)
}
func (receiver *AccountInternalController) Name() string {
return ""
}

@ -15,8 +15,10 @@ type Config struct {
}
type ConfigurationHTTP struct {
Host string `env:"HTTP_HOST,default=localhost"`
Port string `env:"HTTP_PORT,default=8080"`
ExternalHost string `env:"EXTERNAL_HTTP_HOST,default=localhost"`
ExternalPort string `env:"EXTERNAL_HTTP_PORT,default=8080"`
InternalHost string `env:"INTERNAL_HTTP_HOST,default=localhost"`
InternalPort string `env:"INTERNAL_HTTP_PORT,default=8081"`
}
type ConfigurationGRPC struct {

@ -19,7 +19,7 @@ func TestChangeAccount(t *testing.T) {
defer cancel()
assert.NotPanics(t, func() {
token, tokenErr := jwtUtil.Create("64e5d9830fcca0596d82c0c7")
token, tokenErr := jwtUtil.Create("64ebda4387392e122e5d411f")
if isNoError := assert.NoError(t, tokenErr); !isNoError {
return
}
@ -43,7 +43,7 @@ func TestChangeAccount(t *testing.T) {
return
}
assert.Equal(t, "64e5d9830fcca0596d82c0c7", responseChangeAccount.Body.UserID)
assert.Equal(t, "64ebda4387392e122e5d411f", responseChangeAccount.Body.UserID)
assert.Equal(t, "Aloha", responseChangeAccount.Body.Name.Middlename)
assert.Equal(t, "Holla", responseChangeAccount.Body.Name.FirstName)
assert.Equal(t, "Adios payasos", responseChangeAccount.Body.Name.Orgname)
@ -54,7 +54,7 @@ func TestChangeAccount(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
assert.NotPanics(t, func() {
token, tokenErr := jwtUtil.Create("64e5d9830fcca0596d82c0c7")
token, tokenErr := jwtUtil.Create("64ebda4387392e122e5d411f")
if isNoError := assert.NoError(t, tokenErr); !isNoError {
return
}
@ -64,7 +64,7 @@ func TestChangeAccount(t *testing.T) {
}
responseStatusAccount, errStatusAccount := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
URL: "http://localhost:8082/account/64e5d9830fcca0596d82c0c7",
URL: "http://localhost:8083/account/64ebda4387392e122e5d411f",
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
Body: statusRequest,
})

@ -47,7 +47,7 @@ func TestGetAccount(t *testing.T) {
}
responseGetAccount, errGetAccount := client.Get[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
URL: "http://localhost:8082/account/64e5e1ca87392e122e5d3de7",
URL: "http://localhost:8083/account/64e5e1ca87392e122e5d3de7",
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
})
if isNoError := assert.NoError(t, errGetAccount); !isNoError {
@ -61,6 +61,10 @@ func TestGetAccount(t *testing.T) {
})
})
t.Run("Получение аккаунтов с пагинацией", func(t *testing.T) {
token, tokenErr := jwtUtil.Create("64e5e1ca87392e122e5d3de7")
if isNoError := assert.NoError(t, tokenErr); !isNoError {
return
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
assert.NotPanics(t, func() {
@ -77,8 +81,9 @@ func TestGetAccount(t *testing.T) {
}
responseGetAccount, errGetAccount := client.Get[models.PaginationResponse[models.Account], models.ResponseErrorHTTP](ctx, &client.RequestSettings{
URL: "http://localhost:8082/accounts",
Body: params,
URL: "http://localhost:8083/accounts",
Body: params,
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
})
if isNoError := assert.NoError(t, errGetAccount); !isNoError {
return