142 lines
4.8 KiB
Go
142 lines
4.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"otaupdate/services"
|
|
"sort"
|
|
"strconv"
|
|
|
|
"github.com/fiskerinc/cloud-services/pkg/common"
|
|
"github.com/fiskerinc/cloud-services/pkg/httphandlers"
|
|
"github.com/fiskerinc/cloud-services/pkg/loggerdataresp"
|
|
"github.com/fiskerinc/cloud-services/pkg/utils"
|
|
"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
|
|
"github.com/fiskerinc/cloud-services/pkg/validator"
|
|
)
|
|
|
|
var apiCreateToken string = envtool.GetEnv("MIGRATE_CREATE_TOKEN", "")
|
|
|
|
// HandleFlashpackVersionAdd godoc
|
|
// @Summary Add a flashpack version
|
|
// @Description Add a flashpack version
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param Authorization header string false "Bearer <ID token>"
|
|
// @Param Api-Key header string false "<API token>"
|
|
// @Param data body common.CarFlashpackVersionAddRequest true "Mappings between ECU versions and a flashpack number"
|
|
// @Success 200 {object} common.JSONDBQueryResult "Created flashpack ecu mapping result"
|
|
// @Failure 400 {object} common.JSONError "Bad request"
|
|
// @Failure 401 {object} common.JSONError "Unauthorized"
|
|
// @Failure 503 {object} common.JSONError "Service unavailable"
|
|
// @Router /flashpack_version [post]
|
|
func HandleFlashpackVersionAdd(w http.ResponseWriter, r *http.Request) {
|
|
var req common.CarFlashpackVersionAddRequest
|
|
|
|
err := httphandlers.ParseRequest(r, &req)
|
|
if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) {
|
|
return
|
|
}
|
|
|
|
if len(req.ECUVersions) < 1 {
|
|
loggerdataresp.BadDataErrorResp(w, errors.New("CarECUName and CarECUVersion required"), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Include previous flashpack mappings
|
|
previousMappings, err := services.GetDB().GetCars().GetCarFlashpackVersionMappingsByModelTrim(req.CarModel, req.CarTrim, nil)
|
|
if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable) {
|
|
return
|
|
}
|
|
|
|
// the flashpacks are stored in the database as strings, so we have to sort them numerically
|
|
// in descending order by year and flashpack
|
|
sort.Slice(previousMappings, func(i, j int) bool {
|
|
iFp, _ := strconv.ParseFloat(previousMappings[i].Flashpack, 64) // guaranteed numeric
|
|
jFp, _ := strconv.ParseFloat(previousMappings[j].Flashpack, 64) // guaranteed numeric
|
|
iYear := previousMappings[i].CarYear
|
|
jYear := previousMappings[j].CarYear
|
|
|
|
if iYear == jYear {
|
|
return iFp > jFp
|
|
} else {
|
|
return iYear > jYear
|
|
}
|
|
})
|
|
|
|
// Put all the mappings into one array, still in descending order by flashpack number
|
|
// only include the ones that are less than or equal to the new flashpack number being added
|
|
mappings := []common.CarFlashpackVersion{}
|
|
for _, v := range req.ECUVersions {
|
|
mappings = append(mappings, common.CarFlashpackVersion{
|
|
CarECUName: v.CarECUName,
|
|
CarECUVersion: v.CarECUVersion,
|
|
Flashpack: req.Flashpack,
|
|
CarModel: req.CarModel,
|
|
CarTrim: req.CarTrim,
|
|
CarYear: req.CarYear,
|
|
})
|
|
}
|
|
for _, m := range previousMappings {
|
|
reqFp, _ := strconv.ParseFloat(req.Flashpack, 64) // already validated as numeric
|
|
mFp, _ := strconv.ParseFloat(m.Flashpack, 64) // already validated as numeric
|
|
if (m.CarYear < req.CarYear) ||
|
|
(m.CarYear == req.CarYear && mFp <= reqFp) {
|
|
mappings = append(mappings, m)
|
|
}
|
|
}
|
|
|
|
// Put the mappings in a map by ecu name
|
|
// There can be more than one ECU version for an ECU for a flashpack
|
|
var newMappings = make(map[string][]common.CarFlashpackVersion)
|
|
for _, m := range mappings {
|
|
// Only include the mapping if it is one of the latest
|
|
latestVersionMappings, ok := newMappings[m.CarECUName]
|
|
// Include multiple versions for the same ecu and flashpack number
|
|
if (ok && m.Flashpack == latestVersionMappings[0].Flashpack) || !ok {
|
|
newMappings[m.CarECUName] = append(newMappings[m.CarECUName], m)
|
|
}
|
|
}
|
|
|
|
// Flatten the map into an array
|
|
var newMappingsArray []common.CarFlashpackVersion
|
|
for _, m := range newMappings {
|
|
newMappingsArray = append(newMappingsArray, m...)
|
|
}
|
|
|
|
// Apply the new flashpack number to all the mappings to be inserted
|
|
for i := range newMappingsArray {
|
|
newMappingsArray[i].Flashpack = req.Flashpack
|
|
newMappingsArray[i].CarYear = req.CarYear
|
|
}
|
|
|
|
err = services.GetDB().GetCars().AddCarFlashpackVersionMappings(newMappingsArray)
|
|
if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable) {
|
|
return
|
|
}
|
|
|
|
// Also add to other environments, as required
|
|
for _, targetURL := range targetURLS {
|
|
if !validator.ValidateURL(targetURL) || apiCreateToken == "" {
|
|
break // No URL in MANIFEST_MIGRATE_URLS
|
|
}
|
|
|
|
otaService := services.NewOtaService(targetURL, apiCreateToken)
|
|
|
|
resp, err := otaService.FlashpackVersionAdd(req)
|
|
if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) {
|
|
return
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
utils.ForwardResponse(w, resp)
|
|
}
|
|
}
|
|
|
|
utils.RespJSON(w, http.StatusOK, common.JSONMessage{
|
|
Message: "Created",
|
|
})
|
|
}
|