Aktualizr
C++ SOTA Client
campaign.cc
1 #include "libaktualizr/campaign.h"
2 #include "http/httpclient.h"
3 #include "utilities/utils.h"
4 
5 namespace campaign {
6 
7 Campaign::Campaign(const Json::Value &json) {
8  try {
9  if (!json.isObject()) {
10  throw CampaignParseError();
11  }
12 
13  id = json["id"].asString();
14  if (id.empty()) {
15  throw CampaignParseError();
16  }
17 
18  name = json["name"].asString();
19  if (name.empty()) {
20  throw CampaignParseError();
21  }
22 
23  size = json.get("size", 0).asInt64();
24  autoAccept = json.get("autoAccept", false).asBool();
25 
26  for (const auto &o : json["metadata"]) {
27  if (!o.isObject()) {
28  continue;
29  }
30 
31  if (o["type"] == "DESCRIPTION") {
32  if (!description.empty()) {
33  throw CampaignParseError();
34  }
35  description = o["value"].asString();
36  } else if (o["type"] == "ESTIMATED_INSTALLATION_DURATION") {
37  if (estInstallationDuration != 0) {
38  throw CampaignParseError();
39  }
40  estInstallationDuration = std::stoi(o["value"].asString());
41  } else if (o["type"] == "ESTIMATED_PREPARATION_DURATION") {
42  if (estPreparationDuration != 0) {
43  throw CampaignParseError();
44  }
45  estPreparationDuration = std::stoi(o["value"].asString());
46  }
47  }
48 
49  } catch (const std::runtime_error &exc) {
50  LOG_ERROR << exc.what();
51  throw CampaignParseError();
52  } catch (...) {
53  throw CampaignParseError();
54  }
55 }
56 
57 void Campaign::getJson(Json::Value &out) const {
58  out.clear();
59 
60  out["id"] = id;
61  out["name"] = name;
62  out["size"] = Json::UInt(size);
63  out["autoAccept"] = autoAccept;
64 
65  out["metadata"][0]["type"] = "DESCRIPTION";
66  out["metadata"][0]["value"] = description;
67  out["metadata"][1]["type"] = "ESTIMATED_INSTALLATION_DURATION";
68  out["metadata"][1]["value"] = std::to_string(estInstallationDuration);
69  out["metadata"][2]["type"] = "ESTIMATED_PREPARATION_DURATION";
70  out["metadata"][2]["value"] = std::to_string(estPreparationDuration);
71 }
72 
73 std::vector<Campaign> Campaign::campaignsFromJson(const Json::Value &json) {
74  std::vector<Campaign> campaigns;
75 
76  Json::Value campaigns_array;
77  try {
78  if (!json.isObject()) {
79  throw CampaignParseError();
80  }
81  campaigns_array = json["campaigns"];
82  if (!campaigns_array.isArray()) {
83  throw CampaignParseError();
84  }
85  } catch (...) {
86  LOG_ERROR << "Invalid campaigns object: " << json;
87  return {};
88  }
89 
90  for (const auto &c : campaigns_array) {
91  try {
92  campaigns.emplace_back(Campaign(c));
93  } catch (const CampaignParseError &exc) {
94  LOG_ERROR << "Error parsing " << c << ": " << exc.what();
95  }
96  }
97  return campaigns;
98 }
99 
100 void Campaign::JsonFromCampaigns(const std::vector<Campaign> &in, Json::Value &out) {
101  out.clear();
102  auto i = 0;
103  Json::Value json;
104  for (const auto &c : in) {
105  c.getJson(json);
106  out["campaigns"][i] = json;
107  ++i;
108  }
109 }
110 
111 std::vector<Campaign> Campaign::fetchAvailableCampaigns(HttpInterface &http_client, const std::string &tls_server) {
112  HttpResponse response = http_client.get(tls_server + "/campaigner/campaigns", kMaxCampaignsMetaSize);
113  if (!response.isOk()) {
114  LOG_ERROR << "Failed to fetch list of available campaigns";
115  return {};
116  }
117 
118  auto json = response.getJson();
119 
120  LOG_TRACE << "Campaign: " << json;
121 
122  return campaignsFromJson(json);
123 }
124 } // namespace campaign
HttpInterface
Definition: httpinterface.h:38
HttpResponse
Definition: httpinterface.h:17