Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release/38851105: Validation server side and docker-compose #2

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# [Задача №00000000](https://bigbosop215.kaiten.ru/space/439413/card/00000000)

### Что было не так:
<описание проблемы/причины заведения новой фичи>
### Что было сделано:
* слой repository;
* добавлена валидация на уникальность email;
* ручка на получение подборок фильмов;
* написаны тесты и моки.
### Чек лист до ревью :
- [ ] PR разбит на логические коммиты (если нет, то нужно разбить);
- [ ] PR не содержит секретов (пароли, токены, ключи);
- [ ] PR не содержит лишних файлов (например, `.env`);
- [ ] PR не содержит коммитов, которые не относятся к задаче;

**Перед тем, как отдать на ревью нужно убедиться, что все пункты выполнены**

### как вливать ветку
Если это обычная задача, то просто `squash merge` в `develop`
Если это хотфикс, то обычный `merge` в `master` и `develop` (должно быть два `pull request`). При этом в ветке должен быть один коммит
Если это релиз, то обычный `merge` и в `master` и в `develop`. Там будет несколько коммитов
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/validation-service/bin/
/validation-service/.env
40 changes: 40 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: '3.9'

volumes:
postgres_volume:
redis:

services:
validation_ms:
build:
context: ./validation-service/
dockerfile: Dockerfile
restart: always
ports:
- 5050:5050
networks:
- netflix
redis:
image: 'redis:latest'
command: redis-server
volumes:
- redis:/data
networks:
- netflix
db:
image: postgres:latest
environment:
- "POSTGRES_DB=netflix"
- "POSTGRES_USER=test"
- "POSTGRES_PASSWORD=test"
volumes:
- "postgres_volume:/var/lib/postgresql/data"
networks:
- netflix


networks:
netflix:
default:
external:
name: netflix # Не забыть создать сеть перед деплоем
4 changes: 2 additions & 2 deletions validation-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ RUN go mod download
RUN go mod tidy
RUN go build cmd/main.go

EXPOSE 8081
EXPOSE 5050

CMD [ "main" ]
CMD [ "./main" ]

# /app/
# /api
Expand Down
10 changes: 4 additions & 6 deletions validation-service/api/validation/validation.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ package validation;

option go_package = ".";

import "google/protobuf/timestamp.proto";

message ValidateRegistrationRequest {
string email = 1;
string password = 2;
string password_confirm = 3;
}

message ValidateAuthorizationRequest {
string email = 1;
string password = 2;
int32 sex = 4;
google.protobuf.Timestamp bitrhdate = 5;
}

message ErrorMessage {
Expand All @@ -27,5 +26,4 @@ message ValidationResponse {

service Validation {
rpc ValidateRegistration(ValidateRegistrationRequest) returns (ValidationResponse);
rpc ValidateAuthorization(ValidateAuthorizationRequest) returns (ValidationResponse);
}
14 changes: 13 additions & 1 deletion validation-service/cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
package main

import (
"log"

"github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/app"
)

func main() {

a, ctx, err := app.New()

if err != nil {
log.Fatal(err)
}

a.Run(ctx)
}
15 changes: 15 additions & 0 deletions validation-service/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package config

type Config struct {
Listener Listener `yaml:"listener"`
}

type Listener struct {
Address string `yaml:"address"`
Port int `yaml:"port"`
}

type ConfigContextKey struct {
Address string
Port int
}
53 changes: 53 additions & 0 deletions validation-service/config/config_methods.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package config

import (
"context"
"log"
"os"
"path/filepath"

"github.com/joho/godotenv"
"gopkg.in/yaml.v3"
)

func GetConfigFromContext(ctx context.Context) *Config {
value, ok := ctx.Value(ConfigContextKey{}).(*Config)
if !ok {
return nil
}

return value
}

func CreateConfigContext() (context.Context, error) {
ctx := context.Background()
config, err := readConf()
if err != nil {
return nil, err
}

return context.WithValue(ctx, ConfigContextKey{}, config), nil
}

func readConf() (*Config, error) {
err := godotenv.Load()

if err != nil {
log.Fatalf("Error loading .env file", err)
}

cfg := &Config{}

filename, _ := filepath.Abs(os.Getenv("CFG_PATH"))
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}

err = yaml.Unmarshal(data, cfg)
if err != nil {
return nil, err
}

return cfg, nil
}
14 changes: 12 additions & 2 deletions validation-service/go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
module github.com/go-park-mail-ru/2024_2_GOATS
module github.com/go-park-mail-ru/2024_2_GOATS/validation-service

go 1.22.2

require (
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
)

require (
github.com/joho/godotenv v1.5.1 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
17 changes: 17 additions & 0 deletions validation-service/go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
26 changes: 26 additions & 0 deletions validation-service/internal/app/api/converter/converter.go
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
package converter

import (
"github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/app/model"
desc "github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/pb/validation"
"google.golang.org/protobuf/types/known/timestamppb"
)

func ToUserRegisterDataFromDesc(data *desc.ValidateRegistrationRequest) *model.UserRegisterData {
birthday := data.GetBitrhdate().AsTime()
ts := timestamppb.New(birthday)

return &model.UserRegisterData{
Email: data.GetEmail(),
Password: data.GetPassword(),
PasswordConfirm: data.GetPasswordConfirm(),
Sex: data.GetSex(),
Birthday: int(ts.Seconds),
}
}

func ToErrorsFromServ(data *model.ErrorResponse) *desc.ErrorMessage {
return &desc.ErrorMessage{
Code: data.Code,
Error: data.ErrorObj.Error(),
}
}
26 changes: 25 additions & 1 deletion validation-service/internal/app/api/validation/handler.go
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
package handler
package validation

import (
"context"

"github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/app/model"
desc "github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/pb/validation"
)

type ValidationService interface {
ValidateRegistration(ctx context.Context, userData *model.UserRegisterData) *model.ValidationResponse
}

type Implementation struct {
desc.UnimplementedValidationServer
ctx context.Context
validationService ValidationService
}

func NewImplementation(ctx context.Context, validationService ValidationService) *Implementation {
return &Implementation{
ctx: ctx,
validationService: validationService,
}
}
21 changes: 21 additions & 0 deletions validation-service/internal/app/api/validation/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package validation

import (
"context"

"github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/app/api/converter"
desc "github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/pb/validation"
)

func (i *Implementation) ValidateRegistration(ctx context.Context, req *desc.ValidateRegistrationRequest) (*desc.ValidationResponse, error) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот пока не знаю, как избавиться от контекста в аргументах функции. Типо это же из pb файла такой интерфейс
И вообще надо ли избавляться?

validData := i.validationService.ValidateRegistration(i.ctx, converter.ToUserRegisterDataFromDesc(req))
descErrors := make([]*desc.ErrorMessage, 0)
for _, errData := range validData.Errors {
descErrors = append(descErrors, converter.ToErrorsFromServ(&errData))
}

return &desc.ValidationResponse{
Success: validData.Success,
Errors: descErrors,
}, nil
}
48 changes: 47 additions & 1 deletion validation-service/internal/app/app.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
package main
package app

import (
"context"
"fmt"
"log"
"net"

"google.golang.org/grpc"
"google.golang.org/grpc/reflection"

"github.com/go-park-mail-ru/2024_2_GOATS/validation-service/config"
validationAPI "github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/app/api/validation"
validationService "github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/app/service/validation"
desc "github.com/go-park-mail-ru/2024_2_GOATS/validation-service/internal/pb/validation"
)

type App struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

хочу видеть сущность конфиг, где будет listener, он из ямлика будет читать адрес и порт. Рут контекст будет обогощаться этим конфигом, потом вы из него сможете достать конфиг где угодно

Copy link
Collaborator Author

@UnicoYal UnicoYal Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что-то типо?

type Config struct {
	listenerAddress string `yaml:"listener_address"`
	listenerPort    int    `yaml:"listener_port"`
}

type App struct {
	serverPort        int
	validationService validationAPI.ValidationService
	config            Config
}

В конструкторе App читаю конфиг из ямла и добавляю в контекст
Пока у меня контекст не прокидывается вниз, надо ли его передавать в конструкторы слоев?

validationService validationAPI.ValidationService
}

func New() (*App, context.Context, error) {
ctx, err := config.CreateConfigContext()
if err != nil {
log.Fatal("Failed to read config: %v", err)
}

return &App{
validationService: validationService.NewService(ctx),
}, ctx, nil
}

func (a *App) Run(ctx context.Context) {
cfg := config.GetConfigFromContext(ctx)
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", cfg.Listener.Port))
if err != nil {
log.Fatal("Failed to listen: %v", err)
}

s := grpc.NewServer()
reflection.Register(s)
desc.RegisterValidationServer(s, validationAPI.NewImplementation(ctx, a.validationService))

log.Printf("Server listening at %v:%d", cfg.Listener.Address, cfg.Listener.Port)

if err = s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
14 changes: 14 additions & 0 deletions validation-service/internal/app/errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package errors

import "errors"

var (
ErrInvalidEmailCode = "invalid_email"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А почему не сделать обычные ошибки через errors.New

ErrInvalidEmailText = errors.New("email is incorrect")
ErrInvalidPasswordCode = "invalid_password"
ErrInvalidPasswordText = errors.New("password is too short. The minimal len is 8")
ErrInvalidSexCode = "invalid_sex"
ErrInvalidSexText = errors.New("only male or female allowed")
ErrInvalidBirthdateCode = "invalid_birthdate"
ErrInvalidBirthdateText = errors.New("bithdate should be before current time")
)
18 changes: 18 additions & 0 deletions validation-service/internal/app/model/validation.go
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
package model

type UserRegisterData struct {
Email string
Password string
PasswordConfirm string
Sex int32
Birthday int
Starlexxx marked this conversation as resolved.
Show resolved Hide resolved
}

type ErrorResponse struct {
Code string
ErrorObj error
}

type ValidationResponse struct {
Success bool
Errors []ErrorResponse
}
Loading