2024-07-30 16:54:39 +05:30
package service
import (
2024-08-16 13:47:08 +05:30
"context"
"cybertron/configs"
"cybertron/internal/client/aws"
2024-07-30 16:54:39 +05:30
"cybertron/models/db"
2024-08-16 13:47:08 +05:30
"fmt"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
2024-07-30 17:25:49 +05:30
"net/http"
2024-08-16 13:47:08 +05:30
"path"
2024-07-30 16:54:39 +05:30
"time"
)
type SourceMapService struct {
2024-08-16 13:47:08 +05:30
dbClient * gorm . DB
s3Client * aws . Actions
awsConfig * configs . AwsConfig
2024-07-30 16:54:39 +05:30
}
2024-08-16 13:47:08 +05:30
type SourceMapAckBody struct {
2024-08-27 13:40:31 +05:30
ProjectReferenceId string ` json:"projectId" binding:"required" `
ReleaseId string ` json:"releaseId" binding:"required" `
FileName string ` json:"fileName" binding:"required" `
2024-08-16 13:47:08 +05:30
}
func NewSourceMapService ( dbClient * gorm . DB , s3Client * aws . Actions , config * configs . AwsConfig ) * SourceMapService {
2024-07-30 16:54:39 +05:30
return & SourceMapService {
2024-08-16 13:47:08 +05:30
dbClient : dbClient ,
s3Client : s3Client ,
awsConfig : config ,
2024-07-30 16:54:39 +05:30
}
}
2024-08-16 13:47:08 +05:30
func ( s * SourceMapService ) GetSourceMapUploadUrl ( 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." ,
} )
return
}
2024-08-27 13:40:31 +05:30
2024-08-16 13:47:08 +05:30
//generate s3 pre-signed url
2024-10-13 14:31:22 +05:30
key := path . Join ( projectId , releaseId , fileName )
2024-08-16 13:47:08 +05:30
bucket := s . awsConfig . Bucket
2024-08-27 13:40:31 +05:30
request , err := s . s3Client . S3PresignClient . PresignPutObject ( context . TODO ( ) , & s3 . PutObjectInput {
2024-08-16 13:47:08 +05:30
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 {
2024-10-22 13:04:56 +05:30
ctx . JSON ( http . StatusInternalServerError , gin . H { "error" : result . Error . Error ( ) , "message" : "Failed to source map" } )
2024-08-16 13:47:08 +05:30
return
}
ctx . JSON ( http . StatusOK , gin . H {
"url" : request . URL ,
} )
return
2024-07-30 16:54:39 +05:30
}
2024-08-16 13:47:08 +05:30
func ( s * SourceMapService ) SourceMapUploadAck ( c * gin . Context ) {
var sourceMapAckBody SourceMapAckBody
if err := c . BindJSON ( & sourceMapAckBody ) ; err != nil {
2024-07-30 17:25:49 +05:30
c . JSON ( http . StatusBadRequest , gin . H { "error" : err . Error ( ) } )
return
}
2024-08-27 13:40:31 +05:30
2024-08-16 13:47:08 +05:30
//find the record to update ack
var existingSourceMap db . SourceMap
2024-08-27 13:40:31 +05:30
existingRecordError := s . dbClient . First ( & existingSourceMap , "project_reference_id = ? and release_reference_id= ? and file_name = ?" , sourceMapAckBody . ProjectReferenceId , sourceMapAckBody . ReleaseId , sourceMapAckBody . FileName ) . Error
2024-08-16 13:47:08 +05:30
if existingRecordError != nil {
c . JSON ( http . StatusBadRequest , gin . H { "error" : existingRecordError . Error ( ) } )
return
}
2024-07-30 17:25:49 +05:30
2024-08-16 13:47:08 +05:30
existingSourceMap . State = "DONE"
2024-07-30 17:25:49 +05:30
2024-08-16 13:47:08 +05:30
err := s . dbClient . Save ( & existingSourceMap ) . Error
if err != nil {
c . JSON ( http . StatusInternalServerError , gin . H { "error" : err . Error ( ) } )
2024-07-30 17:25:49 +05:30
return
}
c . JSON ( http . StatusOK , gin . H { "status" : "Source map stored successfully" } )
2024-07-30 16:54:39 +05:30
}
2024-08-16 13:47:08 +05:30
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
2024-10-22 13:04:56 +05:30
result := s . dbClient . First ( & existingSourceMap , "ProjectReferenceId = ? and ReleaseReferenceId= ? and file_name = ?" , projectId , releaseId , fileName )
if result . Error != nil {
ctx . JSON ( http . StatusInternalServerError , gin . H { "error" : result . Error . Error ( ) } )
return
}
2024-08-16 13:47:08 +05:30
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" } )
}