package handlers import ( "fmt" "io" "net/http" "github.com/fiskerinc/cloud-services/pkg/common/actionlogger" "github.com/fiskerinc/cloud-services/pkg/common/carupdatestatus" "github.com/fiskerinc/cloud-services/pkg/logger" uhelpers "github.com/fiskerinc/cloud-services/pkg/usecase_helpers" "github.com/fiskerinc/cloud-services/pkg/utils" "otaupdate/services" "github.com/fiskerinc/cloud-services/pkg/common" "github.com/fiskerinc/cloud-services/pkg/httphandlers" "github.com/fiskerinc/cloud-services/pkg/loggerdataresp" ) // HandleCarUpdatesAdd godoc // @Summary Add car updates // @Description Create car updates assigning manifest package to cars, and send notifications // @Accept json // @Produce json // @Param Authorization header string false "Bearer " // @Param Api-Key header string false "" // @Param data body usecase_helpers.JSONCarUpdatesRequest true "Update manifest or package id and, car ids" // @Success 200 {object} common.JSONDBQueryResult{data=[]common.CarUpdate} "Created car updates result" // @Failure 400 {object} common.JSONError "Bad request" // @Failure 401 {object} common.JSONError "Unauthorized" // @Failure 503 {object} common.JSONError "Service unavailable" // @Router /carupdate [post] func HandleCarUpdatesAdd(w http.ResponseWriter, r *http.Request) { var req uhelpers.JSONCarUpdatesRequest var ups []common.CarUpdate err := httphandlers.ParseRequest(r, &req) if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) { return } username := httphandlers.GetClientID(r) manifest, err := getManifest(req.UpdateManifestID) if loggerdataresp.BadDataErrorResp(w, err, http.StatusNotFound, loggerdataresp.PostgresNoRowsErrorCheck) { return } d := services.GetDB().GetCarUpdates() k := services.GetKafkaProducer() alDB := services.GetDB().GetActionLog() go func() { actionLog := actionlogger.ActionLog{ VIN: "", Action: actionlogger.CarUpdate, UserIdentifier: httphandlers.GetClientID(r), CallLocation: "github.com/fiskerinc/cloud-services/services/ota_update_go/handlers/car_update_add.go", Description: fmt.Sprintf("UpdateManifest: %d", req.UpdateManifestID), } for _, vin := range req.VINs { actionLog.VIN = vin err = alDB.Insert(actionLog) if err != nil { logger.Err(err).Msg("failed to insert action log inside HandleCarUpdatesAdd") } } }() notifier := uhelpers.NewUpdateNotifier(d, k) ups, err = notifier.Send(req.VINs, manifest, username) if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable) { return } for _, vin := range req.VINs { // Notify car user of in progress update through FOA API fs := services.GetFoaService() foaResp, err := fs.OtaUpdateStatus(vin, &common.CarUpdate{UpdateManifestID: req.UpdateManifestID}, &common.CarUpdateProgress{Status: carupdatestatus.Pending}) if err != nil || (foaResp != nil && foaResp.StatusCode != http.StatusOK) { bodyBytes, _ := io.ReadAll(foaResp.Body) bodyString := string(bodyBytes) logger.Err(err).Msgf("notify FOA for update manifest %d pending state %s for %s failed with http status %d and message %s", req.UpdateManifestID, carupdatestatus.Pending, vin, foaResp.StatusCode, bodyString) err = nil } } utils.RespJSON(w, http.StatusOK, common.JSONDBQueryResult{ Data: ups, }) } func getManifest(manifestID int64) (common.UpdateManifest, error) { um := services.GetDB().GetUpdateManifests() manifest := common.UpdateManifest{ID: manifestID} err := um.Load(&manifest) return manifest, err }