Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
Пешков Дмитрий committed Sep 15, 2024
1 parent faa82a7 commit 5b7c173
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 8 deletions.
13 changes: 12 additions & 1 deletion cmd/gophermart/main.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
package main

import (
"context"
"github.com/spqrcor/gofermart/internal/config"
"github.com/spqrcor/gofermart/internal/db"
"github.com/spqrcor/gofermart/internal/logger"
"github.com/spqrcor/gofermart/internal/server"
"github.com/spqrcor/gofermart/internal/services"
"github.com/spqrcor/gofermart/internal/workers"
)

func main() {
mainCtx := context.Background()
config.Init()
logger.Init()
db.Init()

server.Start()
userService := services.NewUserService()
orderService := services.NewOrderService()
withdrawalService := services.NewWithdrawalService()

orderWorker := workers.NewOrderWorker(mainCtx, orderService)
orderWorker.Run()

server.Start(userService, orderService, withdrawalService)
}
55 changes: 55 additions & 0 deletions internal/client/order.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package client

import (
"bytes"
"encoding/json"
"errors"
"github.com/spqrcor/gofermart/internal/config"
"github.com/spqrcor/gofermart/internal/services"
"io"
"net/http"
)

func SendOrder(OrderNum string) error {
url := config.Cfg.AccrualSystemAddress + "/api/orders"
resp, err := http.Post(url, "application/json", bytes.NewReader([]byte(`{"order":`+OrderNum+`,"goods":[{"description":"Чайник Bork","price":7000}]}`)))
if err != nil {
return err
}
if resp.StatusCode != http.StatusAccepted {
return errors.New("Error " + resp.Status)
}
return nil
}

func CheckOrder(OrderNum string) (services.OrderFromAccrual, error) {
data := services.OrderFromAccrual{}
resp, err := http.Get(config.Cfg.AccrualSystemAddress + "/api/orders/" + OrderNum)
if err != nil {
return data, nil
}
if resp.StatusCode != http.StatusOK {
return data, errors.New("Error " + resp.Status)
}

bodyBytes, _ := io.ReadAll(resp.Body)
defer func() {
_ = resp.Body.Close()
}()
if err = json.Unmarshal(bodyBytes, &data); err != nil {
return data, err
}
return data, nil
}

func SetReward() error {
url := config.Cfg.AccrualSystemAddress + "/api/goods"
resp, err := http.Post(url, "application/json", bytes.NewReader([]byte(`{"match":"Bork","reward":10,"reward_type":"%"}`)))
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return errors.New("Error " + resp.Status)
}
return nil
}
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var Cfg = Config{
RunAddr: "localhost:8080",
LogLevel: zap.InfoLevel,
AccrualSystemAddress: "",
DatabaseURI: "postgres://postgres:Sp123456@localhost:5432/gofermart?sslmode=disable",
DatabaseURI: "",
}

func Init() {
Expand Down
4 changes: 4 additions & 0 deletions internal/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ func AddOrdersHandler(o services.OrderRepository) http.HandlerFunc {
return
}

//_, _ = client.CheckOrder(orderNum)

err = o.Add(req.Context(), orderNum)
if errors.Is(err, services.ErrOrderInvalidFormat) {
http.Error(res, err.Error(), http.StatusUnprocessableEntity)
Expand All @@ -79,6 +81,8 @@ func AddOrdersHandler(o services.OrderRepository) http.HandlerFunc {
return
}

//_ = client.SendOrder(orderNum)

res.WriteHeader(http.StatusAccepted)
}
}
Expand Down
7 changes: 1 addition & 6 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,13 @@ import (

var publicRoutes = []string{"/api/user/register", "/api/user/login"}

func Start() {
func Start(userService services.UserRepository, orderService services.OrderRepository, withdrawalService services.WithdrawalRepository) {
r := chi.NewRouter()
r.Use(authenticateMiddleware)
r.Use(loggerMiddleware)
r.Use(middleware.Compress(5, "application/json", "text/html"))
r.Use(getBodyMiddleware)

userService := services.NewUserService()
orderService := services.NewOrderService()
withdrawalService := services.NewWithdrawalService()

r.Post("/api/user/register", handlers.RegisterHandler(userService))
r.Post("/api/user/login", handlers.LoginHandler(userService))
r.Post("/api/user/orders", handlers.AddOrdersHandler(orderService))
Expand All @@ -34,6 +30,5 @@ func Start() {
r.HandleFunc(`/*`, func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusBadRequest)
})

log.Fatal(http.ListenAndServe(config.Cfg.RunAddr, r))
}
64 changes: 64 additions & 0 deletions internal/services/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ type Order struct {
UploadedAt string `json:"uploaded_at"`
}

type OrderFromAccrual struct {
Order string `json:"order"`
Status string `json:"status"`
Accrual int `json:"accrual,omitempty"`
}

var ErrOrderAnotherUserExists = fmt.Errorf("order another user exists")
var ErrOrderUserExists = fmt.Errorf("order user exists")
var ErrOrderInvalidFormat = fmt.Errorf("order invalid format")
Expand All @@ -27,6 +33,8 @@ var ErrOrdersNotFound = fmt.Errorf("orders not found")
type OrderRepository interface {
Add(ctx context.Context, orderNum string) error
GetAll(ctx context.Context) ([]Order, error)
GetUnComplete(ctx context.Context) ([]string, error)
ChangeStatus(ctx context.Context, data OrderFromAccrual) error
}

type OrderService struct{}
Expand Down Expand Up @@ -89,3 +97,59 @@ func (o *OrderService) GetAll(ctx context.Context) ([]Order, error) {
}
return orders, nil
}

func (o *OrderService) GetUnComplete(ctx context.Context) ([]string, error) {
var orders []string

childCtx, cancel := context.WithTimeout(ctx, time.Second*5)
defer cancel()

rows, err := db.Source.QueryContext(childCtx, "SELECT number FROM orders WHERE status IN ('NEW', 'PROCESSING') ORDER BY created_at")
if err != nil {
return nil, err
}
defer func() {
if err := rows.Close(); err != nil {
logger.Log.Error(err.Error())
}
if err := rows.Err(); err != nil {
logger.Log.Error(err.Error())
}
}()

for rows.Next() {
var orderNum string
if err = rows.Scan(&orderNum); err != nil {
return nil, err
}
orders = append(orders, orderNum)
}
return orders, nil
}

func (o *OrderService) ChangeStatus(ctx context.Context, data OrderFromAccrual) error {
childCtx, cancel := context.WithTimeout(ctx, time.Second*3)
defer cancel()

tx, err := db.Source.BeginTx(childCtx, nil)
if err != nil {
return err
}
_, err = tx.ExecContext(childCtx, "UPDATE orders SET status = $1, accrual =$2 WHERE number = $3", data.Status, data.Accrual, data.Order)
if err != nil {
_ = tx.Rollback()
return err
}
if data.Accrual > 0 {
_, err = tx.ExecContext(childCtx, "UPDATE users SET balance = balance + $1 WHERE id = (SELECT user_id FROM orders WHERE number = $2)", data.Accrual, data.Order)
if err != nil {
_ = tx.Rollback()
return err
}
}

if err = tx.Commit(); err != nil {
return err
}
return nil
}
57 changes: 57 additions & 0 deletions internal/workers/order.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package workers

import (
"context"
"github.com/spqrcor/gofermart/internal/client"
"github.com/spqrcor/gofermart/internal/logger"
"github.com/spqrcor/gofermart/internal/services"
"time"
)

type OrderWorker struct {
ctx context.Context
orderService services.OrderRepository
}

func NewOrderWorker(ctx context.Context, orderService services.OrderRepository) *OrderWorker {
return &OrderWorker{ctx: ctx, orderService: orderService}
}

func (w *OrderWorker) Send(orderNum string) error {
if err := client.SendOrder(orderNum); err != nil {
return err
}
data := services.OrderFromAccrual{Order: orderNum, Status: "PROCESSING"}
if err := w.orderService.ChangeStatus(w.ctx, data); err != nil {
return err
}
return nil
}

func (w *OrderWorker) Run() {
//_ = client.SetReward()
go w.doInterval()
}

func (w *OrderWorker) doInterval() {
for range time.Tick(time.Second * 5) {
logger.Log.Info("execute 5s")

orders, _ := w.orderService.GetUnComplete(w.ctx)
for _, order := range orders {
logger.Log.Info("before check")
result, err := client.CheckOrder(order)
if err != nil {
logger.Log.Info(err.Error())

} else {
err = w.orderService.ChangeStatus(w.ctx, result)
if err != nil {
logger.Log.Info(err.Error())

}
logger.Log.Info("after check")
}
}
}
}

0 comments on commit 5b7c173

Please sign in to comment.