Make Api virtual.

I think this is a bit better than what I had before.
Still a mess, but that's conditional compilation for you.
This commit is contained in:
King_DuckZ 2020-08-29 17:10:41 +01:00
parent 80bfbc640a
commit 4e63e1b246
8 changed files with 233 additions and 97 deletions

View file

@ -67,19 +67,19 @@ int main(int argc, char* argv[]) {
try {
duck::AppConfig app_conf;
std::string_view api_key = (2 == argc ? std::string_view(argv[1]) : app_conf.api_key());
oro::Api oro_api(
auto oro_api = oro::make_api(
duck::g_base_url,
std::string(api_key),
app_api_name().data(),
duck::g_build_purpose
);
print_ping(oro_api);
print_ping(*oro_api);
std::unique_ptr<oro::OriginsDB> db(oro::OriginsDB::make(app_conf.backend(), app_conf.db_path()));
duck::test(
&oro_api,
oro_api.get(),
db.get(),
app_conf.fetch_extra_delay(),
app_conf.worker_threads()

View file

@ -117,6 +117,7 @@ executable(meson.project_name(),
'eventia/event.cpp',
'timer_oro_api.cpp',
'oro/originsdb.cpp',
'oro/api.cpp',
oro_rest_sources,
project_config_file,
install: true,

80
src/oro/api.cpp Normal file
View file

@ -0,0 +1,80 @@
/* Copyright 2020, Michele Santullo
* This file is part of orotool.
*
* Orotool is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Orotool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api.hpp"
#include "orotool_config.hpp"
#if defined(OROTOOL_WITH_RESTCCPP)
# include "private/api_restccpp.hpp"
#elif defined(OROTOOL_WITH_NAP)
# include "private/api_nap.hpp"
#else
# error "No REST backend library specified"
#endif
#if !defined(NDEBUG)
# include <iostream>
#endif
namespace oro {
Api::Api (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
) :
m_prefix(std::move(root_address)),
m_api_key(std::move(api_key)),
m_client_name(std::move(client_name)),
m_client_purpose(std::move(client_purpose))
{
if (not m_prefix.empty() and m_prefix[m_prefix.size() - 1] != '/')
m_prefix.push_back('/');
#if !defined(NDEBUG)
std::cout << "OriginsRO API settings\n" <<
"\troot_address: \"" << m_prefix << "\"\n" <<
"\tapi_key: \"" << m_api_key << "\"\n" <<
"\tclient_name: \"" << m_client_name << "\"\n" <<
"\tclient_purpose: \"" << m_client_purpose << "\"\n" <<
"";
#endif
}
Api::~Api() noexcept = default;
std::unique_ptr<Api> make_api (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
) {
#if defined(OROTOOL_WITH_RESTCCPP)
typedef ApiRestcCpp RetType;
#elif defined(OROTOOL_WITH_NAP)
typedef ApiNap RetType;
#else
# error "No REST backend library specified"
#endif
return std::make_unique<RetType>(
std::move(root_address),
std::move(api_key),
std::move(client_name),
std::move(client_purpose)
);
}
} //namespace oro

View file

@ -27,10 +27,6 @@
#include <utility>
#include <memory>
namespace restc_cpp {
class RestClient;
} //namespace restc_cpp
namespace oro {
struct Header {
@ -73,19 +69,27 @@ public:
std::string&& client_name,
std::string&& client_purpose
);
~Api() noexcept;
virtual ~Api() noexcept;
std::pair<Header, Ping> ping();
std::pair<Header, WhoAmI> who_am_i();
std::pair<Header, Items> items_list();
std::pair<Header, Icons> items_icons();
std::pair<Header, Shops> market_list();
std::pair<Header, Creators> fame_list();
virtual std::pair<Header, Ping> ping() = 0;
virtual std::pair<Header, WhoAmI> who_am_i() = 0;
virtual std::pair<Header, Items> items_list() = 0;
virtual std::pair<Header, Icons> items_icons() = 0;
virtual std::pair<Header, Shops> market_list() = 0;
virtual std::pair<Header, Creators> fame_list() = 0;
private:
struct LocalData;
std::unique_ptr<LocalData> m_local;
protected:
std::string m_prefix;
std::string m_api_key;
std::string m_client_name;
std::string m_client_purpose;
};
std::unique_ptr<Api> make_api (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
);
} //namespace oro

View file

@ -15,63 +15,48 @@
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api.hpp"
#include "nap/quick_rest.hpp"
#include "private/api_nap.hpp"
#include "private/v1_endpoints.hpp"
namespace oro {
struct Api::LocalData {
LocalData (
std::string&& root_address
) :
prefix(std::move(root_address))
{
}
std::string prefix;
nap::QuickRest qrest;
};
Api::Api (
ApiNap::ApiNap (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
) :
m_local(std::make_unique<LocalData>(std::move(root_address)))
Api(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)),
m_qrest()
{
if (not m_local->prefix.empty() and m_local->prefix[m_local->prefix.size() - 1] != '/')
m_local->prefix.push_back('/');
m_local->qrest.add_headers({
{"X-Client", client_name},
{"X-Client-Purpose", client_purpose},
{"x-api-key", api_key}
m_qrest.add_headers({
{"X-Client", m_client_name},
{"X-Client-Purpose", m_client_purpose},
{"x-api-key", m_api_key}
});
m_local->qrest.set_user_agent(std::move(client_name));
m_qrest.set_user_agent(std::string(m_client_name));
}
Api::~Api() noexcept = default;
ApiNap::~ApiNap() noexcept = default;
std::pair<Header, Ping> Api::ping() {
m_local->qrest.fetch(m_local->prefix + g_endpoint_ping);
std::pair<Header, Ping> ApiNap::ping() {
m_qrest.fetch(m_prefix + g_endpoint_ping);
//std::cout << nap::page_fetch(url, client_name).body << '\n';
}
std::pair<Header, WhoAmI> Api::who_am_i() {
std::pair<Header, WhoAmI> ApiNap::who_am_i() {
}
std::pair<Header, Items> Api::items_list() {
std::pair<Header, Items> ApiNap::items_list() {
}
std::pair<Header, Icons> Api::items_icons() {
std::pair<Header, Icons> ApiNap::items_icons() {
}
std::pair<Header, Shops> Api::market_list() {
std::pair<Header, Shops> ApiNap::market_list() {
}
std::pair<Header, Creators> Api::fame_list() {
std::pair<Header, Creators> ApiNap::fame_list() {
}
} //namespace oro

View file

@ -15,7 +15,7 @@
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api.hpp"
#include "private/api_restccpp.hpp"
#include "datatypes.hpp"
#include "private/dateconv.hpp"
#include "private/v1_endpoints.hpp"
@ -178,71 +178,41 @@ namespace {
}
} //unnamed namespace
struct Api::LocalData {
explicit LocalData (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
) :
prefix(std::move(root_address)),
api_key(std::move(api_key)),
client_name(std::move(client_name)),
client_purpose(std::move(client_purpose)),
client(rc::RestClient::Create())
{}
std::string prefix;
std::string api_key;
std::string client_name;
std::string client_purpose;
std::unique_ptr<restc_cpp::RestClient> client;
};
Api::Api (
ApiRestcCpp::ApiRestcCpp (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
) :
m_local(std::make_unique<LocalData>(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)))
Api(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)),
m_client(rc::RestClient::Create())
{
if (not m_local->prefix.empty() and m_local->prefix[m_local->prefix.size() - 1] != '/')
m_local->prefix.push_back('/');
#if !defined(NDEBUG)
std::cout << "OriginsRO API settings\n" <<
"\troot_address: \"" << m_local->prefix << "\"\n" <<
"\tapi_key: \"" << m_local->api_key << "\"\n" <<
"\tclient_name: \"" << m_local->client_name << "\"\n" <<
"\tclient_purpose: \"" << m_local->client_purpose << "\"\n" <<
"";
#endif
}
Api::~Api() noexcept = default;
ApiRestcCpp::~ApiRestcCpp() noexcept = default;
std::pair<Header, Ping> Api::ping() {
return call_rest_api<oro::Ping>(*m_local->client, m_local->prefix + g_endpoint_ping, m_local->api_key, m_local->client_name, m_local->client_purpose);
std::pair<Header, Ping> ApiRestcCpp::ping() {
return call_rest_api<oro::Ping>(*m_client, m_prefix + g_endpoint_ping, m_api_key, m_client_name, m_client_purpose);
}
std::pair<Header, WhoAmI> Api::who_am_i() {
return call_rest_api<oro::WhoAmI>(*m_local->client, m_local->prefix + g_endpoint_whoami, m_local->api_key, m_local->client_name, m_local->client_purpose);
std::pair<Header, WhoAmI> ApiRestcCpp::who_am_i() {
return call_rest_api<oro::WhoAmI>(*m_client, m_prefix + g_endpoint_whoami, m_api_key, m_client_name, m_client_purpose);
}
std::pair<Header, Items> Api::items_list() {
return call_rest_api<oro::Items>(*m_local->client, m_local->prefix + g_endpoint_items_list, m_local->api_key, m_local->client_name, m_local->client_purpose);
std::pair<Header, Items> ApiRestcCpp::items_list() {
return call_rest_api<oro::Items>(*m_client, m_prefix + g_endpoint_items_list, m_api_key, m_client_name, m_client_purpose);
}
std::pair<Header, Icons> Api::items_icons() {
return call_rest_api<oro::Icons>(*m_local->client, m_local->prefix + g_endpoint_items_icons, m_local->api_key, m_local->client_name, m_local->client_purpose);
std::pair<Header, Icons> ApiRestcCpp::items_icons() {
return call_rest_api<oro::Icons>(*m_client, m_prefix + g_endpoint_items_icons, m_api_key, m_client_name, m_client_purpose);
}
std::pair<Header, Shops> Api::market_list() {
return call_rest_api<oro::Shops>(*m_local->client, m_local->prefix + g_endpoint_market_list, m_local->api_key, m_local->client_name, m_local->client_purpose);
std::pair<Header, Shops> ApiRestcCpp::market_list() {
return call_rest_api<oro::Shops>(*m_client, m_prefix + g_endpoint_market_list, m_api_key, m_client_name, m_client_purpose);
}
std::pair<Header, Creators> Api::fame_list() {
return call_rest_api<oro::Creators>(*m_local->client, m_local->prefix + g_endpoint_fame_list, m_local->api_key, m_local->client_name, m_local->client_purpose);
std::pair<Header, Creators> ApiRestcCpp::fame_list() {
return call_rest_api<oro::Creators>(*m_client, m_prefix + g_endpoint_fame_list, m_api_key, m_client_name, m_client_purpose);
}
} //namespace oro

View file

@ -0,0 +1,47 @@
/* Copyright 2020, Michele Santullo
* This file is part of orotool.
*
* Orotool is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Orotool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "oro/api.hpp"
#include "nap/quick_rest.hpp"
namespace oro {
class ApiNap : public Api {
public:
ApiNap (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
);
virtual ~ApiNap() noexcept;
virtual std::pair<Header, Ping> ping() override;
virtual std::pair<Header, WhoAmI> who_am_i() override;
virtual std::pair<Header, Items> items_list() override;
virtual std::pair<Header, Icons> items_icons() override;
virtual std::pair<Header, Shops> market_list() override;
virtual std::pair<Header, Creators> fame_list() override;
private:
nap::QuickRest m_qrest;
};
} //namespace oro

View file

@ -0,0 +1,49 @@
/* Copyright 2020, Michele Santullo
* This file is part of orotool.
*
* Orotool is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Orotool is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "oro/api.hpp"
namespace restc_cpp {
class RestClient;
} //namespace restc_cpp
namespace oro {
class ApiRestcCpp : public Api {
public:
ApiRestcCpp (
std::string&& root_address,
std::string&& api_key,
std::string&& client_name,
std::string&& client_purpose
);
~ApiRestcCpp() noexcept;
virtual std::pair<Header, Ping> ping() override;
virtual std::pair<Header, WhoAmI> who_am_i() override;
virtual std::pair<Header, Items> items_list() override;
virtual std::pair<Header, Icons> items_icons() override;
virtual std::pair<Header, Shops> market_list() override;
virtual std::pair<Header, Creators> fame_list() override;
private:
std::unique_ptr<restc_cpp::RestClient> m_client;
};
} //namespace oro