Skip to content

Commit 10763e7

Browse files
authored
feat: add ServiceEndpoints builder & struct [1/2] (#2)
* feat: add ServiceEndpoints within launchdarkly::config * feat: add Config structure (#4)
1 parent ab2b0fe commit 10763e7

15 files changed

+635
-2
lines changed

libs/common/include/config/client.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "config/detail/config_builder.hpp"
4+
#include "config/detail/endpoints_builder.hpp"
5+
#include "config/detail/sdks.hpp"
6+
7+
namespace launchdarkly::client {
8+
9+
using SDK = config::detail::ClientSDK;
10+
11+
using EndpointsBuilder = config::detail::EndpointsBuilder<SDK>;
12+
using ConfigBuilder = config::detail::ConfigBuilder<SDK>;
13+
using Config = config::detail::Config<SDK>;
14+
15+
} // namespace launchdarkly::client
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include "config/detail/endpoints_builder.hpp"
4+
5+
namespace launchdarkly::config::detail {
6+
7+
/**
8+
* Config represents the configuration for a LaunchDarkly C++ SDK.
9+
* It should be passed into an instance of Client.
10+
* @tparam SDK Type of SDK.
11+
*/
12+
template <typename SDK>
13+
struct Config {
14+
std::string sdk_key;
15+
bool offline;
16+
detail::EndpointsBuilder<SDK> service_endpoints_builder;
17+
Config(std::string sdk_key,
18+
bool offline,
19+
detail::EndpointsBuilder<SDK> service_endpoints_builder);
20+
};
21+
22+
} // namespace launchdarkly::config::detail
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <optional>
4+
#include <string>
5+
#include "config/detail/config.hpp"
6+
#include "config/detail/endpoints_builder.hpp"
7+
8+
namespace launchdarkly::config::detail {
9+
10+
/**
11+
* ConfigBuilder allows for creation of a Configuration object for use
12+
* in a Client.
13+
* @tparam SDK Type of SDK.
14+
*/
15+
template <typename SDK>
16+
class ConfigBuilder {
17+
public:
18+
using EndpointsBuilder = detail::EndpointsBuilder<SDK>;
19+
using ConfigType = detail::Config<SDK>;
20+
/**
21+
* A minimal configuration consists of a LaunchDarkly SDK Key.
22+
* @param sdk_key SDK Key.
23+
*/
24+
ConfigBuilder(std::string sdk_key);
25+
26+
/**
27+
* To customize the endpoints the SDK uses for streaming, polling, and
28+
* events, pass in an EndpointsBuilder.
29+
* @param builder An EndpointsBuilder.
30+
* @return Reference to this builder.
31+
*/
32+
ConfigBuilder& service_endpoints(detail::EndpointsBuilder<SDK> builder);
33+
34+
/**
35+
* To enable or disable "offline" mode, pass a boolean value. True means
36+
* offline mode is enabled.
37+
* @param offline True if the SDK should operate in offline mode.
38+
* @return Reference to this builder.
39+
*/
40+
ConfigBuilder& offline(bool offline);
41+
42+
/**
43+
* Builds a Configuration, suitable for passing into an instance of Client.
44+
* @return
45+
*/
46+
ConfigType build() const;
47+
48+
private:
49+
std::string sdk_key_;
50+
std::optional<bool> offline_;
51+
std::optional<EndpointsBuilder> service_endpoints_builder_;
52+
};
53+
54+
} // namespace launchdarkly::config::detail
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
3+
#include "config/detail/sdks.hpp"
4+
#include "service_endpoints.hpp"
5+
6+
namespace launchdarkly::config::detail {
7+
8+
/**
9+
* Struct templated over an SDK type, which makes available SDK-specific
10+
* configuration.
11+
* @tparam SDK Type of SDK. See ClientSDK, ServerSDK.
12+
*/
13+
template <typename SDK>
14+
struct Defaults {
15+
/**
16+
* Offline mode is disabled in SDKs by default.
17+
* @return
18+
*/
19+
static bool offline() { return false; }
20+
};
21+
22+
template <>
23+
struct Defaults<ClientSDK> {
24+
static ServiceEndpoints endpoints() {
25+
return {"https://clientsdk.launchdarkly.com",
26+
"https://clientstream.launchdarkly.com",
27+
"https://mobile.launchdarkly.com"};
28+
}
29+
};
30+
31+
template <>
32+
struct Defaults<ServerSDK> {
33+
static ServiceEndpoints endpoints() {
34+
return {"https://sdk.launchdarkly.com",
35+
"https://stream.launchdarkly.com",
36+
"https://events.launchdarkly.com"};
37+
}
38+
};
39+
40+
} // namespace launchdarkly::config::detail
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#pragma once
2+
3+
#include "service_endpoints.hpp"
4+
5+
#include <memory>
6+
#include <optional>
7+
#include <string>
8+
9+
namespace launchdarkly::config::detail {
10+
11+
template <typename SDK>
12+
class EndpointsBuilder;
13+
14+
template <typename SDK>
15+
bool operator==(EndpointsBuilder<SDK> const& lhs,
16+
EndpointsBuilder<SDK> const& rhs);
17+
18+
/**
19+
* EndpointsBuilder allows for specification of LaunchDarkly service endpoints.
20+
*
21+
* @tparam SDK Type of SDK, such as ClientSDK or ServerSDK.
22+
*/
23+
template <typename SDK>
24+
class EndpointsBuilder {
25+
private:
26+
std::optional<std::string> polling_base_url_;
27+
std::optional<std::string> streaming_base_url_;
28+
std::optional<std::string> events_base_url_;
29+
30+
public:
31+
friend bool operator==<SDK>(EndpointsBuilder<SDK> const& lhs,
32+
EndpointsBuilder<SDK> const& rhs);
33+
/**
34+
* Constructs an EndpointsBuilder.
35+
*/
36+
EndpointsBuilder() = default;
37+
38+
/**
39+
* Sets a custom URL for the polling service.
40+
* @param url URL to set.
41+
* @return Reference to this builder.
42+
*/
43+
EndpointsBuilder& polling_base_url(std::string url);
44+
45+
/**
46+
* Sets a custom URL for the streaming service.
47+
* @param url URL to set.
48+
* @return Reference to this builder.
49+
*/
50+
EndpointsBuilder& streaming_base_url(std::string url);
51+
52+
/**
53+
* Sets a custom URL for the events service.
54+
* @param url URL to set.
55+
* @return Reference to this builder.
56+
*/
57+
EndpointsBuilder& events_base_url(std::string url);
58+
59+
/**
60+
* Sets a single base URL for a Relay Proxy instance.
61+
* @param url URL to set.
62+
* @return Reference to this builder.
63+
*/
64+
EndpointsBuilder& relay_proxy(std::string const& url);
65+
66+
/**
67+
* Builds a ServiceEndpoints if the configuration is valid. If not,
68+
* returns nullptr.
69+
* @return Unique pointer to ServiceEndpoints, or nullptr.
70+
*/
71+
[[nodiscard]] std::unique_ptr<ServiceEndpoints> build();
72+
};
73+
74+
} // namespace launchdarkly::config::detail
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
3+
namespace launchdarkly::config::detail {
4+
/**
5+
* Represents a client-side SDK configured for production services.
6+
*/
7+
struct ClientSDK {};
8+
/**
9+
* Represents a server-side SDK configured for production services.
10+
*/
11+
struct ServerSDK {};
12+
13+
/**
14+
* Represents configuration not common to any particular SDK type.
15+
*/
16+
struct AnySDK {};
17+
18+
} // namespace launchdarkly::config::detail
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
namespace launchdarkly::config {
6+
7+
/**
8+
* ServiceEndpoints contains configured endpoints for the LaunchDarkly
9+
* service or a Relay Proxy instance.
10+
*/
11+
class ServiceEndpoints {
12+
private:
13+
std::string polling_base_url_;
14+
std::string streaming_base_url_;
15+
std::string events_base_url_;
16+
17+
public:
18+
/**
19+
* Constructs a ServiceEndpoints from individual polling, streaming, and
20+
* events URLs.
21+
*
22+
* Meant for internal usage only; see ClientEndpointsBuilder or
23+
* ServerEndpointsBuilder to safely construct a ServiceEndpoints with
24+
* default URLs.
25+
*
26+
* @param polling Polling URL.
27+
* @param streaming Streaming URL.
28+
* @param events Events URL.
29+
*/
30+
ServiceEndpoints(std::string polling,
31+
std::string streaming,
32+
std::string events);
33+
/**
34+
* Returns the configured base polling URL.
35+
* @return Base polling URL.
36+
*/
37+
[[nodiscard]] std::string const& polling_base_url() const;
38+
/**
39+
* Returns the configured base streaming URL.
40+
* @return Base streaming URL.
41+
*/
42+
[[nodiscard]] std::string const& streaming_base_url() const;
43+
/**
44+
* Returns the configured base events URL.
45+
* @return Base events URL.
46+
*/
47+
[[nodiscard]] std::string const& events_base_url() const;
48+
};
49+
50+
bool operator==(ServiceEndpoints const& lhs, ServiceEndpoints const& rhs);
51+
} // namespace launchdarkly::config

libs/common/include/config/server.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "config/detail/config_builder.hpp"
4+
#include "config/detail/endpoints_builder.hpp"
5+
#include "config/detail/sdks.hpp"
6+
7+
namespace launchdarkly::server {
8+
9+
using SDK = config::detail::ServerSDK;
10+
11+
using EndpointsBuilder = config::detail::EndpointsBuilder<SDK>;
12+
using ConfigBuilder = config::detail::ConfigBuilder<SDK>;
13+
using Config = config::detail::Config<SDK>;
14+
15+
} // namespace launchdarkly::server

libs/common/src/CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11

2-
file(GLOB HEADER_LIST CONFIGURE_DEPENDS "${LaunchDarklyCPPCommon_SOURCE_DIR}/include/*.hpp")
2+
file(GLOB HEADER_LIST CONFIGURE_DEPENDS
3+
"${LaunchDarklyCPPCommon_SOURCE_DIR}/include/*.hpp"
4+
"${LaunchDarklyCPPCommon_SOURCE_DIR}/include/config/*.hpp"
5+
)
36

47
# Automatic library: static or dynamic based on user config.
5-
add_library(${LIBNAME} logger.cpp ${HEADER_LIST} console_backend.cpp log_level.cpp attribute_reference.cpp)
8+
add_library(${LIBNAME}
9+
${HEADER_LIST}
10+
logger.cpp
11+
console_backend.cpp
12+
log_level.cpp
13+
attribute_reference.cpp
14+
config/service_endpoints.cpp
15+
config/endpoints_builder.cpp
16+
config/config_builder.cpp
17+
config/config.cpp
18+
)
19+
620

721
add_library(launchdarkly::common ALIAS ${LIBNAME})
822

libs/common/src/config/config.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "config/detail/config.hpp"
2+
3+
#include "config/detail/sdks.hpp"
4+
namespace launchdarkly::config::detail {
5+
template <typename SDK>
6+
Config<SDK>::Config(std::string sdk_key,
7+
bool offline,
8+
detail::EndpointsBuilder<SDK> service_endpoints_builder)
9+
: sdk_key(std::move(sdk_key)),
10+
offline(offline),
11+
service_endpoints_builder(std::move(service_endpoints_builder)) {}
12+
13+
template class Config<detail::ClientSDK>;
14+
template class Config<detail::ServerSDK>;
15+
16+
} // namespace launchdarkly::config::detail
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "config/detail/config_builder.hpp"
2+
#include "config/detail/defaults.hpp"
3+
4+
namespace launchdarkly::config::detail {
5+
template <typename SDK>
6+
ConfigBuilder<SDK>::ConfigBuilder(std::string sdk_key)
7+
: sdk_key_(std::move(sdk_key)),
8+
offline_(std::nullopt),
9+
service_endpoints_builder_(std::nullopt) {}
10+
11+
template <typename SDK>
12+
ConfigBuilder<SDK>& ConfigBuilder<SDK>::service_endpoints(
13+
detail::EndpointsBuilder<SDK> builder) {
14+
service_endpoints_builder_ = std::move(builder);
15+
return *this;
16+
}
17+
18+
template <typename SDK>
19+
ConfigBuilder<SDK>& ConfigBuilder<SDK>::offline(bool offline) {
20+
offline_ = offline;
21+
return *this;
22+
}
23+
24+
template <typename SDK>
25+
typename ConfigBuilder<SDK>::ConfigType ConfigBuilder<SDK>::build() const {
26+
return {sdk_key_, offline_.value_or(Defaults<detail::AnySDK>::offline()),
27+
service_endpoints_builder_.value_or(
28+
ConfigBuilder<SDK>::EndpointsBuilder())};
29+
}
30+
31+
template class ConfigBuilder<detail::ClientSDK>;
32+
template class ConfigBuilder<detail::ServerSDK>;
33+
34+
} // namespace launchdarkly::config::detail

0 commit comments

Comments
 (0)