198 lines
5.0 KiB
Go
198 lines
5.0 KiB
Go
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
|
|
}
|