Skip to content

Commit

Permalink
Server updated
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreiMartynenko committed Feb 29, 2024
1 parent c8a8ea9 commit f6e6b59
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 89 deletions.
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/Masterminds/squirrel v1.5.4
github.com/brianvoe/gofakeit v3.18.0+incompatible
github.com/jackc/pgx/v4 v4.18.1
github.com/jackc/pgx/v5 v5.5.3
google.golang.org/grpc v1.61.1
google.golang.org/protobuf v1.32.0
)
Expand All @@ -22,9 +23,9 @@ require (
github.com/jackc/puddle v1.3.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect
)
12 changes: 8 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,14 @@ 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.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0=
github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
github.com/jackc/pgx/v5 v5.5.3 h1:Ces6/M3wbDXYpM8JyyPD57ivTtJACFZJd885pdIaV2s=
github.com/jackc/pgx/v5 v5.5.3/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
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.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -145,8 +148,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
Expand All @@ -162,6 +165,7 @@ golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand All @@ -177,8 +181,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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=
Expand Down
161 changes: 108 additions & 53 deletions grpc/cmd/grpc_server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ package main

import (
"context"
"database/sql"
"errors"
"fmt"
"log"
"math/rand"
"net"
"time"

"github.com/AndreiMartynenko/auth/grpc/pkg/auth_v1"
"github.com/brianvoe/gofakeit"
"github.com/jackc/pgx/v5"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/reflection"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)

Expand All @@ -27,96 +31,147 @@ This helps in keeping your code organized and ensures that you fulfill
the requirements of the gRPC service.
*/

const grpcPort = 50051
const (
dbDSN = "host=localhost port=54321 dbname=auth user=auth-user password=auth-password sslmode=disable"
grpcPort = 50051
dbTimeout = time.Second * 3
)

type server struct {
db *sql.DB
auth_v1.UnimplementedUserAPIServicesServer
}

func main() {
log.Println("Starting authentication service")

ctx := context.Background()

// Create a connection to the database
con, err := pgx.Connect(ctx, dbDSN)
if err != nil {
log.Fatalf("failed to connect to database: %v", err)
}
defer con.Close(ctx)

lis, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}

srv := grpc.NewServer()

reflection.Register(srv)
auth_v1.RegisterUserAPIServicesServer(srv, &server{})

log.Printf("server listening at %v", lis.Addr())

if err = srv.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}

}

// Create
func (srv *server) Create(ctx context.Context, req *auth_v1.CreateUserRequest) (*auth_v1.CreateUserResponse, error) {
ctx, cancel := context.WithTimeout(ctx, dbTimeout)
defer cancel()

// Insert the new user into the database
res := srv.db.QueryRowContext(ctx, "INSERT INTO users (name, email, password, password_confirmed, role) VALUES ($1, $2, $3, $4, $5) RETURNING id", req.Name, req.Email, req.Password, req.PasswordConfirmed, req.Role)
// Get the ID of the newly created user
var id int64
err := res.Scan(&id)
if err != nil {
return nil, fmt.Errorf("failed to get id of newly created user: %v", err)
}

//For testing purposes
id := generateUniqueID()
// if res.RowsAffected() > 0 {
// id = res.RowsAffected()
// } else {

return &auth_v1.CreateUserResponse{
//Id: gofakeit.Int64(),
Id: id,
}, nil

}

// Get
func (srv *server) Get(ctx context.Context, req *auth_v1.GetUserRequest) (*auth_v1.GetUserResponse, error) {
log.Printf("User id %d", req.GetId())
ctx, cancel := context.WithTimeout(ctx, dbTimeout)
defer cancel()

// Query the user from the database
row := srv.db.QueryRowContext(ctx, "SELECT name, email, role, created_at, updated_at FROM users WHERE id = $1", req.GetId())

// Scan the result into variables
var name string
var email string
var role int32
var createdAt time.Time
var updatedAt time.Time
err := row.Scan(&name, &email, &role, &createdAt, &updatedAt)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, status.Errorf(codes.NotFound, "user with id %d not found", req.GetId())
}
return nil, fmt.Errorf("failed to query user: %v", err)
}

return &auth_v1.GetUserResponse{
Id: req.GetId(),
// Name: gofakeit.Name(),
Name: "NEW NAME",
Email: gofakeit.Email(),
Role: auth_v1.UserRole_USER,
CreatedAt: timestamppb.New(gofakeit.Date()),
UpdatedAt: timestamppb.New(gofakeit.Date()),
Id: req.GetId(),
Name: name,
Email: email,
Role: auth_v1.UserRole(role),
CreatedAt: timestamppb.New(createdAt),
UpdatedAt: timestamppb.New(updatedAt),
}, nil
}

// Update
func (srv *server) Update(ctx context.Context, req *auth_v1.UpdateUserRequest) (*auth_v1.UpdateUserResponse, error) {
ctx, cancel := context.WithTimeout(ctx, dbTimeout)
defer cancel()

// Update the user in the database
result, err := srv.db.ExecContext(ctx, "UPDATE users SET name = $1, email = $2, role = $3 WHERE id = $4", req.GetName().GetValue(), req.GetEmail().GetValue(), req.GetRole(), req.GetId())
if err != nil {
return nil, fmt.Errorf("failed to update user: %v", err)
}

updatedName := gofakeit.Name()
updatedEmail := gofakeit.Email()
updatedRole := auth_v1.UserRole(gofakeit.Number(0, 1))
rowsAffected, err := result.RowsAffected()
if err != nil {
return nil, fmt.Errorf("failed to get rows affected: %v", err)
}
if rowsAffected == 0 {
return nil, status.Errorf(codes.NotFound, "user with id %d not found", req.GetId())
}

log.Printf("Updating user with ID %d", req.GetId())
log.Printf("New Name: %s, New Email: %s, New Role: %v", updatedName, updatedEmail, updatedRole)
log.Printf("New Name: %s, New Email: %s, New Role: %v", req.GetName().GetValue(), req.GetEmail().GetValue(), req.GetRole())

return &auth_v1.UpdateUserResponse{}, nil

}

// Delete
func (srv *server) Delete(ctx context.Context, req *auth_v1.DeleteUserRequest) (*auth_v1.DeleteUserResponse, error) {
ctx, cancel := context.WithTimeout(ctx, dbTimeout)
defer cancel()

err := deleteUserByID(req.GetId())
// Delete the user from the database
result, err := srv.db.ExecContext(ctx, "DELETE FROM users WHERE id = $1", req.GetId())
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to delete user: %v", err)
}
return &auth_v1.DeleteUserResponse{}, nil

}

func deleteUserByID(userID int64) error {
//Example
return nil
}

func generateUniqueID() int64 {

return rand.Int63n(1000)
}

func main() {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
rowsAffected, err := result.RowsAffected()
if err != nil {
log.Fatalf("failed to listen: %v", err)
return nil, fmt.Errorf("failed to get rows affected: %v", err)
}

srv := grpc.NewServer()
/*
Reflection in this context allows gRPC clients to query information
about the gRPC server's services dynamically at runtime.
It enables tools like gRPC's command-line interface (grpc_cli)
and gRPC's web-based GUI (grpcui) to inspect the server's
services and make RPC calls without needing to know
the specifics of each service beforehand.
*/
reflection.Register(srv)
auth_v1.RegisterUserAPIServicesServer(srv, &server{})

log.Printf("server listening at %v", lis.Addr())

if err = srv.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
if rowsAffected == 0 {
return nil, status.Errorf(codes.NotFound, "user with id %d not found", req.GetId())
}

return &auth_v1.DeleteUserResponse{}, nil
}
14 changes: 7 additions & 7 deletions postgres/cmd/raw_query/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

const (
dbDSN = "host=localhost port=54321 dbname=note user=note-user password=note-password sslmode=disable"
dbDSN = "host=localhost port=54321 dbname=auth user=auth-user password=auth-password sslmode=disable"
)

func main() {
Expand All @@ -25,17 +25,17 @@ func main() {
defer con.Close(ctx)

// Making a request to insert a record into the note table
res, err := con.Exec(ctx, "INSERT INTO note (title, body) VALUES ($1, $2)", gofakeit.City(), gofakeit.Address().Street)
res, err := con.Exec(ctx, "INSERT INTO auth (title, body) VALUES ($1, $2)", gofakeit.City(), gofakeit.Address().Street)
if err != nil {
log.Fatalf("failed to insert note: %v", err)
log.Fatalf("failed to insert auth: %v", err)
}

log.Printf("inserted %d rows", res.RowsAffected())

// We make a request to select records from the note table
rows, err := con.Query(ctx, "SELECT id, title, body, created_at, updated_at FROM note")
// We make a request to select records from the auth table
rows, err := con.Query(ctx, "SELECT id, title, body, created_at, updated_at FROM user")
if err != nil {
log.Fatalf("failed to select notes: %v", err)
log.Fatalf("failed to select auth_users: %v", err)
}
defer rows.Close()

Expand All @@ -47,7 +47,7 @@ func main() {

err = rows.Scan(&id, &title, &body, &createdAt, &updatedAt)
if err != nil {
log.Fatalf("failed to scan note: %v", err)
log.Fatalf("failed to scan auth: %v", err)
}

log.Printf("id: %d, title: %s, body: %s, created_at: %v, updated_at: %v\n", id, title, body, createdAt, updatedAt)
Expand Down
12 changes: 12 additions & 0 deletions postgres/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@ services:
# pg - name to coonect db from other services
pg:
image: postgres:14-alpine3.17

# sets environment variables needed for the PostgreSQL instance to run correctly.
# These are environment variable placeholders. They will be replaced by the actual
# values defined in your environment variables or in a .env file.
# When you run your Docker Compose stack, Docker will substitute ${PG_DATABASE_NAME},
# ${PG_USER}, and ${PG_PASSWORD} with the values specified in
# your environment or in an .env file.
environment:
- "POSTGRES_DB=${PG_DATABASE_NAME}"
- "POSTGRES_USER=${PG_USER}"
- "POSTGRES_PASSWORD=${PG_PASSWORD}"

# Our Docker container will be accessible on port .env 54321 of your host,
# and Docker will redirect requests from this port to port 5432
# inside the container, where the PostgreSQL service is expected
# to be running.
ports:
- "${PG_PORT}:5432"

# Volumes Mounts the postgres_volume volume to the /var/lib/postgresql/data
# directory within the container. This ensures that the data generated by
# the PostgreSQL container is persisted even if the container is stopped or removed.
Expand Down
15 changes: 12 additions & 3 deletions postgres/migrations/20240219145029_migrations_bla_bla.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
-- +goose Up
-- +goose StatementBegin
SELECT 'up SQL query';
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
password_confirmed TEXT NOT NULL,
role INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
SELECT 'down SQL query';
-- +goose StatementEnd
DROP TABLE users;
-- +goose StatementEnd

This file was deleted.

9 changes: 0 additions & 9 deletions postgres/migrations/20240220152524_add_user_table.sql

This file was deleted.

0 comments on commit f6e6b59

Please sign in to comment.