TP-55555/source-map-flow

This commit is contained in:
varnit-goyal_navi
2024-08-16 13:47:08 +05:30
parent 9380234b3c
commit c4de994f2e
10 changed files with 135 additions and 80 deletions

View File

@@ -67,3 +67,6 @@ DocumentService:
generate_token: DOCUMENT_SERVICE_MOCK_GENERATE_TOKEN
aws:
region: ap-south-1
bucket: navi-cd955a63c4476df0f00c1cea0e4a40d1

View File

@@ -16,6 +16,6 @@ func InitReleaseRepository(dbClient *gorm.DB) *gorm.DB {
}
func InitSourceMapRepository(dbClient *gorm.DB) *gorm.DB {
dbClient.AutoMigrate(&db.SourcMap{})
dbClient.AutoMigrate(&db.SourceMap{})
return dbClient
}

View File

@@ -42,8 +42,9 @@ type Handler struct {
}
type Repositories struct {
ProjectRepository *gorm.DB
ReleaseRepository *gorm.DB
ProjectRepository *gorm.DB
ReleaseRepository *gorm.DB
SourceMapRepository *gorm.DB
}
func InitDependencies() *Dependencies {
@@ -56,7 +57,7 @@ func InitDependencies() *Dependencies {
documentServiceClient := document.NewDocumentServiceHttpClient(httpClient, logger, configs.GetDocumentServiceHttpClientConfigs())
projectServiceClient := service.NewProjectCreator(logger, dbClient, s3Client, kafkaProducer)
sourceMapServiceClient := service.NewSourceMapService(dbClient)
sourceMapServiceClient := service.NewSourceMapService(dbClient, s3Client, configs.GetAWSConfig())
releaseServiceClient := service.NewReleaseService(logger, dbClient)
exceptionServiceClient := service.NewExceptionService(logger, dbClient, kafkaProducer)
@@ -83,8 +84,9 @@ func initServices(documentService *document.HttpClient, projectService *service.
func initRepositories(dbClient *gorm.DB) *Repositories {
return &Repositories{
ProjectRepository: database.InitProjectRepository(dbClient),
ReleaseRepository: database.InitReleaseRepository(dbClient),
ProjectRepository: database.InitProjectRepository(dbClient),
ReleaseRepository: database.InitReleaseRepository(dbClient),
SourceMapRepository: database.InitSourceMapRepository(dbClient),
}
}

View File

@@ -2,8 +2,6 @@ package handler
import (
"cybertron/service"
"net/http"
"github.com/gin-gonic/gin"
)
@@ -17,11 +15,14 @@ func NewSourceMapHandler(sourceMapService *service.SourceMapService) *SourceMapH
}
}
func (h *SourceMapHandler) GetSourceMap(c *gin.Context) {
sourceMap := h.sourceMapService.GetSourceMap()
c.JSON(http.StatusOK, sourceMap)
func (h *SourceMapHandler) GetSourceMapUploadUrl(c *gin.Context) {
h.sourceMapService.GetSourceMapUploadUrl(c)
}
func (h *SourceMapHandler) StoreSourceMap(c *gin.Context) {
h.sourceMapService.StoreSourceMap(c)
func (h *SourceMapHandler) SourceMapUploadAck(c *gin.Context) {
h.sourceMapService.SourceMapUploadAck(c)
}
func (h *SourceMapHandler) ValidateSourceMap(c *gin.Context) {
h.sourceMapService.ValidateSourceMap(c)
}

View File

@@ -1,16 +1,15 @@
package router
import (
"cybertron/internal/dependencies"
"cybertron/internal/transport/handler"
"cybertron/service"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func SourceMapRouter(r *gin.Engine, dbClient *gorm.DB) {
sourceMapService := service.NewSourceMapService(dbClient)
sourceMapHandler := handler.NewSourceMapHandler(sourceMapService)
r.GET("/uploadsourcemap", sourceMapHandler.GetSourceMap)
r.POST("/storesourcemap", sourceMapHandler.StoreSourceMap)
func SourceMapRouter(r *gin.Engine, dep *dependencies.Dependencies) {
sourceMapHandler := handler.NewSourceMapHandler(dep.Service.SourceMapService)
sourceMapGroup := r.Group("/api/v1")
sourceMapGroup.GET("/get-sourcemap-upload-url", sourceMapHandler.GetSourceMapUploadUrl)
sourceMapGroup.POST("/source-map-upload-ack", sourceMapHandler.SourceMapUploadAck)
sourceMapGroup.POST("/validate-source-map", sourceMapHandler.ValidateSourceMap)
}

View File

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

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

@@ -0,0 +1,9 @@
package db
import "gorm.io/gorm"
type Release struct {
gorm.Model
ProjectReferenceId string `gorm:"primaryKey"`
ReleaseVersion string `gorm:"column:name"`
}

View File

@@ -6,5 +6,6 @@ type SourceMap struct {
gorm.Model
ReleaseReferenceId string `gorm:"primaryKey"`
ProjectReferenceId string `gorm:"column:project_reference_id"`
SourceMapZipUrl string `gorm:"column:source_map_zip_url"`
FileName string `gorm:"column:file_name"`
State string `gorm:"column:state"`
}

View File

@@ -3,7 +3,6 @@ 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"
@@ -44,6 +43,8 @@ func (pc *ProjectCreator) CreateProject(ctx *gin.Context) {
return
}
var uuidGenerated = uuid.New()
//converting uuid to all numbers since sentry only supports
//all digit project uuid
var i big.Int
i.SetString(strings.Replace(uuidGenerated.String(), "-", "", 4), 16)
@@ -65,33 +66,7 @@ func (pc *ProjectCreator) CreateProject(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"
//bucket := "navi-cd955a63c4476df0f00c1cea0e4a40d1"
//request, err := pc.s3Client.S3PresignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
// Bucket: &bucket,
// Key: &key,
//}, func(opts *s3.PresignOptions) {
// opts.Expires = time.Duration(7 * 24 * time.Hour)
//})
//pc.logger.Info(request.URL)
//if err != nil {
// log.Log.Fatal(err.Error())
// pc.logger.Error("S3 List Buckets Failed")
//}
//kafka producer testing
//generate Random numbers in go
err := pc.kafkaProducer.PublishEvent(`{"hello" :"world"}`, "kafka-stream", "", nil, encoder.JsonEncoderInstance)
if err != nil {
pc.logger.Info(err.Error())
}
pc.logger.Info("published kafka message")
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()})

View File

@@ -1,56 +1,121 @@
package service
import (
"context"
"cybertron/configs"
"cybertron/internal/client/aws"
"cybertron/models/db"
"net/http"
"time"
"fmt"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"net/http"
"path"
"time"
)
type SourceMapService struct {
dbClient *gorm.DB
dbClient *gorm.DB
s3Client *aws.Actions
awsConfig *configs.AwsConfig
}
func NewSourceMapService(dbClient *gorm.DB) *SourceMapService {
type SourceMapAckBody struct {
ProjectId string `json:"project-id" binding:"required"`
ReleaseId string `json:"releaseId" binding:"required"`
FileName string `json:"file_name" binding:"required"`
}
func NewSourceMapService(dbClient *gorm.DB, s3Client *aws.Actions, config *configs.AwsConfig) *SourceMapService {
return &SourceMapService{
dbClient: dbClient,
dbClient: dbClient,
s3Client: s3Client,
awsConfig: config,
}
}
func (s *SourceMapService) GetSourceMap() db.SourceMap {
//fetching SourceMap from a client API
sourceMap := db.SourceMap{
Model: gorm.Model{
ID: 1,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
DeletedAt: gorm.DeletedAt{},
},
ReleaseReferenceId: "some-release-ref-id",
ProjectReferenceId: "some-project-ref-id",
SourceMapZipUrl: "http://example.com/sourcemap.zip",
}
func (s *SourceMapService) GetSourceMapUploadUrl(ctx *gin.Context) {
projectId := ctx.Query("project_id")
releaseId := ctx.Query("release_id")
fileName := ctx.Query("file_name")
return sourceMap
if projectId == "" || releaseId == "" || fileName == "" {
ctx.JSON(http.StatusBadRequest, gin.H{
"error": "Missing required query parameters: project_id, release_id, and file_name are required.",
})
return
}
//generate s3 pre-signed url
key := path.Join(projectId, releaseId, fileName)
bucket := s.awsConfig.Bucket
request, err := s.s3Client.S3PresignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
Bucket: &bucket,
Key: &key,
}, func(opts *s3.PresignOptions) {
opts.Expires = time.Duration(7 * 24 * time.Hour)
})
if err != nil {
fmt.Println(err)
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "unable to create S3 object"})
return
}
// save state in database
result := *s.dbClient.Create(&db.SourceMap{
ProjectReferenceId: projectId,
ReleaseReferenceId: releaseId,
FileName: fileName,
State: "IN_PROGRESS",
})
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{
"url": request.URL,
})
return
}
func (s *SourceMapService) StoreSourceMap(c *gin.Context) {
var sourceMap db.SourceMap
if err := c.ShouldBindJSON(&sourceMap); err != nil {
func (s *SourceMapService) SourceMapUploadAck(c *gin.Context) {
var sourceMapAckBody SourceMapAckBody
if err := c.BindJSON(&sourceMapAckBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
//find the record to update ack
var existingSourceMap db.SourceMap
existingRecordError := s.dbClient.First(&existingSourceMap, "project_reference_id = ? and release_reference_id= ? and file_name = ?", sourceMapAckBody.ProjectId, sourceMapAckBody.ReleaseId, sourceMapAckBody.FileName).Error
if existingRecordError != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": existingRecordError.Error()})
return
}
result := s.dbClient.Create(&db.SourceMap{
ReleaseReferenceId: sourceMap.ReleaseReferenceId,
ProjectReferenceId: sourceMap.ProjectReferenceId,
SourceMapZipUrl: sourceMap.SourceMapZipUrl,
})
existingSourceMap.State = "DONE"
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to store source map"})
err := s.dbClient.Save(&existingSourceMap).Error
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "Source map stored successfully"})
}
func (s *SourceMapService) ValidateSourceMap(ctx *gin.Context) {
projectId := ctx.Query("project_id")
releaseId := ctx.Query("release_id")
fileName := ctx.Query("file_name")
if projectId == "" || releaseId == "" || fileName == "" {
ctx.JSON(http.StatusBadRequest, gin.H{
"error": "Missing required query parameters: project_id, release_id, and file_name are required.",
})
}
var existingSourceMap db.SourceMap
s.dbClient.First(&existingSourceMap, "ProjectReferenceId = ? and ReleaseReferenceId= ? and file_name = ?", projectId, releaseId, fileName)
if existingSourceMap.State == "DONE" {
ctx.JSON(http.StatusOK, gin.H{"status": "Source map stored successfully"})
}
ctx.JSON(http.StatusNotFound, gin.H{"error": "Source map not found"})
}