feat: added API gateway

This commit is contained in:
ITQ
2025-12-17 11:00:50 +03:00
parent daa8c24482
commit 340ae43d22
30 changed files with 2838 additions and 3 deletions
@@ -0,0 +1,49 @@
package grpc_client
import (
"context"
"fmt"
"google.golang.org/grpc"
pb "datarush/pkg/api/achievements"
)
type AchievementsClient struct {
client pb.AchievementsServiceClient
conn *grpc.ClientConn
}
func NewAchievementsClient(ctx context.Context, address string, factory *ClientFactory) (*AchievementsClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create achievements client: %w", err)
}
return &AchievementsClient{client: pb.NewAchievementsServiceClient(conn), conn: conn}, nil
}
func (c *AchievementsClient) GetAchievement(ctx context.Context, achievementID string) (*pb.Achievement, error) {
req := &pb.GetAchievementRequest{Id: achievementID}
resp, err := c.client.GetAchievement(ctx, req)
if err != nil {
return nil, fmt.Errorf("get achievement failed: %w", err)
}
return resp, nil
}
func (c *AchievementsClient) ListAchievements(ctx context.Context) ([]*pb.Achievement, error) {
resp, err := c.client.ListAchievements(ctx, nil)
if err != nil {
return nil, fmt.Errorf("list achievements failed: %w", err)
}
return resp.Achievements, nil
}
func (c *AchievementsClient) GetUserAchievements(ctx context.Context, userID string) ([]*pb.AchievementUser, error) {
req := &pb.GetUserAchievementsRequest{UserId: userID}
resp, err := c.client.GetUserAchievements(ctx, req)
if err != nil {
return nil, fmt.Errorf("get user achievements failed: %w", err)
}
return resp.UserAchievements, nil
}
+69
View File
@@ -0,0 +1,69 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/auth"
"google.golang.org/grpc"
)
type AuthClient struct {
client pb.AuthServiceClient
conn *grpc.ClientConn
}
func NewAuthClient(ctx context.Context, address string, factory *ClientFactory) (*AuthClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create auth client: %w", err)
}
return &AuthClient{
client: pb.NewAuthServiceClient(conn),
conn: conn,
}, nil
}
func (c *AuthClient) SignUp(ctx context.Context, email, username, password string) (string, error) {
req := &pb.SignUpRequest{
Email: email,
Username: username,
Password: password,
}
resp, err := c.client.SignUp(ctx, req)
if err != nil {
return "", fmt.Errorf("sign up failed: %w", err)
}
return resp.Token, nil
}
func (c *AuthClient) SignIn(ctx context.Context, email, password string) (string, error) {
req := &pb.SignInRequest{
Email: email,
Password: password,
}
resp, err := c.client.SignIn(ctx, req)
if err != nil {
return "", fmt.Errorf("sign in failed: %w", err)
}
return resp.Token, nil
}
func (c *AuthClient) ValidateToken(ctx context.Context, token string) (string, error) {
req := &pb.ValidateTokenRequest{
Token: token,
}
resp, err := c.client.ValidateToken(ctx, req)
if err != nil {
return "", fmt.Errorf("token validation failed: %w", err)
}
return resp.UserId, nil
}
+49
View File
@@ -0,0 +1,49 @@
package grpc_client
import (
"context"
"fmt"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
type ClientFactory struct {
connections map[string]*grpc.ClientConn
}
func NewClientFactory() *ClientFactory {
return &ClientFactory{
connections: make(map[string]*grpc.ClientConn),
}
}
func (f *ClientFactory) GetConnection(ctx context.Context, address string) (*grpc.ClientConn, error) {
if conn, ok := f.connections[address]; ok {
return conn, nil
}
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, address,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock(),
)
if err != nil {
return nil, fmt.Errorf("failed to connect to %s: %w", address, err)
}
f.connections[address] = conn
return conn, nil
}
func (f *ClientFactory) Close() error {
for addr, conn := range f.connections {
if err := conn.Close(); err != nil {
return fmt.Errorf("failed to close connection to %s: %w", addr, err)
}
}
return nil
}
@@ -0,0 +1,98 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/competition"
"google.golang.org/grpc"
)
type CompetitionClient struct {
client pb.CompetitionServiceClient
conn *grpc.ClientConn
}
func NewCompetitionClient(ctx context.Context, address string, factory *ClientFactory) (*CompetitionClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create competition client: %w", err)
}
return &CompetitionClient{
client: pb.NewCompetitionServiceClient(conn),
conn: conn,
}, nil
}
func (c *CompetitionClient) CreateCompetition(
ctx context.Context,
competition *pb.Competition,
) (*pb.Competition, error) {
resp, err := c.client.CreateCompetition(ctx, competition)
if err != nil {
return nil, fmt.Errorf("create competition failed: %w", err)
}
return resp, nil
}
func (c *CompetitionClient) GetCompetition(ctx context.Context, competitionID string) (*pb.Competition, error) {
req := &pb.GetCompetitionRequest{
CompetitionId: competitionID,
}
resp, err := c.client.GetCompetition(ctx, req)
if err != nil {
return nil, fmt.Errorf("get competition failed: %w", err)
}
return resp, nil
}
func (c *CompetitionClient) EditCompetition(ctx context.Context, competition *pb.Competition) (*pb.Competition, error) {
resp, err := c.client.EditCompetition(ctx, competition)
if err != nil {
return nil, fmt.Errorf("edit competition failed: %w", err)
}
return resp, nil
}
func (c *CompetitionClient) DeleteCompetition(ctx context.Context, competitionID string) error {
req := &pb.DeleteCompetitionRequest{
CompetitionId: competitionID,
}
_, err := c.client.DeleteCompetition(ctx, req)
if err != nil {
return fmt.Errorf("delete competition failed: %w", err)
}
return nil
}
func (c *CompetitionClient) ListCompetitions(
ctx context.Context,
req *pb.ListCompetitionsRequest,
) (*pb.ListCompetitionsResponse, error) {
resp, err := c.client.ListCompetitions(ctx, req)
if err != nil {
return nil, fmt.Errorf("list competitions failed: %w", err)
}
return resp, nil
}
func (c *CompetitionClient) ChangeCompetitionState(
ctx context.Context,
competitionID string,
state pb.CompetitionState,
) (*pb.Competition, error) {
req := &pb.ChangeCompetitionStateRequest{
CompetitionId: competitionID,
State: state,
}
resp, err := c.client.ChangeCompetitionState(ctx, req)
if err != nil {
return nil, fmt.Errorf("change competition state failed: %w", err)
}
return resp, nil
}
+58
View File
@@ -0,0 +1,58 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/results"
"google.golang.org/grpc"
)
type ResultsClient struct {
client pb.ResultsServiceClient
conn *grpc.ClientConn
}
func NewResultsClient(ctx context.Context, address string, factory *ClientFactory) (*ResultsClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create results client: %w", err)
}
return &ResultsClient{client: pb.NewResultsServiceClient(conn), conn: conn}, nil
}
func (c *ResultsClient) GetCompetitionResults(
ctx context.Context,
req *pb.GetCompetitionResultsRequest,
) (*pb.GetCompetitionResultsResponse, error) {
resp, err := c.client.GetCompetitionResults(ctx, req)
if err != nil {
return nil, fmt.Errorf("get competition results failed: %w", err)
}
return resp, nil
}
func (c *ResultsClient) GetUserCompetitionResults(
ctx context.Context,
competitionID, userID string,
) (*pb.UserResult, error) {
req := &pb.GetUserCompetitionResultsRequest{
CompetitionId: competitionID,
UserId: userID,
}
resp, err := c.client.GetUserCompetitionResults(ctx, req)
if err != nil {
return nil, fmt.Errorf("get user competition results failed: %w", err)
}
return resp.Result, nil
}
func (c *ResultsClient) RecalculateResults(ctx context.Context, competitionID string) error {
req := &pb.RecalculateResultsRequest{CompetitionId: competitionID}
_, err := c.client.RecalculateResults(ctx, req)
if err != nil {
return fmt.Errorf("recalculate results failed: %w", err)
}
return nil
}
+81
View File
@@ -0,0 +1,81 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/review"
"google.golang.org/grpc"
)
type ReviewClient struct {
client pb.ReviewServiceClient
conn *grpc.ClientConn
}
func NewReviewClient(ctx context.Context, address string, factory *ClientFactory) (*ReviewClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create review client: %w", err)
}
return &ReviewClient{client: pb.NewReviewServiceClient(conn), conn: conn}, nil
}
func (c *ReviewClient) ValidateReviewToken(ctx context.Context, token string) (*pb.ValidateReviewTokenResponse, error) {
req := &pb.ValidateReviewTokenRequest{Token: token}
resp, err := c.client.ValidateReviewToken(ctx, req)
if err != nil {
return nil, fmt.Errorf("validate review token failed: %w", err)
}
return resp, nil
}
func (c *ReviewClient) ListSubmissionsForReview(
ctx context.Context,
req *pb.ListSubmissionsForReviewRequest,
) (*pb.ListSubmissionsForReviewResponse, error) {
resp, err := c.client.ListSubmissionsForReview(ctx, req)
if err != nil {
return nil, fmt.Errorf("list submissions for review failed: %w", err)
}
return resp, nil
}
func (c *ReviewClient) GetSubmissionForReview(
ctx context.Context,
token, submissionID string,
) (*pb.SubmissionForReview, error) {
req := &pb.GetSubmissionForReviewRequest{
Token: token,
SubmissionId: submissionID,
}
resp, err := c.client.GetSubmissionForReview(ctx, req)
if err != nil {
return nil, fmt.Errorf("get submission for review failed: %w", err)
}
return resp, nil
}
func (c *ReviewClient) EvaluateSubmission(
ctx context.Context,
req *pb.EvaluateSubmissionRequest,
) (*pb.EvaluateSubmissionResponse, error) {
resp, err := c.client.EvaluateSubmission(ctx, req)
if err != nil {
return nil, fmt.Errorf("evaluate submission failed: %w", err)
}
return resp, nil
}
func (c *ReviewClient) ReleaseSubmission(ctx context.Context, token, submissionID string) error {
req := &pb.ReleaseSubmissionRequest{
Token: token,
SubmissionId: submissionID,
}
_, err := c.client.ReleaseSubmission(ctx, req)
if err != nil {
return fmt.Errorf("release submission failed: %w", err)
}
return nil
}
@@ -0,0 +1,85 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/submission"
"google.golang.org/grpc"
)
type SubmissionClient struct {
client pb.SubmissionServiceClient
conn *grpc.ClientConn
}
func NewSubmissionClient(ctx context.Context, address string, factory *ClientFactory) (*SubmissionClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create submission client: %w", err)
}
return &SubmissionClient{
client: pb.NewSubmissionServiceClient(conn),
conn: conn,
}, nil
}
func (c *SubmissionClient) SubmitTask(
ctx context.Context,
userID, competitionID, taskID, fileURL string,
) (*pb.Submission, error) {
req := &pb.SubmitTaskRequest{
UserId: userID,
CompetitionId: competitionID,
TaskId: taskID,
FileUrl: fileURL,
}
resp, err := c.client.SubmitTask(ctx, req)
if err != nil {
return nil, fmt.Errorf("submit task failed: %w", err)
}
return resp, nil
}
func (c *SubmissionClient) GetSubmissionsHistory(
ctx context.Context,
userID, competitionID, taskID string,
) ([]*pb.Submission, error) {
req := &pb.GetSubmissionsHistoryRequest{
UserId: userID,
CompetitionId: competitionID,
TaskId: taskID,
}
resp, err := c.client.GetSubmissionsHistory(ctx, req)
if err != nil {
return nil, fmt.Errorf("get submissions history failed: %w", err)
}
return resp.Submissions, nil
}
func (c *SubmissionClient) GetSubmission(ctx context.Context, submissionID string) (*pb.Submission, error) {
req := &pb.GetSubmissionRequest{
SubmissionId: submissionID,
}
resp, err := c.client.GetSubmission(ctx, req)
if err != nil {
return nil, fmt.Errorf("get submission failed: %w", err)
}
return resp, nil
}
func (c *SubmissionClient) ListSubmissions(
ctx context.Context,
req *pb.ListSubmissionsRequest,
) (*pb.ListSubmissionsResponse, error) {
resp, err := c.client.ListSubmissions(ctx, req)
if err != nil {
return nil, fmt.Errorf("list submissions failed: %w", err)
}
return resp, nil
}
+82
View File
@@ -0,0 +1,82 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/task"
"google.golang.org/grpc"
)
type TaskClient struct {
client pb.TaskServiceClient
conn *grpc.ClientConn
}
func NewTaskClient(ctx context.Context, address string, factory *ClientFactory) (*TaskClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create task client: %w", err)
}
return &TaskClient{client: pb.NewTaskServiceClient(conn), conn: conn}, nil
}
func (c *TaskClient) CreateTask(ctx context.Context, task *pb.Task) (*pb.Task, error) {
resp, err := c.client.CreateTask(ctx, task)
if err != nil {
return nil, fmt.Errorf("create task failed: %w", err)
}
return resp, nil
}
func (c *TaskClient) GetTask(ctx context.Context, taskID string) (*pb.Task, error) {
req := &pb.GetTaskRequest{TaskId: taskID}
resp, err := c.client.GetTask(ctx, req)
if err != nil {
return nil, fmt.Errorf("get task failed: %w", err)
}
return resp, nil
}
func (c *TaskClient) EditTask(ctx context.Context, task *pb.Task) (*pb.Task, error) {
resp, err := c.client.EditTask(ctx, task)
if err != nil {
return nil, fmt.Errorf("edit task failed: %w", err)
}
return resp, nil
}
func (c *TaskClient) DeleteTask(ctx context.Context, taskID string) error {
req := &pb.DeleteTaskRequest{TaskId: taskID}
_, err := c.client.DeleteTask(ctx, req)
if err != nil {
return fmt.Errorf("delete task failed: %w", err)
}
return nil
}
func (c *TaskClient) ListCompetitionTasks(ctx context.Context, competitionID string) ([]*pb.Task, error) {
req := &pb.ListCompetitionTasksRequest{CompetitionId: competitionID}
resp, err := c.client.ListCompetitionTasks(ctx, req)
if err != nil {
return nil, fmt.Errorf("list tasks failed: %w", err)
}
return resp.Tasks, nil
}
func (c *TaskClient) GetTaskAttachments(
ctx context.Context,
taskID string,
showPrivate bool,
) ([]*pb.TaskAttachment, error) {
req := &pb.GetTaskAttachmentsRequest{
TaskId: taskID,
ShowPrivate: &showPrivate,
}
resp, err := c.client.GetTaskAttachments(ctx, req)
if err != nil {
return nil, fmt.Errorf("get task attachments failed: %w", err)
}
return resp.Attachments, nil
}
+79
View File
@@ -0,0 +1,79 @@
package grpc_client
import (
"context"
"fmt"
pb "datarush/pkg/api/user"
"google.golang.org/grpc"
)
type UserClient struct {
client pb.UserServiceClient
conn *grpc.ClientConn
}
func NewUserClient(ctx context.Context, address string, factory *ClientFactory) (*UserClient, error) {
conn, err := factory.GetConnection(ctx, address)
if err != nil {
return nil, fmt.Errorf("failed to create user client: %w", err)
}
return &UserClient{
client: pb.NewUserServiceClient(conn),
conn: conn,
}, nil
}
func (c *UserClient) GetProfile(ctx context.Context, userID string) (*pb.User, error) {
req := &pb.GetProfileRequest{
UserId: userID,
}
resp, err := c.client.GetProfile(ctx, req)
if err != nil {
return nil, fmt.Errorf("get profile failed: %w", err)
}
return resp, nil
}
func (c *UserClient) RegisterForCompetition(ctx context.Context, competitionID string) error {
req := &pb.RegisterForCompetitionRequest{
CompetitionId: competitionID,
}
_, err := c.client.RegisterForCompetition(ctx, req)
if err != nil {
return fmt.Errorf("register for competition failed: %w", err)
}
return nil
}
func (c *UserClient) UnregisterFromCompetition(ctx context.Context, competitionID string) error {
req := &pb.UnregisterFromCompetitionRequest{
CompetitionId: competitionID,
}
_, err := c.client.UnregisterFromCompetition(ctx, req)
if err != nil {
return fmt.Errorf("unregister from competition failed: %w", err)
}
return nil
}
func (c *UserClient) ListUserCompetitions(ctx context.Context, userID string) ([]string, error) {
req := &pb.ListUserCompetitionsRequest{
UserId: userID,
}
resp, err := c.client.ListUserCompetitions(ctx, req)
if err != nil {
return nil, fmt.Errorf("list user competitions failed: %w", err)
}
return resp.CompetitionIds, nil
}