Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,39 @@ func (uc *VehicleRunUseCase) DeleteVehicleRunById(ctx context.Context, id primit
func (uc *VehicleRunUseCase) UpdateVehicleRun(ctx context.Context, id primitive.ObjectID, model *models.VehicleRunModel) error {
return uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, id, model)
}

func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primitive.ObjectID, awsBucket string, fileName string, filePath string) (*models.VehicleRunModel, error) {
vehicleRun, err := uc.vechicleRunRepo.GetVehicleRunFromId(ctx, vehicleRunID)
if err != nil {
return nil, err
}
miscFile := models.FileModel{
AwsBucket: awsBucket,
FilePath: filePath,
FileName: fileName,
}
if vehicleRun.ContentFiles["misc_files"] == nil {
vehicleRun.ContentFiles["misc_files"] = []models.FileModel{}
}
vehicleRun.ContentFiles["misc_files"] = append(vehicleRun.ContentFiles["misc_files"], miscFile)
err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun)
if err != nil {
return nil, err
}
return vehicleRun, nil
}

func (uc *VehicleRunUseCase) FileNameExists(ctx context.Context, vehicleRunID primitive.ObjectID, fileName string) (bool, error) {
vehicleRun, err := uc.vechicleRunRepo.GetVehicleRunFromId(ctx, vehicleRunID)
if err != nil {
return true, err
}
if vehicleRun.ContentFiles["misc_files"] != nil {
for _, f := range vehicleRun.ContentFiles["misc_files"] {
if f.FileName == fileName {
return true, nil
}
}
}
return false, nil
}
93 changes: 93 additions & 0 deletions cloud_webserver_v2/internal/delivery/http/mcap_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,102 @@ func NewMcapHandler(
r.Get("/{id}/process", HandlerFunc(handler.ProcessMatlabJob).ServeHTTP)
r.Post("/{id}/updateMetadataRecords", HandlerFunc(handler.UpdateMetadataRecordFromID).ServeHTTP)
r.Delete("/{id}/resetMetaDataRecord/{metadata}", HandlerFunc(handler.ResetMetadataRecordFromID).ServeHTTP)
r.Post("/{id}/addMiscFile", HandlerFunc(handler.UploadNewMiscFile).ServeHTTP)
r.Delete("/{id}/deleteMiscFile/{fileName}", HandlerFunc(handler.DeleteMiscFile).ServeHTTP)
})
}

// Retrieves misc files uploaded from request, calls S3 usecase to update S3, & calls vehicle run usecase to
// update MongoDB
func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) *HandlerError {
ctx := r.Context()
err := r.ParseMultipartForm(32 << 20)
if err != nil {
return NewHandlerError(fmt.Sprintf("Failed to parse multipart form"), http.StatusBadRequest)
}
file, header, err := r.FormFile("file")
if err != nil {
return NewHandlerError(fmt.Sprintf("Could not read file from request"), http.StatusBadRequest)
}
defer file.Close()

idStr := chi.URLParam(r, "id")
vehicleRunID, err := primitive.ObjectIDFromHex(idStr)
if err != nil {
return NewHandlerError(fmt.Sprint("Invalid vehicle run ID"), http.StatusBadRequest)
}

s3Key := fmt.Sprintf("%s/miscFiles/%s", vehicleRunID.Hex(), header.Filename)
exists, err := h.dbClient.VehicleRunUseCase().FileNameExists(ctx, vehicleRunID, header.Filename)
if err != nil {
return NewHandlerError(fmt.Sprintf("Failed to save misc file to vehicle run: "+err.Error()), http.StatusInternalServerError)
}
if exists {
return NewHandlerError(fmt.Sprintf("File name already exists, duplicate file names not allowed"), http.StatusNotAcceptable)
}
err = h.s3Repository.WriteObjectReader(ctx, file, s3Key)
if err != nil {
return NewHandlerError(fmt.Sprintf("Failed to upload to S3: "+err.Error()), http.StatusInternalServerError)
}

_, err = h.dbClient.VehicleRunUseCase().AddMiscFile(ctx, vehicleRunID, h.s3Repository.Bucket(), header.Filename, s3Key)
if err != nil {
return NewHandlerError(fmt.Sprintf("Failed to save misc file to vehicle run: "+err.Error()), http.StatusInternalServerError)
}
response := map[string]interface{}{
"message": "Misc file uploaded successfully",
}
render.JSON(w, r, response)
return nil
}

func (h *mcapHandler) DeleteMiscFile(w http.ResponseWriter, r *http.Request) *HandlerError {
ctx := r.Context()
id := chi.URLParam(r, "id")
vehicleRunID, err := primitive.ObjectIDFromHex(id)
if err != nil {
return NewHandlerError(fmt.Sprintf("Could not decode MCAP id %v, %v", id, err), http.StatusInternalServerError)
}
fileName := chi.URLParam(r, "fileName")
vehicleRun, err := h.dbClient.VehicleRunUseCase().GetVehicleRunById(ctx, vehicleRunID)
if err != nil {
if err.Error() == "mongo: no documents in result" {
return NewHandlerError(fmt.Sprintf("no run with id %v found", id), http.StatusNotFound)
}
return NewHandlerError(err.Error(), http.StatusInternalServerError)
}
var targetFile *models.FileModel
for _, f := range vehicleRun.ContentFiles["misc_files"] {
if f.FileName == fileName {
targetFile = &f
break
}
}
if targetFile == nil {
return NewHandlerError(fmt.Sprintf("File does not exist to be deleted"), http.StatusBadRequest)
}
err = h.s3Repository.DeleteObject(ctx, targetFile.AwsBucket, targetFile.FilePath)
if err != nil {
return NewHandlerError(err.Error(), http.StatusInternalServerError)
}
updatedFiles := make([]models.FileModel, 0)
for _, f := range vehicleRun.ContentFiles["misc_files"] {
if f.FileName != fileName {
updatedFiles = append(updatedFiles, f)
}
}
vehicleRun.ContentFiles["misc_files"] = updatedFiles
err = h.dbClient.VehicleRunUseCase().UpdateVehicleRun(ctx, vehicleRunID, vehicleRun)
if err != nil {
return NewHandlerError(fmt.Sprintf("Failed to update vehicle run"), http.StatusInternalServerError)
}
response := map[string]interface{}{
"message": "Misc file deleted successfully",
}
render.JSON(w, r, response)
return nil
}

// GetMcapsFromFilters takes in filters through Query parameters and will respond with a
// map with a message and data field where data contains the filtered MCAPs
func (h *mcapHandler) GetMcapsFromFilters(w http.ResponseWriter, r *http.Request) {
Expand Down