120 строки
3.8 KiB
C++
120 строки
3.8 KiB
C++
#include <iostream>
|
|
#include <iterator>
|
|
#include <regex>
|
|
#include <list>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include "HostsManager.h"
|
|
#include "HttpHelper.h"
|
|
|
|
using namespace hpc::utils;
|
|
using namespace hpc::data;
|
|
using namespace web::http;
|
|
using namespace hpc::core;
|
|
|
|
HostsManager::HostsManager(std::function<std::string(pplx::cancellation_token)> getHostsUri, int fetchInterval)
|
|
{
|
|
this->hostsFetcher =
|
|
std::unique_ptr<HttpFetcher>(
|
|
new HttpFetcher(
|
|
"HostsFetcher",
|
|
getHostsUri,
|
|
0,
|
|
fetchInterval,
|
|
[this](http_request& request)
|
|
{
|
|
if (!this->updateId.empty())
|
|
{
|
|
request.headers().add(UpdateIdHeaderName, this->updateId);
|
|
}
|
|
|
|
return true;
|
|
},
|
|
[this](http_response& response)
|
|
{
|
|
return this->HostsResponseHandler(response);
|
|
},
|
|
[]()
|
|
{
|
|
NamingClient::InvalidateCache();
|
|
}));
|
|
}
|
|
|
|
bool HostsManager::HostsResponseHandler(const http_response& response)
|
|
{
|
|
if (response.status_code() == status_codes::NoContent)
|
|
{
|
|
Logger::Info("Hosts file manager: response received with no update");
|
|
return true;
|
|
}
|
|
else if (response.status_code() != status_codes::OK)
|
|
{
|
|
Logger::Warn("Hosts file manager: failed to fetch hosts file: {0}", response.status_code());
|
|
return false;
|
|
}
|
|
|
|
std::string respUpdateId;
|
|
if (HttpHelper::FindHeader(response, UpdateIdHeaderName, respUpdateId))
|
|
{
|
|
this->updateId = respUpdateId;
|
|
Logger::Info("Hosts file manager: hosts file update received with update Id {0}", respUpdateId);
|
|
std::vector<HostEntry> hostEntries = JsonHelper<std::vector<HostEntry>>::FromJson(response.extract_json().get());
|
|
this->UpdateHostsFile(hostEntries);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void HostsManager::UpdateHostsFile(const std::vector<HostEntry>& hostEntries)
|
|
{
|
|
Logger::Info("Hosts file manager: update local hosts file {0}", HostsFilePath);
|
|
std::list<std::string> unmanagedLines;
|
|
std::ifstream ifs(HostsFilePath, std::ios::in);
|
|
std::string line;
|
|
while (getline(ifs, line))
|
|
{
|
|
std::regex entryRegex(HPCHostEntryPattern);
|
|
std::smatch entryMatch;
|
|
// Strip the original HPC entries
|
|
if(!std::regex_match(line, entryMatch, entryRegex))
|
|
{
|
|
unmanagedLines.push_back(line);
|
|
}
|
|
else
|
|
{
|
|
Logger::Debug("Strip the existing HPC host entry: ({0}, {1})", entryMatch[2], entryMatch[1]);
|
|
}
|
|
}
|
|
|
|
ifs.close();
|
|
|
|
std::ofstream ofs(HostsFilePath);
|
|
auto it = unmanagedLines.cbegin();
|
|
while(it != unmanagedLines.cend())
|
|
{
|
|
ofs << *it++ << std::endl;
|
|
}
|
|
|
|
// Append the HPC entries at the end
|
|
// Make the <NetworkType>.<NodeName> entries at the end
|
|
for(std::size_t i=0; i<hostEntries.size(); i++)
|
|
{
|
|
if (hostEntries[i].HostName.find('.') == std::string::npos)
|
|
{
|
|
Logger::Debug("Add HPC host entry: ({0}, {1})", hostEntries[i].HostName, hostEntries[i].IPAddress);
|
|
ofs << std::left << std::setw(24) << hostEntries[i].IPAddress << std::setw(30) << hostEntries[i].HostName << "#HPC" << std::endl;
|
|
}
|
|
}
|
|
for(std::size_t i=0; i<hostEntries.size(); i++)
|
|
{
|
|
if (hostEntries[i].HostName.find('.') != std::string::npos)
|
|
{
|
|
Logger::Debug("Add HPC host entry: ({0}, {1})", hostEntries[i].HostName, hostEntries[i].IPAddress);
|
|
ofs << std::left << std::setw(24) << hostEntries[i].IPAddress << std::setw(30) << hostEntries[i].HostName << "#HPC" << std::endl;
|
|
}
|
|
}
|
|
ofs.close();
|
|
}
|
|
|