This repository has been archived by the owner on May 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OTA-2536: Preconfigure IpUptaneSecondary with IP address
Signed-off-by: Mike Sul <[email protected]>
- Loading branch information
Mike Sul
committed
Apr 17, 2019
1 parent
99bfcf9
commit 87325ea
Showing
19 changed files
with
391 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include <unordered_map> | ||
|
||
#include "secondary.h" | ||
#include "secondary_config.h" | ||
|
||
#include "ipuptanesecondary.h" | ||
|
||
namespace Primary { | ||
|
||
using SecondaryFactoryRegistry = | ||
std::unordered_map<std::string, std::function<std::shared_ptr<Uptane::SecondaryInterface>(const SecondaryConfig&)>>; | ||
|
||
static SecondaryFactoryRegistry sec_factory_regisrty = { | ||
{IPSecondaryConfig::Type, | ||
[](const SecondaryConfig& config) { | ||
auto ip_sec_cgf = dynamic_cast<const IPSecondaryConfig&>(config); | ||
return Uptane::IpUptaneSecondary::create(ip_sec_cgf.ip, ip_sec_cgf.port); | ||
}}, | ||
// { | ||
// Add another secondary factory here | ||
// } | ||
}; | ||
|
||
static std::shared_ptr<Uptane::SecondaryInterface> createSecondary(const SecondaryConfig& config) { | ||
return (sec_factory_regisrty.at(config.type()))(config); | ||
} | ||
|
||
void initSecondaries(Aktualizr& aktualizr, const boost::filesystem::path& config_file) { | ||
if (!boost::filesystem::exists(config_file)) { | ||
throw std::invalid_argument("Secondary ECUs config file does not exist: " + config_file.string()); | ||
} | ||
|
||
auto secondary_configs = SecondaryConfigParser::parse_config_file(config_file); | ||
|
||
for (auto& config : secondary_configs) { | ||
try { | ||
LOG_INFO << "Creating Secondary of type: " << config->type() << "...\n"; | ||
std::shared_ptr<Uptane::SecondaryInterface> secondary = createSecondary(*config); | ||
|
||
LOG_INFO << "Adding Secondary to Aktualizr." | ||
<< "HW_ID: " << secondary->getHwId() << " Serial: " << secondary->getSerial() << "\n"; | ||
aktualizr.AddSecondary(secondary); | ||
|
||
} catch (const std::exception& exc) { | ||
LOG_ERROR << "Failed to initialize a secondary: " << exc.what(); | ||
LOG_ERROR << "Continue with initialization of the remaining secondaries, if any left.\n"; | ||
// otherwise rethrow the exception | ||
} | ||
} | ||
} | ||
} // namespace Primary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef SECONDARY_H_ | ||
#define SECONDARY_H_ | ||
|
||
#include <boost/filesystem.hpp> | ||
|
||
#include "primary/aktualizr.h" | ||
|
||
namespace Primary { | ||
|
||
void initSecondaries(Aktualizr& aktualizr, const boost::filesystem::path& config_file); | ||
|
||
} // namespace Primary | ||
|
||
#endif // SECONDARY_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <fstream> | ||
#include <iostream> | ||
#include <unordered_map> | ||
|
||
#include "logging/logging.h" | ||
#include "secondary_config.h" | ||
|
||
namespace Primary { | ||
|
||
SecondaryConfigParser::Configs SecondaryConfigParser::parse_config_file(const boost::filesystem::path& config_file) { | ||
if (!boost::filesystem::exists(config_file)) { | ||
throw std::invalid_argument("Specified config file doesn't exist: " + config_file.string()); | ||
} | ||
|
||
auto cfg_file_ext = boost::filesystem::extension(config_file); | ||
std::shared_ptr<SecondaryConfigParser> cfg_parser; | ||
|
||
if (cfg_file_ext == ".json") { | ||
cfg_parser = std::make_shared<JsonConfigParser>(config_file); | ||
} else { // add your format of configuration file + implement SecondaryConfigParser specialization | ||
throw std::invalid_argument("Unsupported type of config format: " + cfg_file_ext); | ||
} | ||
|
||
return cfg_parser->parse(); | ||
} | ||
|
||
/* | ||
config file example | ||
{ | ||
"ip": [ | ||
{"addr": "127.0.0.1:9031"}, | ||
{"addr": "127.0.0.1:9032"} | ||
], | ||
"socketcan": [ | ||
{"key": "value", "key1": "value1"}, | ||
{"key": "value", "key1": "value1"} | ||
] | ||
} | ||
*/ | ||
|
||
JsonConfigParser::JsonConfigParser(const boost::filesystem::path& config_file) { | ||
assert(boost::filesystem::exists(config_file)); | ||
std::ifstream json_file_stream(config_file.string()); | ||
Json::Reader json_reader; | ||
|
||
if (!json_reader.parse(json_file_stream, root_, false)) { | ||
throw std::invalid_argument("Failed to parse secondary config file: " + config_file.string() + ": " + | ||
json_reader.getFormattedErrorMessages()); | ||
} | ||
} | ||
|
||
SecondaryConfigParser::Configs JsonConfigParser::parse() { | ||
Configs res_sec_cfg; | ||
|
||
for (Json::ValueIterator it = root_.begin(); it != root_.end(); ++it) { | ||
std::string secondary_type = it.key().asString(); | ||
|
||
if (sec_cfg_factory_regisrty_.find(secondary_type) == sec_cfg_factory_regisrty_.end()) { | ||
LOG_ERROR << "Unsupported type of sescondary config was found: `" << secondary_type | ||
<< "`. Ingoring it and continue with parsing of other secondary configs"; | ||
} else { | ||
(sec_cfg_factory_regisrty_.at(secondary_type))(res_sec_cfg, *it); | ||
} | ||
} | ||
|
||
return res_sec_cfg; | ||
} | ||
|
||
static std::pair<std::string, uint16_t> getIPAndPort(const std::string& addr) { | ||
auto del_pos = addr.find_first_of(':'); | ||
if (del_pos == std::string::npos) { | ||
throw std::invalid_argument("Incorrect address string, couldn't find port delimeter: " + addr); | ||
} | ||
std::string ip = addr.substr(0, del_pos); | ||
uint16_t port = static_cast<uint16_t>(std::stoul(addr.substr(del_pos + 1))); | ||
|
||
return std::make_pair(ip, port); | ||
} | ||
|
||
void JsonConfigParser::createIPSecondaryConfig(Configs& configs, Json::Value& ip_sec_cfgs) { | ||
for (const auto& ip_sec_cfg : ip_sec_cfgs) { | ||
auto addr = getIPAndPort(ip_sec_cfg[IPSecondaryConfig::AddrField].asString()); | ||
configs.emplace_back(std::make_shared<IPSecondaryConfig>(addr.first, addr.second)); | ||
} | ||
} | ||
|
||
} // namespace Primary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#ifndef SECONDARY_CONFIG_H_ | ||
#define SECONDARY_CONFIG_H_ | ||
|
||
#include <json/json.h> | ||
#include <boost/filesystem.hpp> | ||
#include <unordered_map> | ||
|
||
namespace Primary { | ||
|
||
class SecondaryConfig { | ||
public: | ||
SecondaryConfig(const char* type) : type_(type) {} | ||
virtual const char* type() const { return type_; } | ||
virtual ~SecondaryConfig() = default; | ||
|
||
private: | ||
const char* const type_; | ||
}; | ||
|
||
class IPSecondaryConfig : public SecondaryConfig { | ||
public: | ||
static constexpr const char* Type{"ip"}; | ||
static constexpr const char* AddrField{"addr"}; | ||
|
||
IPSecondaryConfig(std::string addr_ip, uint16_t addr_port) | ||
: SecondaryConfig(Type), ip(std::move(addr_ip)), port(addr_port) {} | ||
|
||
public: | ||
const std::string ip; | ||
const uint16_t port; | ||
}; | ||
|
||
class SecondaryConfigParser { | ||
public: | ||
using Configs = std::vector<std::shared_ptr<SecondaryConfig>>; | ||
|
||
static Configs parse_config_file(const boost::filesystem::path& config_file); | ||
virtual ~SecondaryConfigParser() = default; | ||
|
||
// TODO implement iterator instead of parse | ||
virtual Configs parse() = 0; | ||
}; | ||
|
||
class JsonConfigParser : public SecondaryConfigParser { | ||
public: | ||
JsonConfigParser(const boost::filesystem::path& config_file); | ||
|
||
Configs parse() override; | ||
|
||
private: | ||
static void createIPSecondaryConfig(Configs& configs, Json::Value& ip_sec_cfgs); | ||
// add here a factory method for another type of secondary config | ||
|
||
private: | ||
using SecondaryConfigFactoryRegistry = std::unordered_map<std::string, std::function<void(Configs&, Json::Value&)>>; | ||
|
||
SecondaryConfigFactoryRegistry sec_cfg_factory_regisrty_ = { | ||
{IPSecondaryConfig::Type, createIPSecondaryConfig} | ||
// add here factory method for another type of secondary config | ||
}; | ||
|
||
Json::Value root_; | ||
}; | ||
|
||
} // namespace Primary | ||
|
||
#endif // SECONDARY_CONFIG_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.