Initial commit
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"datarush/internal/lms/domain"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func mapError(err error) error {
|
||||
if errors.Is(err, domain.ErrOrderNotFound) {
|
||||
return status.Error(codes.NotFound, err.Error())
|
||||
}
|
||||
if errors.Is(err, domain.ErrOrderAlreadyExist) {
|
||||
return status.Error(codes.AlreadyExists, err.Error())
|
||||
}
|
||||
if errors.Is(err, domain.ErrInvalidOrderData) || errors.Is(err, domain.ErrInvalidID) {
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
log.Printf("internal server error: %v", err)
|
||||
return status.Error(codes.Internal, "internal server error")
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"datarush/internal/lms/domain"
|
||||
"datarush/internal/lms/service"
|
||||
pb "datarush/pkg/api/order"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type OrderHandler struct {
|
||||
pb.UnimplementedOrderServiceServer
|
||||
|
||||
service *service.OrderService
|
||||
}
|
||||
|
||||
func NewOrderHandler(service *service.OrderService) *OrderHandler {
|
||||
return &OrderHandler{
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
func mapDomainStructToHandler(order *domain.Order) *pb.Order {
|
||||
return &pb.Order{
|
||||
Id: order.ID.String(),
|
||||
Item: order.Item,
|
||||
Quantity: order.Quantity,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *OrderHandler) CreateOrder(
|
||||
ctx context.Context,
|
||||
req *pb.CreateOrderRequest,
|
||||
) (*pb.CreateOrderResponse, error) {
|
||||
order, err := h.service.Create(ctx, req.GetItem(), req.GetQuantity())
|
||||
if err != nil {
|
||||
return nil, mapError(err)
|
||||
}
|
||||
|
||||
return &pb.CreateOrderResponse{Id: order.ID.String()}, nil
|
||||
}
|
||||
|
||||
func (h *OrderHandler) GetOrder(ctx context.Context, req *pb.GetOrderRequest) (*pb.GetOrderResponse, error) {
|
||||
parsedID, err := uuid.Parse(req.GetId())
|
||||
if err != nil {
|
||||
return nil, domain.ErrInvalidID
|
||||
}
|
||||
|
||||
order, err := h.service.Get(ctx, parsedID)
|
||||
if err != nil {
|
||||
return nil, mapError(err)
|
||||
}
|
||||
|
||||
return &pb.GetOrderResponse{Order: mapDomainStructToHandler(order)}, nil
|
||||
}
|
||||
|
||||
func (h *OrderHandler) UpdateOrder(
|
||||
ctx context.Context,
|
||||
req *pb.UpdateOrderRequest,
|
||||
) (*pb.UpdateOrderResponse, error) {
|
||||
parsedID, err := uuid.Parse(req.GetId())
|
||||
if err != nil {
|
||||
return nil, mapError(domain.ErrInvalidID)
|
||||
}
|
||||
|
||||
order, err := h.service.Update(ctx, parsedID, req.GetItem(), req.GetQuantity())
|
||||
if err != nil {
|
||||
return nil, mapError(err)
|
||||
}
|
||||
|
||||
return &pb.UpdateOrderResponse{Order: mapDomainStructToHandler(order)}, nil
|
||||
}
|
||||
|
||||
func (h *OrderHandler) DeleteOrder(
|
||||
ctx context.Context,
|
||||
req *pb.DeleteOrderRequest,
|
||||
) (*pb.DeleteOrderResponse, error) {
|
||||
parsedID, err := uuid.Parse(req.GetId())
|
||||
if err != nil {
|
||||
return nil, domain.ErrInvalidID
|
||||
}
|
||||
|
||||
err = h.service.Delete(ctx, parsedID)
|
||||
if err != nil {
|
||||
return nil, mapError(err)
|
||||
}
|
||||
|
||||
return &pb.DeleteOrderResponse{Success: true}, nil
|
||||
}
|
||||
|
||||
func (h *OrderHandler) ListOrders(
|
||||
ctx context.Context,
|
||||
_ *pb.ListOrdersRequest,
|
||||
) (*pb.ListOrdersResponse, error) {
|
||||
domainOrders, err := h.service.List(ctx)
|
||||
if err != nil {
|
||||
return nil, mapError(err)
|
||||
}
|
||||
|
||||
orders := make([]*pb.Order, 0, len(domainOrders))
|
||||
for _, o := range domainOrders {
|
||||
orders = append(orders, mapDomainStructToHandler(o))
|
||||
}
|
||||
|
||||
return &pb.ListOrdersResponse{Orders: orders}, nil
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
type HealthHandler struct {
|
||||
DB *sqlx.DB
|
||||
Redis *redis.Client
|
||||
}
|
||||
|
||||
func NewHealthHandler(db *sqlx.DB, redisDB *redis.Client) *HealthHandler {
|
||||
return &HealthHandler{
|
||||
DB: db,
|
||||
Redis: redisDB,
|
||||
}
|
||||
}
|
||||
|
||||
type HealthResponse struct {
|
||||
Status string `json:"status"`
|
||||
Details map[string]string `json:"details"`
|
||||
}
|
||||
|
||||
func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
details := map[string]string{}
|
||||
|
||||
if err := h.DB.PingContext(ctx); err != nil {
|
||||
details["postgres"] = "unhealthy: " + err.Error()
|
||||
} else {
|
||||
details["postgres"] = "ok"
|
||||
}
|
||||
|
||||
if err := h.Redis.Ping(ctx).Err(); err != nil {
|
||||
details["redis"] = "unhealthy: " + err.Error()
|
||||
} else {
|
||||
details["redis"] = "ok"
|
||||
}
|
||||
|
||||
status := "ok"
|
||||
for _, v := range details {
|
||||
if v != "ok" {
|
||||
status = "unhealthy"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
resp := HealthResponse{Status: status, Details: details}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if status != "ok" {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
Reference in New Issue
Block a user