@@ -30,6 +30,26 @@ namespace Plugin {
30
30
31
31
const uint32_t POPULATE_DEVICE_INFO_RETRY_MS = 3000 ;
32
32
33
+ class AnalyticsConfig : public Core ::JSON::Container {
34
+ private:
35
+ AnalyticsConfig (const AnalyticsConfig&) = delete ;
36
+ AnalyticsConfig& operator =(const AnalyticsConfig&) = delete ;
37
+
38
+ public:
39
+ AnalyticsConfig ()
40
+ : Core::JSON::Container()
41
+ , EventsMap()
42
+ {
43
+ Add (_T (" eventsmap" ), &EventsMap);
44
+ }
45
+ ~AnalyticsConfig ()
46
+ {
47
+ }
48
+
49
+ public:
50
+ Core::JSON::String EventsMap;
51
+ };
52
+
33
53
SERVICE_REGISTRATION (AnalyticsImplementation, 1 , 0 );
34
54
35
55
AnalyticsImplementation::AnalyticsImplementation ():
@@ -146,6 +166,21 @@ namespace Plugin {
146
166
backend.second ->Configure (shell, mSysTime );
147
167
}
148
168
169
+ std::string configLine = mShell ->ConfigLine ();
170
+ Core::OptionalType<Core::JSON::Error> error;
171
+ AnalyticsConfig config;
172
+
173
+ if (config.FromString (configLine, error) == false )
174
+ {
175
+ SYSLOG (Logging::ParsingError,
176
+ (_T (" Failed to parse config line, error: '%s', config line: '%s'." ),
177
+ (error.IsSet () ? error.Value ().Message ().c_str () : " Unknown" ),
178
+ configLine.c_str ()));
179
+ }
180
+
181
+ LOGINFO (" EventsMap: %s" , config.EventsMap .Value ().c_str ());
182
+ ParseEventsMapFile (config.EventsMap .Value ());
183
+
149
184
return result;
150
185
}
151
186
@@ -273,27 +308,41 @@ namespace Plugin {
273
308
274
309
void AnalyticsImplementation::SendEventToBackend (const AnalyticsImplementation::Event& event)
275
310
{
276
- // TODO: Add mapping of event source/name to backend
277
311
IAnalyticsBackend::Event backendEvent;
278
- backendEvent.eventName = event.eventName ;
312
+ backendEvent.eventName = mEventMapper .MapEventNameIfNeeded (event.eventName , event.eventSource ,
313
+ event.eventSourceVersion , event.eventVersion );
279
314
backendEvent.eventVersion = event.eventVersion ;
280
315
backendEvent.eventSource = event.eventSource ;
281
316
backendEvent.eventSourceVersion = event.eventSourceVersion ;
282
317
backendEvent.epochTimestamp = event.epochTimestamp ;
283
318
backendEvent.eventPayload = event.eventPayload ;
284
319
backendEvent.cetList = event.cetList ;
285
320
321
+ // TODO: Add mapping of event source/name to the desired backend
286
322
if (mBackends .empty ())
287
323
{
288
324
LOGINFO (" No backends available!" );
289
325
}
290
326
else if (mBackends .find (IAnalyticsBackend::SIFT) != mBackends .end ())
291
327
{
292
- LOGINFO (" Sending event to Sift backend: %s" , event .eventName .c_str ());
328
+ LOGINFO (" Sending event to Sift backend: %s" , backendEvent .eventName .c_str ());
293
329
mBackends .at (IAnalyticsBackend::SIFT)->SendEvent (backendEvent);
294
330
}
295
331
}
296
332
333
+ void AnalyticsImplementation::ParseEventsMapFile (const std::string& eventsMapFile)
334
+ {
335
+ if (eventsMapFile.empty ())
336
+ {
337
+ LOGINFO (" Events map file path is empty, skipping parsing" );
338
+ return ;
339
+ }
340
+ std::ifstream t (eventsMapFile);
341
+ std::string str ((std::istreambuf_iterator<char >(t)),
342
+ std::istreambuf_iterator<char >());
343
+ mEventMapper .FromString (str);
344
+ }
345
+
297
346
uint64_t AnalyticsImplementation::GetCurrentTimestampInMs ()
298
347
{
299
348
return std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now ().time_since_epoch () ).count ();
@@ -319,5 +368,102 @@ namespace Plugin {
319
368
return currentTimestamp - uptimeDiff;
320
369
}
321
370
371
+ void AnalyticsImplementation::EventMapper::FromString (const std::string &jsonArrayStr)
372
+ {
373
+ // expect json array:
374
+ // [
375
+ // {
376
+ // "event_name": "event_name",
377
+ // "event_source": "event_source",
378
+ // "event_source_version": "event_source_version", - optional
379
+ // "event_version": "event_version", - optional
380
+ // "mapped_event_name": "mapped_event_name"
381
+ // }
382
+ // ]
383
+ if (jsonArrayStr.empty ())
384
+ {
385
+ LOGERR (" Empty events map json array string" );
386
+ return ;
387
+ }
388
+
389
+ JsonArray array;
390
+ array.FromString (jsonArrayStr);
391
+
392
+ if (array.Length () == 0 )
393
+ {
394
+ LOGERR (" Empty or corrupted events map json array" );
395
+ return ;
396
+ }
397
+
398
+ for (int i = 0 ; i < array.Length (); i++)
399
+ {
400
+ JsonObject entry = array[i].Object ();
401
+ if (entry.HasLabel (" event_name" ) && entry.HasLabel (" event_source" ) && entry.HasLabel (" mapped_event_name" ))
402
+ {
403
+ AnalyticsImplementation::EventMapper::Key key{
404
+ entry[" event_name" ].String (),
405
+ entry[" event_source" ].String (),
406
+ entry.HasLabel (" event_source_version" ) ? entry[" event_source_version" ].String () : " " ,
407
+ entry.HasLabel (" event_version" ) ? entry[" event_version" ].String () : " " };
408
+
409
+ std::string mapped_event_name = entry[" mapped_event_name" ].String ();
410
+ map[key] = mapped_event_name;
411
+ LOGINFO (" Index %d: Mapped event: %s -> %s" , i, entry[" event_name" ].String ().c_str (), mapped_event_name.c_str ());
412
+ }
413
+ else
414
+ {
415
+ LOGERR (" Invalid entry in events map file at index %d" , i);
416
+ }
417
+ }
418
+ }
419
+
420
+ std::string AnalyticsImplementation::EventMapper::MapEventNameIfNeeded (const std::string &eventName,
421
+ const std::string &eventSource,
422
+ const std::string &eventSourceVersion,
423
+ const std::string &eventVersion) const
424
+ {
425
+ // Try exact match
426
+ AnalyticsImplementation::EventMapper::Key key{eventName, eventSource, eventSourceVersion, eventVersion};
427
+ auto it = map.find (key);
428
+ if (it != map.end ())
429
+ {
430
+ return it->second ;
431
+ }
432
+
433
+ // Try without eventVersion
434
+ if (!eventVersion.empty ())
435
+ {
436
+ AnalyticsImplementation::EventMapper::Key partialKey{eventName, eventSource, eventSourceVersion, " " };
437
+ it = map.find (partialKey);
438
+ if (it != map.end ())
439
+ {
440
+ return it->second ;
441
+ }
442
+ }
443
+
444
+ // Try without eventSourceVersion
445
+ if (!eventSourceVersion.empty ())
446
+ {
447
+ AnalyticsImplementation::EventMapper::Key partialKey{eventName, eventSource, " " , eventVersion};
448
+ it = map.find (partialKey);
449
+ if (it != map.end ())
450
+ {
451
+ return it->second ;
452
+ }
453
+ }
454
+
455
+ // Try without both eventSourceVersion and eventVersion
456
+ if (!eventSourceVersion.empty () || !eventVersion.empty ())
457
+ {
458
+ AnalyticsImplementation::EventMapper::Key partialKey{eventName, eventSource, " " , " " };
459
+ it = map.find (partialKey);
460
+ if (it != map.end ())
461
+ {
462
+ return it->second ;
463
+ }
464
+ }
465
+
466
+ return eventName; // Not found, nothing to map
467
+ }
322
468
}
323
469
}
0 commit comments