88 "strconv"
99 "time"
1010
11+ "github.com/DIMO-Network/shared/pkg/logfields"
12+
1113 "github.com/tidwall/sjson"
1214
1315 "github.com/DIMO-Network/device-definitions-api/internal/infrastructure/metrics"
@@ -74,15 +76,20 @@ func NewDecodeVINQueryHandler(dbs func() *db.ReaderWriter, vinDecodingService se
7476func (dc DecodeVINQueryHandler ) Handle (ctx context.Context , query mediator.Message ) (interface {}, error ) {
7577 qry := query .(* DecodeVINQuery )
7678 if len (qry .VIN ) < 10 || len (qry .VIN ) > 17 {
77- return nil , & exceptions.ValidationError {Err : fmt .Errorf ("invalid vin %s" , qry .VIN )}
79+ return nil , & exceptions.ValidationError {Err : fmt .Errorf ("invalid VIN %s" , qry .VIN )}
7880 }
7981 resp := & p_grpc.DecodeVinResponse {}
80- vin := vin .VIN (qry .VIN )
81- resp .Year = int32 (vin .Year ())
82- wmi := vin .Wmi ()
82+ vinObj := vin .VIN (qry .VIN )
83+
84+ if ! vinObj .IsValidJapanChassis () && ! vinObj .IsValidVIN () {
85+ return nil , & exceptions.ValidationError {Err : fmt .Errorf ("invalid VIN %s" , qry .VIN )}
86+ }
87+
88+ resp .Year = int32 (vinObj .Year ())
89+ wmi := vinObj .Wmi ()
8390
8491 localLog := dc .logger .With ().
85- Str ("vin" , vin .String ()).
92+ Str (logfields . VIN , vinObj .String ()).
8693 Str ("handler" , query .Key ()).
8794 Str ("vinYear" , fmt .Sprintf ("%d" , resp .Year )).
8895 Str ("knownModel" , qry .KnownModel ).
@@ -104,7 +111,7 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
104111 }
105112 defer txVinNumbers .Rollback () //nolint
106113 vinDecodeNumber , err := models .VinNumbers (
107- models .VinNumberWhere .Vin .EQ (vin .String ())).
114+ models .VinNumberWhere .Vin .EQ (vinObj .String ())).
108115 One (ctx , txVinNumbers )
109116 if err != nil && ! errors .Is (err , sql .ErrNoRows ) {
110117 metrics .InternalError .With (prometheus.Labels {"method" : VinErrors }).Inc ()
@@ -126,28 +133,28 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
126133 // future: see if we can self decode model based on data we have before calling external decode WMI and VDS. Only thing is we won't get the style.
127134
128135 if resp .Year == 0 || resp .Year > int32 (time .Now ().Year ()+ 1 ) {
129- localLog .Info ().Msgf ("encountered vin with non-standard year digit" )
136+ localLog .Info ().Msgf ("encountered vinObj with non-standard year digit" )
130137 }
131138 // check if this is a Tesla VIN, if not just follow regular path
132139 vinInfo := & coremodels.VINDecodingInfoData {}
133140 dbWMI , err := models .Wmis (models .WmiWhere .Wmi .EQ (wmi )).One (ctx , dc .dbs ().Reader )
134141 if err == nil && dbWMI != nil {
135142 if dbWMI .ManufacturerName == "Tesla" {
136- vinInfo , err = dc .vinDecodingService .GetVIN (ctx , vin .String (), coremodels .TeslaProvider , qry .Country )
143+ vinInfo , err = dc .vinDecodingService .GetVIN (ctx , vinObj .String (), coremodels .TeslaProvider , qry .Country )
137144 resp .Manufacturer = "Tesla"
138145 }
139146 }
140147 // not a tesla, regular decode path
141148 if vinInfo == nil || vinInfo .Model == "" {
142- vinInfo , err = dc .vinDecodingService .GetVIN (ctx , vin .String (), coremodels .AllProviders , qry .Country ) // this will try drivly first unless of japan
149+ vinInfo , err = dc .vinDecodingService .GetVIN (ctx , vinObj .String (), coremodels .AllProviders , qry .Country ) // this will try drivly first unless of japan
143150 }
144151
145152 // if no luck decoding VIN, try buildingVinInfo from known data passed in, typically smartcar or software connections
146153 if err != nil {
147154 if len (qry .KnownModel ) > 0 && qry .KnownYear > 0 {
148155 // note if this is successful, err gets set to nil
149156 // todo: the knownModel should correspond with the Make
150- vinInfo , err = dc .vinInfoFromKnown (vin , qry .KnownModel , qry .KnownYear )
157+ vinInfo , err = dc .vinInfoFromKnown (vinObj , qry .KnownModel , qry .KnownYear )
151158 }
152159 }
153160
@@ -160,7 +167,7 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
160167 if err == nil {
161168 err = errors .New ("failed to decode, vinInfo is nil" )
162169 }
163- localLog .Err (err ).Msgf ("failed to decode vin from provider, country: %s" , qry .Country )
170+ localLog .Err (err ).Msgf ("failed to decode vinObj from provider, country: %s" , qry .Country )
164171 // todo track failed decodes
165172 return nil , err
166173 }
@@ -169,7 +176,7 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
169176 _ , err = dc .vinRepository .GetOrCreateWMI (ctx , wmi , vinInfo .Make )
170177 if err != nil {
171178 // just log, Japan chasis numbers won't really work with this anyways
172- dc .logger .Error ().Err (err ).Msgf ("failed to get or create wmi for vin %s" , vin .String ())
179+ dc .logger .Error ().Err (err ).Msgf ("failed to get or create wmi for vinObj %s" , vinObj .String ())
173180 }
174181 }
175182 resp .Manufacturer = vinInfo .Make
@@ -183,11 +190,11 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
183190
184191 tblDef , _ , errTbl := dc .deviceDefinitionOnChainService .GetDefinitionByID (ctx , tid )
185192 if errTbl != nil {
186- dc .logger .Warn ().Err (errTbl ).Msgf ("failed to get definition from tableland for vin : %s, id: %s" , vin .String (), tid )
193+ dc .logger .Warn ().Err (errTbl ).Msgf ("failed to get definition from tableland for vinObj : %s, id: %s" , vinObj .String (), tid )
187194 } else if tblDef == nil {
188- dc .logger .Warn ().Msgf ("failed to get definition from tableland for vin : %s, id: %s" , vin .String (), tid )
195+ dc .logger .Warn ().Msgf ("failed to get definition from tableland for vinObj : %s, id: %s" , vinObj .String (), tid )
189196 } else {
190- dc .logger .Info ().Str ("vin" , vin .String ()).Msgf ("found definition from tableland %s: %+v" , tid , tblDef )
197+ dc .logger .Info ().Str (logfields . VIN , vinObj .String ()).Msgf ("found definition from tableland %s: %+v" , tid , tblDef )
191198 }
192199
193200 // add images if we don't have any for this definition_id
@@ -236,7 +243,7 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
236243 })
237244 if err != nil {
238245 metrics .InternalError .With (prometheus.Labels {"method" : VinErrors }).Inc ()
239- return nil , errors .Wrap (err , "error creating new device definition on-chain from decoded vin " )
246+ return nil , errors .Wrap (err , "error creating new device definition on-chain from decoded vinObj " )
240247 }
241248 resp .NewTrxHash = * trx
242249 }
@@ -248,22 +255,22 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
248255 var styleErr error
249256 resp .DeviceStyleId , styleErr = dc .processDeviceStyle (ctx , vinInfo , tid , resp .Powertrain )
250257 if styleErr != nil {
251- dc .logger .Error ().Err (styleErr ).Msgf ("error processing device style for vin : %s. continuing" , vin .String ())
258+ dc .logger .Error ().Err (styleErr ).Msgf ("error processing device style for vinObj : %s. continuing" , vinObj .String ())
252259 }
253260 }
254261
255262 // insert vin_numbers
256- errVinNumber := dc .saveVinDecodeNumber (ctx , vin , vinInfo , resp )
263+ errVinNumber := dc .saveVinDecodeNumber (ctx , vinObj , vinInfo , resp )
257264 if errVinNumber != nil {
258265 return nil , errors .Wrap (errVinNumber , "error saving vin_number" )
259266 }
260267
261268 localLog .Info ().Str ("device_definition_id" , resp .DefinitionId ).
262269 Str ("style_id" , resp .DeviceStyleId ).
263270 Str ("wmi" , wmi ).
264- Str ("vds" , vin .VDS ()).
265- Str ("vis" , vin .VIS ()).
266- Str ("check_digit" , vin .CheckDigit ()).Msgf ("decoded vin ok with: %s" , vinInfo .Source )
271+ Str ("vds" , vinObj .VDS ()).
272+ Str ("vis" , vinObj .VIS ()).
273+ Str ("check_digit" , vinObj .CheckDigit ()).Msgf ("decoded vinObj ok with: %s" , vinInfo .Source )
267274
268275 metrics .Success .With (prometheus.Labels {"method" : VinSuccess }).Inc ()
269276
@@ -367,20 +374,20 @@ func (dc DecodeVINQueryHandler) processDeviceStyle(ctx context.Context, vinInfo
367374 return style .ID , nil
368375}
369376
370- func (dc DecodeVINQueryHandler ) saveVinDecodeNumber (ctx context.Context , vin vin.VIN , vinInfo * coremodels.VINDecodingInfoData , resp * p_grpc.DecodeVinResponse ) error {
377+ func (dc DecodeVINQueryHandler ) saveVinDecodeNumber (ctx context.Context , vinObj vin.VIN , vinInfo * coremodels.VINDecodingInfoData , resp * p_grpc.DecodeVinResponse ) error {
371378 vinDecodeNumber := & models.VinNumber {
372- Vin : vin .String (),
379+ Vin : vinObj .String (),
373380 ManufacturerName : resp .Manufacturer ,
374- Wmi : null .StringFrom (vin .Wmi ()),
375- SerialNumber : vin .SerialNumber (),
381+ Wmi : null .StringFrom (vinObj .Wmi ()),
382+ SerialNumber : vinObj .SerialNumber (),
376383 DecodeProvider : null .StringFrom (string (vinInfo .Source )),
377384 Year : int (resp .Year ),
378385 DefinitionID : resp .DefinitionId ,
379386 }
380- if ! vin . IsJapanChassis () {
381- vinDecodeNumber .VDS = null .StringFrom (vin .VDS ())
382- vinDecodeNumber .Vis = null .StringFrom (vin .VIS ())
383- vinDecodeNumber .CheckDigit = null .StringFrom (vin .CheckDigit ())
387+ if vinObj . IsValidVIN () {
388+ vinDecodeNumber .VDS = null .StringFrom (vinObj .VDS ())
389+ vinDecodeNumber .Vis = null .StringFrom (vinObj .VIS ())
390+ vinDecodeNumber .CheckDigit = null .StringFrom (vinObj .CheckDigit ())
384391 }
385392
386393 // Optional fields based on response and VIN info
@@ -409,6 +416,8 @@ func (dc DecodeVINQueryHandler) saveVinDecodeNumber(ctx context.Context, vin vin
409416 if len (vinInfo .Raw ) > 0 {
410417 vinDecodeNumber .Vin17Data = null .JSONFrom (vinInfo .Raw )
411418 }
419+ case coremodels .CarVXVIN :
420+ // we currently do not store the raw payload since seemed to not gain much for now
412421 }
413422
414423 // Insert VIN decode number into the database
0 commit comments