Add depot, attendant, jetfire, optimus, ota services with kustomize overlays
This commit is contained in:
210
services/ota_update_go/handlers/vehicles_get.go
Normal file
210
services/ota_update_go/handlers/vehicles_get.go
Normal file
@@ -0,0 +1,210 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/fiskerinc/cloud-services/pkg/cache"
|
||||
re "github.com/fiskerinc/cloud-services/pkg/redis"
|
||||
"github.com/fiskerinc/cloud-services/pkg/utils"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"otaupdate/services"
|
||||
|
||||
"github.com/fiskerinc/cloud-services/pkg/common"
|
||||
orm "github.com/fiskerinc/cloud-services/pkg/db/queries"
|
||||
"github.com/fiskerinc/cloud-services/pkg/logger"
|
||||
"github.com/fiskerinc/cloud-services/pkg/loggerdataresp"
|
||||
"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
|
||||
"github.com/fiskerinc/cloud-services/pkg/utils/urlhelper"
|
||||
"github.com/fiskerinc/cloud-services/pkg/validator"
|
||||
"github.com/fiskerinc/cloud-services/pkg/utils/elptr"
|
||||
)
|
||||
|
||||
// HandleVehiclesGet godoc
|
||||
// @Summary Search cars
|
||||
// @Description Returns cars filtered by id, model, year, and vin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param Authorization header string false "Bearer <ID token>"
|
||||
// @Param Api-Key header string false "<API token>"
|
||||
// @Param search query string false "Text search"
|
||||
// @Param vins query []string false "csv of Car vin"
|
||||
// @Param model query int false "Car model"
|
||||
// @Param year query string false "Car year"
|
||||
// @Param online query bool false "Car status"
|
||||
// @Param online_hmi query bool false "HMI status"
|
||||
// @Param limit query int false "Max number of records"
|
||||
// @Param offset query int false "Records offset"
|
||||
// @Param order query string false "Sort on column with asc or desc"
|
||||
// @Success 200 {object} common.JSONDBQueryResult{data=[]common.Car}
|
||||
// @Failure 400 {object} common.JSONError "Bad request"
|
||||
// @Failure 401 {object} common.JSONError "Unauthorized"
|
||||
// @Failure 503 {object} common.JSONError "Service unavailable"
|
||||
// @Router /vehicles [get]
|
||||
func HandleVehiclesGet(w http.ResponseWriter, r *http.Request) {
|
||||
var total int
|
||||
c := services.GetDB().GetCars()
|
||||
filter, err := parseCarsFilter(r)
|
||||
if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) {
|
||||
return
|
||||
}
|
||||
|
||||
options, err := orm.ParsePageQuery(r)
|
||||
if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) {
|
||||
return
|
||||
}
|
||||
if options.Order == "" {
|
||||
options.Order = "vin"
|
||||
}
|
||||
|
||||
err = fillOnline(filter)
|
||||
if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable) {
|
||||
return
|
||||
}
|
||||
|
||||
// Do not display EU vins in the list in NA prod UI
|
||||
if isNAProd() {
|
||||
filter.NoEU = true
|
||||
}
|
||||
|
||||
cars, err := c.Search(filter, options)
|
||||
if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable, loggerdataresp.PostgresNoRowsErrorCheck) {
|
||||
return
|
||||
}
|
||||
|
||||
if options.Offset == 0 && filter.VIN == "" {
|
||||
total, err = c.SearchCount(filter)
|
||||
if loggerdataresp.BadDataErrorResp(w, err, http.StatusServiceUnavailable) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
utils.RespJSON(w, http.StatusOK, common.JSONDBQueryResult{
|
||||
Data: cars,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
var vehiclesCache cache.VehicleCacher
|
||||
|
||||
func SetVehiclesCache(c cache.VehicleCacher) {
|
||||
vehiclesCache = c
|
||||
}
|
||||
|
||||
func GetVehiclesCache() cache.VehicleCacher {
|
||||
if vehiclesCache == nil {
|
||||
var err error
|
||||
vehiclesCache, err = cache.NewVehiclesCache(
|
||||
envtool.GetEnvDuration("VEHICLES_CACHE_TTL", 5*time.Minute),
|
||||
envtool.GetEnvInt("VEHICLES_CACHE_LIMIT", 1000))
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Send()
|
||||
}
|
||||
}
|
||||
|
||||
return vehiclesCache
|
||||
}
|
||||
|
||||
func fillOnline(filter *common.CarSearch) error {
|
||||
if filter == nil || filter.Online == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var keys []string
|
||||
if filter.Online.Online != nil && *filter.Online.Online {
|
||||
keys = append(keys, re.CarSessionsKey())
|
||||
}
|
||||
|
||||
if filter.Online.HMI != nil && *filter.Online.HMI {
|
||||
keys = append(keys, re.HMISessionsKey())
|
||||
}
|
||||
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
vehicles, err := getOnline(keys)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "get online vehicles")
|
||||
}
|
||||
|
||||
filter.Online.VINsOnline = vehicles
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOnline(sessionKeys []string) ([]string, error) {
|
||||
var onlineVehicles []string
|
||||
redisCli := services.RedisClientPool().GetFromPool()
|
||||
defer redisCli.Close()
|
||||
|
||||
batch := re.NewRedisBatchCommands()
|
||||
|
||||
for i := range sessionKeys {
|
||||
batch.Add("SMEMBERS", sessionKeys[i])
|
||||
}
|
||||
|
||||
vinOfVins, err := redis.Values(redisCli.ExecuteBatch(batch))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "redis get multi failed for keys: %v", sessionKeys)
|
||||
}
|
||||
|
||||
onlineVehicles = make([]string, 0)
|
||||
|
||||
for _, rvins := range vinOfVins {
|
||||
setVehicles, err := redis.Strings(rvins, nil)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "redis cast to string failed: %v", sessionKeys)
|
||||
}
|
||||
|
||||
onlineVehicles = append(onlineVehicles, setVehicles...)
|
||||
}
|
||||
|
||||
return onlineVehicles, nil
|
||||
}
|
||||
|
||||
func parseCarsFilter(r *http.Request) (*common.CarSearch, error) {
|
||||
qs := r.URL.Query()
|
||||
|
||||
filter := common.CarSearch{
|
||||
Search: qs.Get("search"),
|
||||
VINs: qs.Get("vins"),
|
||||
Car: common.Car{
|
||||
VIN: qs.Get("vin"),
|
||||
Model: qs.Get("model"),
|
||||
Year: urlhelper.GetQueryInt(qs, "year"),
|
||||
},
|
||||
}
|
||||
|
||||
var o *common.CarOnlineFilter
|
||||
|
||||
online, ok := urlhelper.GetQueryBool(qs, "online")
|
||||
if ok {
|
||||
if o == nil {
|
||||
o = &common.CarOnlineFilter{}
|
||||
}
|
||||
|
||||
o.Online = elptr.ElPtr(online)
|
||||
}
|
||||
|
||||
onlineHMI, ok := urlhelper.GetQueryBool(qs, "online_hmi")
|
||||
if ok {
|
||||
if o == nil {
|
||||
o = &common.CarOnlineFilter{}
|
||||
}
|
||||
|
||||
o.HMI = elptr.ElPtr(onlineHMI)
|
||||
}
|
||||
|
||||
filter.Online = o
|
||||
|
||||
err := validator.ValidateNonRequired(filter)
|
||||
|
||||
return &filter, err
|
||||
}
|
||||
|
||||
func isNAProd() bool {
|
||||
return envtool.GetEnv("IS_NA_PROD", "") != ""
|
||||
}
|
||||
Reference in New Issue
Block a user