Merge pull request #6 from navi-ppl/TP-55555/projectHandler

TP-55555 | Releases and exception handler
This commit is contained in:
Varnit Goyal
2024-07-29 15:59:36 +05:30
committed by GitHub
13 changed files with 264 additions and 33 deletions

View File

@@ -9,3 +9,8 @@ func InitProjectRepository(dbClient *gorm.DB) *gorm.DB {
dbClient.AutoMigrate(&db.Project{})
return dbClient
}
func InitReleaseRepository(dbClient *gorm.DB) *gorm.DB {
dbClient.AutoMigrate(&db.Release{})
return dbClient
}

View File

@@ -24,18 +24,23 @@ type Dependencies struct {
}
type Service struct {
DocumentService *document.HttpClient
ProjectService *service.ProjectCreator
DocumentService *document.HttpClient
ProjectService *service.ProjectCreator
ReleaseService *service.ReleaseService
ExceptionService *service.ExceptionService
S3Client *aws.Actions
// Add your service here
}
type Handler struct {
ProjectHandler *handler.ProjectHandler
ProjectHandler *handler.ProjectHandler
ReleaseHandler *handler.ReleasesHandler
ExceptionHandler *handler.ExceptionHandler
}
type Repositories struct {
ProjectRepository *gorm.DB
ReleaseRepository *gorm.DB
}
func InitDependencies() *Dependencies {
@@ -48,8 +53,11 @@ func InitDependencies() *Dependencies {
documentServiceClient := document.NewDocumentServiceHttpClient(httpClient, logger, configs.GetDocumentServiceHttpClientConfigs())
projectServiceClient := service.NewProjectCreator(logger, dbClient, s3Client, kafkaProducer)
services := initServices(documentServiceClient, projectServiceClient)
handlers := initHandlers(projectServiceClient)
releaseServiceClient := service.NewReleaseService(logger, dbClient)
exceptionServiceClient := service.NewExceptionService(logger, dbClient, kafkaProducer)
services := initServices(documentServiceClient, projectServiceClient, releaseServiceClient, exceptionServiceClient)
handlers := initHandlers(projectServiceClient, releaseServiceClient, exceptionServiceClient)
return &Dependencies{
Service: services,
DBClient: dbClient,
@@ -59,23 +67,30 @@ func InitDependencies() *Dependencies {
}
}
func initServices(documentService *document.HttpClient, projectService *service.ProjectCreator) *Service {
func initServices(documentService *document.HttpClient, projectService *service.ProjectCreator, releaseService *service.ReleaseService, exceptionService *service.ExceptionService) *Service {
return &Service{
DocumentService: documentService,
ProjectService: projectService,
DocumentService: documentService,
ProjectService: projectService,
ReleaseService: releaseService,
ExceptionService: exceptionService,
}
}
func initRepositories(dbClient *gorm.DB) *Repositories {
return &Repositories{
ProjectRepository: database.InitProjectRepository(dbClient),
ReleaseRepository: database.InitReleaseRepository(dbClient),
}
}
func initHandlers(projectService *service.ProjectCreator) *Handler {
func initHandlers(projectService *service.ProjectCreator, releaseService *service.ReleaseService, exceotionService *service.ExceptionService) *Handler {
projectHandler := handler.NewProjectHandler(projectService)
releaseHandler := handler.NewReleaseHandler(releaseService)
exceptionHandler := handler.NewExceptionHandler(exceotionService)
return &Handler{
ProjectHandler: projectHandler,
ProjectHandler: projectHandler,
ReleaseHandler: releaseHandler,
ExceptionHandler: exceptionHandler,
}
}

View File

@@ -0,0 +1,20 @@
package handler
import (
"cybertron/service"
"github.com/gin-gonic/gin"
)
type ExceptionHandler struct {
exceptionService *service.ExceptionService
}
func (h *ExceptionHandler) CatchErrors(c *gin.Context) {
h.exceptionService.CatchErrors(c)
}
func NewExceptionHandler(es *service.ExceptionService) *ExceptionHandler {
return &ExceptionHandler{
exceptionService: es,
}
}

View File

@@ -9,17 +9,12 @@ type ProjectHandler struct {
projectCreatorService *service.ProjectCreator
}
type ProjectBody struct {
Name string `json:"name" binding:"required"`
Team string `json:"team" binding:"required"`
}
func (h *ProjectHandler) ProjectCreate(c *gin.Context) {
h.projectCreatorService.CreateProject(c)
}
func (h *ProjectHandler) ProjectGet(c *gin.Context) {
h.projectCreatorService.GetProject(c)
h.projectCreatorService.ProjectGet(c)
}
func NewProjectHandler(projectCreatorService *service.ProjectCreator) *ProjectHandler {

View File

@@ -0,0 +1,24 @@
package handler
import (
"cybertron/service"
"github.com/gin-gonic/gin"
)
type ReleasesHandler struct {
releaseService *service.ReleaseService
}
func (h *ReleasesHandler) AddRelease(c *gin.Context) {
h.releaseService.AddRelease(c)
}
func (h *ReleasesHandler) GetReleases(c *gin.Context) {
h.releaseService.GetReleases(c)
}
func NewReleaseHandler(rs *service.ReleaseService) *ReleasesHandler {
return &ReleasesHandler{
releaseService: rs,
}
}

View File

@@ -0,0 +1,15 @@
package router
import (
"cybertron/internal/dependencies"
"cybertron/internal/transport/handler"
"github.com/gin-gonic/gin"
)
func ExceptionRouter(r *gin.Engine, dep *dependencies.Dependencies) {
exceptionHandler := handler.NewExceptionHandler(dep.Service.ExceptionService)
exceptionRouterGroup := r.Group("/api/v1")
{
exceptionRouterGroup.POST("/catch-errors", exceptionHandler.CatchErrors)
}
}

View File

@@ -0,0 +1,16 @@
package router
import (
"cybertron/internal/dependencies"
"cybertron/internal/transport/handler"
"github.com/gin-gonic/gin"
)
func ReleasesRouter(r *gin.Engine, dep *dependencies.Dependencies) {
releasesHandler := handler.NewReleaseHandler(dep.Service.ReleaseService)
releasesGroup := r.Group("/api/v1")
{
releasesGroup.POST("/release", releasesHandler.AddRelease)
releasesGroup.GET("/releases", releasesHandler.GetReleases)
}
}

View File

@@ -31,6 +31,8 @@ func NewServer(dep *dependencies.Dependencies) *Server {
func (s *Server) router() {
router.ReadinessRouter(s.gin)
router.ProjectRouter(s.gin, s.dependencies)
router.ReleasesRouter(s.gin, s.dependencies)
router.ExceptionRouter(s.gin, s.dependencies)
}
func (s *Server) Start() {

View File

@@ -2,12 +2,15 @@ package db
import (
"github.com/google/uuid"
"gorm.io/gorm"
"time"
)
type Project struct {
gorm.Model
ProjectReferenceId uuid.UUID `gorm:"primaryKey"`
Name string `gorm:"column:name;unique"`
Team string
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt time.Time `json:"deletedAt"`
ProjectReferenceId uuid.UUID `json:"projectReferenceId" gorm:"primaryKey"`
Name string `json:"name" gorm:"unique"`
Team string `json:"team"`
}

14
models/db/release.go Normal file
View File

@@ -0,0 +1,14 @@
package db
import (
"github.com/google/uuid"
"gorm.io/gorm"
)
type Release struct {
gorm.Model
ReleaseId uuid.UUID
ProjectReferenceId string `gorm:"primaryKey"`
ReleaseVersion string `gorm:"column:name"`
SourceMapUrl string
}

View File

@@ -0,0 +1,47 @@
package service
import (
"cybertron/configs"
"cybertron/pkg/encoder"
"cybertron/pkg/kafka/producer"
"cybertron/pkg/log"
"fmt"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
"net/http"
)
type ExceptionService struct {
logger *log.Logger
dbClient *gorm.DB
kafkaProducer producer.KProducer
}
func NewExceptionService(logger *log.Logger, dbClient *gorm.DB, kafkaProducer producer.KProducer) *ExceptionService {
return &ExceptionService{
logger: logger,
dbClient: dbClient,
kafkaProducer: kafkaProducer,
}
}
func (exceptionService *ExceptionService) CatchErrors(c *gin.Context) {
var errorsPayload []interface{}
if err := c.BindJSON(&errorsPayload); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON payload"})
return
}
headerMap := make(map[string]string)
for _, errorItem := range errorsPayload {
err := exceptionService.kafkaProducer.PublishEvent(errorItem, configs.GetKafkaConfig().GetTopic("js-error-topic"), uuid.NewString(), headerMap, encoder.JsonEncoderInstance)
if err != nil {
fmt.Println("Failed to push error to kafka")
}
}
c.JSON(http.StatusOK, gin.H{"status": "success"})
}

View File

@@ -3,13 +3,11 @@ package service
import (
"cybertron/internal/client/aws"
"cybertron/models/db"
"cybertron/pkg/encoder"
"cybertron/pkg/kafka/producer"
"cybertron/pkg/log"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
"math/rand"
"net/http"
)
@@ -44,18 +42,23 @@ func (pc *ProjectCreator) CreateProject(ctx *gin.Context) {
}
// Write to database
pc.dbClient.Create(&db.Project{
result := pc.dbClient.Create(&db.Project{
ProjectReferenceId: uuid.New(),
Name: projectBody.Name,
Team: projectBody.Team,
})
if result.Error != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error(), "message": "Failed to create project"})
return
}
ctx.JSON(http.StatusOK, gin.H{
"message": "Project created",
})
}
func (pc *ProjectCreator) GetProject(ctx *gin.Context) {
func (pc *ProjectCreator) ProjectGet(c *gin.Context) {
//s3 processing
//buckets, err := pc.s3Client.S3Client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
//key := "async js.pdf"
@@ -76,14 +79,17 @@ func (pc *ProjectCreator) GetProject(ctx *gin.Context) {
//generate Random numbers in go
err := pc.kafkaProducer.PublishEvent(rand.Int(), "kafka-stream", "", nil, encoder.JsonEncoderInstance)
if err != nil {
pc.logger.Info(err.Error())
//err := pc.kafkaProducer.PublishEvent(rand.Int(), "kafka-stream", "", nil, encoder.JsonEncoderInstance)
//if err != nil {
// pc.logger.Info(err.Error())
//}
var projects []db.Project
pc.dbClient.Find(&projects)
if result := pc.dbClient.Find(&projects); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
var project db.Project
pc.dbClient.First(&project, 1)
ctx.JSON(http.StatusOK, gin.H{
"message": project,
})
c.JSON(http.StatusOK, projects)
}

69
service/ReleaseService.go Normal file
View File

@@ -0,0 +1,69 @@
package service
import (
"cybertron/models/db"
"cybertron/pkg/log"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
"net/http"
)
type ReleaseService struct {
logger *log.Logger
dbClient *gorm.DB
}
type ReleaseBody struct {
ProjectId string `json:"project_id" binding:"required"`
Version string `json:"version" binding:"required"`
SourceMapUrl string `json:"source_map_url" binding:"required"`
}
func NewReleaseService(logger *log.Logger, dbClient *gorm.DB) *ReleaseService {
return &ReleaseService{
logger: logger,
dbClient: dbClient,
}
}
// FIXME: This may not be requried now, can be used in source maps services only
func (releaseService *ReleaseService) AddRelease(c *gin.Context) {
var releaseBody ReleaseBody
if err := c.BindJSON(&releaseBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "Invalid Request",
})
return
}
releaseToBeAdded := db.Release{
ReleaseId: uuid.New(),
ProjectReferenceId: releaseBody.ProjectId,
ReleaseVersion: releaseBody.Version,
SourceMapUrl: releaseBody.SourceMapUrl,
}
if result := releaseService.dbClient.Create(&releaseToBeAdded); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "Release added successfully",
})
}
func (releaseService *ReleaseService) GetReleases(c *gin.Context) {
projectRefId := c.Query("project_reference_id")
var releases []db.Release
releaseService.dbClient.Where("project_reference_id = ?", projectRefId).Find(&releases)
if result := releaseService.dbClient.Find(&releases); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
c.JSON(http.StatusOK, releases)
}