Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
197
pkg/cachev2/vehicle_config.go
Normal file
197
pkg/cachev2/vehicle_config.go
Normal file
@@ -0,0 +1,197 @@
|
||||
package cachev2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"fiskerinc.com/modules/common"
|
||||
"fiskerinc.com/modules/logger"
|
||||
"fiskerinc.com/modules/mongo"
|
||||
"fiskerinc.com/modules/redis"
|
||||
"fiskerinc.com/modules/utils/envtool"
|
||||
|
||||
"fiskerinc.com/modules/utils/elptr"
|
||||
redigo "github.com/gomodule/redigo/redis"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
ENABLE_DBG_MASK_EV_NAME = "ENABLE_DEBUGMASK"
|
||||
ENABLE_DBG_MASK_VAL_FALSE = "0"
|
||||
ENABLE_DBG_MASK_VAL_TRUE = "1"
|
||||
ENABLE_DBG_MASK_VAL_DEFAULT = ENABLE_DBG_MASK_VAL_FALSE
|
||||
)
|
||||
|
||||
// This flag is to decide whether retrieved value of DebugMask is to be passed to TrexCfg or not.
|
||||
// When the flag is true, the retrieved value is passed; else no value is passed.
|
||||
// The value of flag is fetched from the specific environmental variable. If that environmental
|
||||
// variable is not present / not defined, we assume the flag itself to be FALSE. That is the
|
||||
// default value (FALSE) of the environmental variable. When user/developer has set this evironmental
|
||||
// variable correctly, the flag can become TRUE in which case the value is passed to TrexCfg.
|
||||
var ENABLE_DEBUG_MASK = DbgMaskEnabled()
|
||||
|
||||
// method introduced so as unit testing is easier otherwise not necessary since environment variables
|
||||
// can't be changed so easily subsequent to a process start (meaning revaluation at runtime of no much use).
|
||||
func DbgMaskEnabled() bool {
|
||||
return envtool.GetEnv(ENABLE_DBG_MASK_EV_NAME, ENABLE_DBG_MASK_VAL_DEFAULT) == ENABLE_DBG_MASK_VAL_TRUE
|
||||
}
|
||||
|
||||
func RetrieveVehicleConfig(r redis.Client, m mongo.Client, id string) (*common.TRexConfigResponse, error) {
|
||||
config := &common.TRexConfigResponse{}
|
||||
|
||||
reply, err := checkCacheForVehicleConfig(r, id)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if reply != nil {
|
||||
err = json.Unmarshal(reply, config)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if config.CANBus.DTCEnabled == nil {
|
||||
config.CANBus.DTCEnabled = elptr.ElPtr(false)
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
config.LogLevel = common.Critical
|
||||
// config.Log = &common.LogConfig{
|
||||
// Matches: []common.LogConfigChannel{
|
||||
// {
|
||||
// Channel: common.ChannelCMD,
|
||||
// Level: common.Trace,
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
config.CANBus.Enabled = true
|
||||
config.CANBus.DataLogger = true
|
||||
|
||||
filters := make(FiltersMap)
|
||||
|
||||
f, err := checkFleetsDBForVehicleConfig(m, id)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Send()
|
||||
}
|
||||
if f != nil {
|
||||
config.CANBus = f.CANBus
|
||||
config.LogLevel = f.LogLevel
|
||||
filters.AppendFilters(f.CANBus.Filters)
|
||||
}
|
||||
|
||||
v, err := checkVehiclesDBForVehicleConfig(m, id)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Send()
|
||||
}
|
||||
if v != nil {
|
||||
config.CANBus = v.CANBus
|
||||
config.LogLevel = v.LogLevel
|
||||
config.DLTEnabled = v.DLTEnabled
|
||||
config.DLTLevel = v.DLTLevel
|
||||
// we should evaluate at run-time, not just at start-up time
|
||||
if ENABLE_DEBUG_MASK {
|
||||
config.DebugMask = v.DebugMask
|
||||
}
|
||||
config.IDPSEnabled = v.IDPSEnabled
|
||||
|
||||
filters.AppendFilters(v.CANBus.Filters)
|
||||
}
|
||||
|
||||
config.CANBus.Filters = filters.ToSlice()
|
||||
if config.CANBus.DTCEnabled == nil {
|
||||
config.CANBus.DTCEnabled = elptr.ElPtr(false)
|
||||
}
|
||||
err = setCacheForVehicleConfig(r, id, config)
|
||||
return config, err
|
||||
}
|
||||
|
||||
func checkCacheForVehicleConfig(r redis.Client, id string) ([]byte, error) {
|
||||
key := redis.CarConfigKey(id)
|
||||
|
||||
reply, err := redigo.Bytes(r.Execute("GET", key))
|
||||
if err != nil {
|
||||
if errors.Is(err, redigo.ErrNil) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
func checkVehiclesDBForVehicleConfig(m mongo.Client, id string) (*mongo.Vehicle, error) {
|
||||
return m.GetVehicles().FindVehicle(&mongo.Vehicle{VIN: id})
|
||||
}
|
||||
|
||||
func checkFleetsDBForVehicleConfig(m mongo.Client, id string) (*mongo.Fleet, error) {
|
||||
return m.GetFleets().GetCANBusForVehicle(id)
|
||||
}
|
||||
|
||||
func setCacheForVehicleConfig(r redis.Client, id string, config *common.TRexConfigResponse) error {
|
||||
key := redis.CarConfigKey(id)
|
||||
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
batch := redis.NewRedisBatchCommands()
|
||||
batch.Add("SET", key, data)
|
||||
batch.Add("EXPIRE", key, redisObjectExpire.Seconds())
|
||||
|
||||
_, err = r.ExecuteBatch(batch)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RemoveCacheConfigForVehicles(r redis.Client, vins []string) error {
|
||||
batch := redis.NewRedisBatchCommands()
|
||||
for _, vin := range vins {
|
||||
batch.Add("DEL", redis.CarConfigKey(vin))
|
||||
}
|
||||
|
||||
_, err := r.ExecuteBatch(batch)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type IntervalEdgeMask struct {
|
||||
Interval *int
|
||||
EdgeMask *common.BinaryHex
|
||||
}
|
||||
|
||||
type FiltersMap map[string]IntervalEdgeMask
|
||||
|
||||
func (f FiltersMap) AppendFilters(filters []common.CANFilter) {
|
||||
for _, filter := range filters {
|
||||
if filter.EdgeMask != nil && filter.EdgeMask.String() != "" {
|
||||
f[filter.CANID] = IntervalEdgeMask{
|
||||
EdgeMask: filter.EdgeMask,
|
||||
}
|
||||
} else if filter.Interval != nil {
|
||||
f[filter.CANID] = IntervalEdgeMask{
|
||||
Interval: filter.Interval,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f FiltersMap) ToSlice() []common.CANFilter {
|
||||
filters := make([]common.CANFilter, 0, len(f))
|
||||
|
||||
for k, v := range f {
|
||||
filters = append(filters, common.CANFilter{
|
||||
CANID: k,
|
||||
Interval: v.Interval,
|
||||
EdgeMask: v.EdgeMask,
|
||||
})
|
||||
}
|
||||
|
||||
return filters
|
||||
}
|
||||
Reference in New Issue
Block a user