generated from PenaSide/GolangTemplate
separate servers internal and external
This commit is contained in:
parent
5c78187bf0
commit
9adf427501
@ -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)
|
||||
}
|
14
internal/interface/controller/http/account_internal/route.go
Normal file
14
internal/interface/controller/http/account_internal/route.go
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user