package handlers import ( "net/http" "otaupdate/services" "github.com/fiskerinc/cloud-services/pkg/common" "github.com/fiskerinc/cloud-services/pkg/db/queries" "github.com/fiskerinc/cloud-services/pkg/httphandlers" uhelpers "github.com/fiskerinc/cloud-services/pkg/usecase_helpers" "github.com/fiskerinc/cloud-services/pkg/utils" "github.com/fiskerinc/cloud-services/pkg/loggerdataresp" ) // HandleFleetUpdatesAdd godoc // @Summary Add car updates by fleet // @Description Create car updates assigning update 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.JSONFleetUpdatesRequest true "Update manifest or package id and, car ids" // @Success 200 {object} common.JSONDBQueryResult "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 /fleetupdate [post] func HandleFleetUpdatesAdd(w http.ResponseWriter, r *http.Request) { var req uhelpers.JSONFleetUpdatesRequest err := httphandlers.ParseRequest(r, &req) if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) { return } manifest, err := getManifest(req.UpdateManifestID) if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable, loggerdataresp.PostgresNoRowsErrorCheck) { return } username := httphandlers.GetClientID(r) err = sendManifestToFleets(req.FleetNames, manifest, username) if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable) { return } utils.RespJSON(w, http.StatusOK, common.JSONDBQueryResult{ Data: req.FleetNames, }) } func sendManifestToFleets(fleetNames []string, manifest common.UpdateManifest, username string) error { var resultNames []string resC := make(chan string, len(fleetNames)) // to avoid goroutines leak, we add buffer to the errC channel errC := make(chan error, len(fleetNames)) for _, name := range fleetNames { go updateFleet(name, manifest, username, errC, resC) } for { select { case err := <-errC: return err case name := <-resC: resultNames = append(resultNames, name) if len(resultNames) == len(fleetNames) { return nil } } } } func updateFleet(name string, manifest common.UpdateManifest, username string, errC chan<- error, resC chan<- string) { client, err := services.GetMongoClient() if err != nil { errC <- err return } vins, err := client.GetFleets().GetVehiclesForFleet(name, "", &queries.PageQueryOptions{}) if err != nil { errC <- err return } d := services.GetDB().GetCarUpdates() k := services.GetKafkaProducer() notifier := uhelpers.NewUpdateNotifier(d, k) _, err = notifier.Send(vins, manifest, username) if err != nil { errC <- err return } resC <- name }