Skip to content

Commit

Permalink
Merge branch 'main' into feature/constraint_operators
Browse files Browse the repository at this point in the history
  • Loading branch information
bolomcs50 authored Feb 15, 2024
2 parents ff5d41c + 6e86a5e commit cf09981
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "client-specification"]
path = client-specification
url = git@github.com:Unleash/client-specification.git
url = https://github.com/Unleash/client-specification.git
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ The below table shows what features the SDKs support or plan to support.
- [x] Strategy constrains
- [x] Application registration
- [x] Variants
- [ ] Custom stickiness (WIP)
- [ ] Bootstraping
- [ ] Usage Metrics
- [ ] Custom stickiness

## Requirements

Expand Down
4 changes: 3 additions & 1 deletion include/unleash/api/cprclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
namespace unleash {
class CprClient : public ApiClient {
public:
CprClient(std::string url, std::string name, std::string instanceId, std::string authentication = std::string());
CprClient(std::string url, std::string name, std::string instanceId, std::string authentication = std::string(),
std::string caInfo = std::string());
std::string features() override;
bool registration(unsigned int refreshInterval) override;

Expand All @@ -15,6 +16,7 @@ class CprClient : public ApiClient {
std::string m_instanceId;
std::string m_name;
std::string m_authentication;
std::string m_caInfo;
};
} // namespace unleash
#endif //UNLEASH_CPRCLIENT_H
3 changes: 3 additions & 0 deletions include/unleash/unleashclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class UNLEASH_EXPORT UnleashClient {
friend UNLEASH_EXPORT std::ostream &operator<<(std::ostream &os, const UnleashClient &obj);
static UnleashClientBuilder create(std::string name, std::string url);
void initializeClient();
std::vector<std::string> featureFlags() const;
bool isEnabled(const std::string &flag);
bool isEnabled(const std::string &flag, const Context &context);
variant_t variant(const std::string &flag, const Context &context);
Expand All @@ -43,6 +44,7 @@ class UNLEASH_EXPORT UnleashClient {
std::string m_authentication;
bool m_registration = false;
std::string m_cacheFilePath;
std::string m_caInfo;
unsigned int m_refreshInterval = 15000;
std::thread m_thread;
bool m_stopThread = false;
Expand All @@ -67,6 +69,7 @@ class UNLEASH_EXPORT UnleashClientBuilder {
UnleashClientBuilder &authentication(std::string authentication);
UnleashClientBuilder &registration(bool registration);
UnleashClientBuilder &cacheFilePath(std::string cacheFilePath);
UnleashClientBuilder &caInfo(std::string caInfo);

private:
UnleashClient unleashClient;
Expand Down
38 changes: 30 additions & 8 deletions src/api/cprclient.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
#include "unleash/api/cprclient.h"
#include <chrono>
#include <cpr/cpr.h>
#include <cpr/ssl_options.h>
#include <iostream>
#include <nlohmann/json.hpp>

namespace unleash {
CprClient::CprClient(std::string url, std::string name, std::string instanceId, std::string authentication)
CprClient::CprClient(std::string url, std::string name, std::string instanceId, std::string authentication,
std::string caInfo)
: m_url(std::move(url)), m_instanceId(std::move(instanceId)), m_name(std::move(name)),
m_authentication(std::move(authentication)) {}
m_authentication(std::move(authentication)), m_caInfo(std::move(caInfo)) {}

std::string CprClient::features() {
auto response = cpr::Get(cpr::Url{m_url + "/client/features"}, cpr::Header{{"UNLEASH-INSTANCEID", m_instanceId},
{"UNLEASH-APPNAME", m_name},
{"Authorization", m_authentication}});
cpr::SslOptions sslOptions;


if (!m_caInfo.empty()) {
// since CaInfo takes an rvalue reference and we don't want to move the m_caInfo in
// we create a copy of it and move it in
std::string copyOfCaInfo = m_caInfo;
sslOptions = cpr::Ssl(cpr::ssl::CaInfo{std::move(copyOfCaInfo)});
}
auto response = cpr::Get(cpr::Url{m_url + "/client/features"},
cpr::Header{{"UNLEASH-INSTANCEID", m_instanceId},
{"UNLEASH-APPNAME", m_name},
{"Authorization", m_authentication}},
sslOptions);
if (response.status_code == 0) {
std::cerr << response.error.message << std::endl;
return std::string{};
Expand All @@ -24,15 +37,24 @@ std::string CprClient::features() {
}

bool CprClient::registration(unsigned int refreshInterval) {
cpr::SslOptions sslOptions;


if (!m_caInfo.empty()) {
// since CaInfo takes an rvalue reference and we don't want to move the m_caInfo in
// we create a copy of it and move it in
std::string copyOfCaInfo = m_caInfo;
sslOptions = cpr::Ssl(cpr::ssl::CaInfo{std::move(copyOfCaInfo)});
}
nlohmann::json payload;
payload["appName"] = m_name;
payload["interval"] = refreshInterval;
payload["started"] = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
payload["strategies"] = {"default", "userWithId", "flexibleRollout", "remoteAddress", "applicationHostname"};

if (auto response =
cpr::Post(cpr::Url{m_url + "/client/register"}, cpr::Body{payload.dump()},
cpr::Header{{"Authorization", m_authentication}, {"Content-Type", "application/json"}});
if (auto response = cpr::Post(
cpr::Url{m_url + "/client/register"}, cpr::Body{payload.dump()},
cpr::Header{{"Authorization", m_authentication}, {"Content-Type", "application/json"}}, sslOptions);
response.status_code == 0) {
std::cerr << response.error.message << std::endl;
} else if (response.status_code >= 400) {
Expand Down
17 changes: 16 additions & 1 deletion src/unleashclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,16 @@ UnleashClientBuilder &UnleashClientBuilder::cacheFilePath(std::string cacheFileP
return *this;
}

UnleashClientBuilder &UnleashClientBuilder::caInfo(std::string caInfo) {
unleashClient.m_caInfo = std::move(caInfo);
return *this;
}

void UnleashClient::initializeClient() {
if (!m_isInitialized) {
// Set-up Unleash API client
if (m_apiClient == nullptr) {
m_apiClient = std::make_unique<CprClient>(m_url, m_name, m_instanceId, m_authentication);
m_apiClient = std::make_unique<CprClient>(m_url, m_name, m_instanceId, m_authentication, m_caInfo);
}

// Register the Client
Expand Down Expand Up @@ -130,6 +135,16 @@ UnleashClient::~UnleashClient() {
if (m_thread.joinable()) m_thread.join();
}

std::vector<std::string> UnleashClient::featureFlags() const {
std::vector<std::string> featureFlags;
if (m_isInitialized) {
for (auto it = m_features.begin(); it != m_features.end(); it++) {
featureFlags.push_back(it->first);
}
}
return featureFlags;
}

bool UnleashClient::isEnabled(const std::string &flag) {
Context context;
return isEnabled(flag, context);
Expand Down

0 comments on commit cf09981

Please sign in to comment.