Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
reportqueue.cc
1 #include "reportqueue.h"
2 
3 #include <chrono>
4 
5 ReportQueue::ReportQueue(const Config& config_in, std::shared_ptr<HttpInterface> http_client)
6  : config(config_in), http(std::move(http_client)) {
7  thread_ = std::thread(std::bind(&ReportQueue::run, this));
8 }
9 
10 ReportQueue::~ReportQueue() {
11  {
12  std::lock_guard<std::mutex> lock(m_);
13  shutdown_ = true;
14  }
15  cv_.notify_all();
16  thread_.join();
17 
18  LOG_TRACE << "Flushing report queue";
19  flushQueue();
20 }
21 
22 void ReportQueue::run() {
23  // Check if queue is nonempty. If so, move any reports to the Json array and
24  // try to send it to the server. Clear the Json array only if the send
25  // succeeds.
26  std::unique_lock<std::mutex> lock(m_);
27  while (!shutdown_) {
28  flushQueue();
29  cv_.wait_for(lock, std::chrono::seconds(10));
30  }
31 }
32 
33 void ReportQueue::enqueue(std::unique_ptr<ReportEvent> event) {
34  {
35  std::lock_guard<std::mutex> lock(m_);
36  report_queue_.push(std::move(event));
37  }
38  cv_.notify_all();
39 }
40 
41 void ReportQueue::flushQueue() {
42  while (!report_queue_.empty()) {
43  report_array.append(report_queue_.front()->toJson());
44  report_queue_.pop();
45  }
46 
47  if (config.tls.server.empty()) {
48  // Prevent a lot of unnecessary garbage output in uptane vector tests.
49  LOG_TRACE << "No server specified. Clearing report queue.";
50  report_array.clear();
51  }
52 
53  if (!report_array.empty()) {
54  HttpResponse response = http->post(config.tls.server + "/events", report_array);
55 
56  // 404 implies the server does not support this feature. Nothing we can
57  // do, just move along.
58  if (response.http_status_code == 404) {
59  LOG_TRACE << "Server does not support event reports. Clearing report queue.";
60  }
61 
62  if (response.isOk() || response.http_status_code == 404) {
63  report_array.clear();
64  }
65  }
66 }
67 
68 void ReportEvent::setEcu(const Uptane::EcuSerial& ecu) { custom["ecu"] = ecu.ToString(); }
69 void ReportEvent::setCorrelationId(const std::string& correlation_id) {
70  if (correlation_id != "") {
71  custom["correlationId"] = correlation_id;
72  }
73 }
74 
75 Json::Value ReportEvent::toJson() {
76  Json::Value out;
77 
78  out["id"] = id;
79  out["deviceTime"] = timestamp.ToString();
80  out["eventType"]["id"] = type;
81  out["eventType"]["version"] = version;
82  out["event"] = custom;
83 
84  return out;
85 }
86 
87 CampaignAcceptedReport::CampaignAcceptedReport(const std::string& campaign_id) : ReportEvent("campaign_accepted", 0) {
88  custom["campaignId"] = campaign_id;
89 }
90 
91 CampaignDeclinedReport::CampaignDeclinedReport(const std::string& campaign_id) : ReportEvent("campaign_declined", 0) {
92  custom["campaignId"] = campaign_id;
93 }
94 
95 CampaignPostponedReport::CampaignPostponedReport(const std::string& campaign_id)
96  : ReportEvent("campaign_postponed", 0) {
97  custom["campaignId"] = campaign_id;
98 }
99 
100 DevicePausedReport::DevicePausedReport(const std::string& correlation_id) : ReportEvent("DevicePaused", 0) {
101  setCorrelationId(correlation_id);
102 }
103 
104 DeviceResumedReport::DeviceResumedReport(const std::string& correlation_id) : ReportEvent("DeviceResumed", 0) {
105  setCorrelationId(correlation_id);
106 }
107 
108 EcuDownloadStartedReport::EcuDownloadStartedReport(const Uptane::EcuSerial& ecu, const std::string& correlation_id)
109  : ReportEvent("EcuDownloadStarted", 0) {
110  setEcu(ecu);
111  setCorrelationId(correlation_id);
112 }
113 
114 EcuDownloadCompletedReport::EcuDownloadCompletedReport(const Uptane::EcuSerial& ecu, const std::string& correlation_id,
115  bool success)
116  : ReportEvent("EcuDownloadCompleted", 0) {
117  setEcu(ecu);
118  setCorrelationId(correlation_id);
119  custom["success"] = success;
120 }
121 
122 EcuInstallationStartedReport::EcuInstallationStartedReport(const Uptane::EcuSerial& ecu,
123  const std::string& correlation_id)
124  : ReportEvent("EcuInstallationStarted", 0) {
125  setEcu(ecu);
126  setCorrelationId(correlation_id);
127 }
128 
129 EcuInstallationAppliedReport::EcuInstallationAppliedReport(const Uptane::EcuSerial& ecu,
130  const std::string& correlation_id)
131  : ReportEvent("EcuInstallationApplied", 0) {
132  setEcu(ecu);
133  setCorrelationId(correlation_id);
134 }
135 
136 EcuInstallationCompletedReport::EcuInstallationCompletedReport(const Uptane::EcuSerial& ecu,
137  const std::string& correlation_id, bool success)
138  : ReportEvent("EcuInstallationCompleted", 0) {
139  setEcu(ecu);
140  setCorrelationId(correlation_id);
141  custom["success"] = success;
142 }
ReportEvent
Definition: reportqueue.h:17
HttpResponse
Definition: httpinterface.h:17
Config
Configuration object for an aktualizr instance running on a primary ECU.
Definition: config.h:74
Uptane::EcuSerial
Definition: tuf.h:174
event
Aktualizr status events.
Definition: events.h:18