Skip to content

Commit

Permalink
move logic to config_manager
Browse files Browse the repository at this point in the history
  • Loading branch information
dmehala authored and cataphract committed Aug 27, 2024
1 parent f25e15e commit 8e11e46
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 97 deletions.
15 changes: 15 additions & 0 deletions src/datadog/config_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ ConfigManager::Update parse_dynamic_config(const nlohmann::json& j) {
namespace rc = datadog::remote_config;

ConfigManager::ConfigManager(const FinalizedTracerConfig& config,
const TracerSignature& tracer_signature,
const std::shared_ptr<TracerTelemetry>& telemetry)
: clock_(config.clock),
default_metadata_(config.metadata),
Expand All @@ -117,6 +118,7 @@ ConfigManager::ConfigManager(const FinalizedTracerConfig& config,
rules_(config.trace_sampler.rules),
span_defaults_(std::make_shared<SpanDefaults>(config.defaults)),
report_traces_(config.report_traces),
tracer_signature_(tracer_signature),
telemetry_(telemetry) {}

rc::Products ConfigManager::get_products() { return rc::product::APM_TRACING; }
Expand All @@ -128,7 +130,20 @@ rc::Capabilities ConfigManager::get_capabilities() {
}

Optional<std::string> ConfigManager::on_update(const Configuration& config) {
if (config.product != rc::product::Flag::APM_TRACING) {
return nullopt;
}

const auto config_json = nlohmann::json::parse(config.content);

const auto& targeted_service = config_json.at("service_target");
if (targeted_service.at("service").get<StringView>() !=
tracer_signature_.default_service ||
targeted_service.at("env").get<StringView>() !=
tracer_signature_.default_environment) {
return "Wrong service targeted";
}

auto config_update = parse_dynamic_config(config_json.at("lib_config"));

auto config_metadata = apply_update(config_update);
Expand Down
2 changes: 2 additions & 0 deletions src/datadog/config_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ConfigManager : public remote_config::Listener {
DynamicConfig<std::shared_ptr<const SpanDefaults>> span_defaults_;
DynamicConfig<bool> report_traces_;

const TracerSignature& tracer_signature_;
std::shared_ptr<TracerTelemetry> telemetry_;

private:
Expand All @@ -85,6 +86,7 @@ class ConfigManager : public remote_config::Listener {

public:
ConfigManager(const FinalizedTracerConfig& config,
const TracerSignature& signature,
const std::shared_ptr<TracerTelemetry>& telemetry);
~ConfigManager() override{};

Expand Down
30 changes: 6 additions & 24 deletions src/datadog/remote_config/remote_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ constexpr std::array<uint8_t, sizeof(uint64_t)> capabilities_byte_array(
return res;
}

struct ConfigKeyData {
struct ConfigKeyMetadata final {
product::Flag product;
StringView config_id;
};

Optional<ConfigKeyData> parse_config_path(StringView config_path) {
Optional<ConfigKeyMetadata> parse_config_path(StringView config_path) {
static const std::regex path_reg(
"^(datadog/\\d+|employee)/([^/]+)/([^/]+)/[^/]+$");

Expand Down Expand Up @@ -206,16 +206,16 @@ void Manager::process_response(const nlohmann::json& json) {
auto config_path = client_config.get<StringView>();
visited_config.emplace(config_path);

const auto config_key_data = parse_config_path(config_path);
if (!config_key_data) {
const auto config_key_metadata = parse_config_path(config_path);
if (!config_key_metadata) {
std::string reason{config_path};
reason += " is an invalid configuration path";

error(reason);
return;
}

const auto product = config_key_data->product;
const auto product = config_key_metadata->product;

const auto& config_metadata =
targets.at("/signed/targets"_json_pointer).at(config_path);
Expand Down Expand Up @@ -244,30 +244,13 @@ void Manager::process_response(const nlohmann::json& json) {
auto decoded_config = base64_decode(raw_data);

Configuration new_config;
auto&& config_id = config_key_data->config_id;
new_config.id = std::string{config_id.data(), config_id.size()};
new_config.id = std::string{config_key_metadata->config_id};
new_config.path = std::string{config_path};
new_config.hash = config_metadata.at("/hashes/sha256"_json_pointer);
new_config.content = std::move(decoded_config);
new_config.version = config_metadata.at("/custom/v"_json_pointer);
new_config.product = product;

// TODO: should be moved to the listener
if (product == product::Flag::APM_TRACING) {
const auto config_json = nlohmann::json::parse(new_config.content);
new_config.version = config_json.at("revision");

const auto& targeted_service = config_json.at("service_target");
if (targeted_service.at("service").get<StringView>() !=
tracer_signature_.default_service ||
targeted_service.at("env").get<StringView>() !=
tracer_signature_.default_environment) {
new_config.state = Configuration::State::error;
new_config.error_message = "Wrong service targeted";
goto skip_listeners;
}
}

for (const auto& listener : listeners_per_product_[product]) {
// Q: Two listeners on the same product. What should be the behaviour
// if one of the listeners report an error?
Expand All @@ -281,7 +264,6 @@ void Manager::process_response(const nlohmann::json& json) {
}
}

skip_listeners:
applied_config_[std::string{config_path}] = new_config;
}

Expand Down
12 changes: 6 additions & 6 deletions src/datadog/tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
namespace datadog {
namespace tracing {

void to_json(nlohmann::json& j, const PropagationStyle& style) {
j = to_string_view(style);
}

Tracer::Tracer(const FinalizedTracerConfig& config)
: Tracer(config, default_id_generator(config.generate_128bit_trace_ids)) {}

Expand All @@ -43,8 +47,8 @@ Tracer::Tracer(const FinalizedTracerConfig& config,
tracer_telemetry_(std::make_shared<TracerTelemetry>(
config.report_telemetry, config.clock, logger_, signature_,
config.integration_name, config.integration_version)),
config_manager_(
std::make_shared<ConfigManager>(config, tracer_telemetry_)),
config_manager_(std::make_shared<ConfigManager>(config, signature_,
tracer_telemetry_)),
collector_(/* see constructor body */),
span_sampler_(
std::make_shared<SpanSampler>(config.span_sampler, config.clock)),
Expand Down Expand Up @@ -83,10 +87,6 @@ Tracer::Tracer(const FinalizedTracerConfig& config,
}
}

void to_json(nlohmann::json& j, const PropagationStyle& style) {
j = to_string_view(style);
}

std::string Tracer::config() const {
// clang-format off
auto config = nlohmann::json::object({
Expand Down
65 changes: 0 additions & 65 deletions test/remote_config/test_remote_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,71 +190,6 @@ REMOTE_CONFIG_TEST("response processing") {
CHECK(payload.contains("/client/state/error"_json_pointer) == true);
}

SECTION(
"configuration updates targetting the wrong tracer reports an error") {
// clang-format off
auto test_case = GENERATE(values<std::string>({
// "service_target": { "service": "not-testsvc", "env": "test" }
R"({
"targets":
"ewogICAgInNpZ25lZCI6IHsKICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiYWdlbnRfcmVmcmVzaF9pbnRlcnZhbCI6IDUsCiAgICAgICAgICAgICJvcGFxdWVfYmFja2VuZF9zdGF0ZSI6ICJleUoyWlhKemFXOXVJam95TENKemRHRjBaU0k2ZXlKbWFXeGxYMmhoYzJobGN5STZleUprWVhSaFpHOW5MekV3TURBeE1qVTROREF2UVZCTlgxUlNRVU5KVGtjdk9ESTNaV0ZqWmpoa1ltTXpZV0l4TkRNMFpETXlNV05pT0RGa1ptSm1OMkZtWlRZMU5HRTBZall4TVRGalpqRTJOakJpTnpGalkyWTRPVGM0TVRrek9DOHlPVEE0Tm1Ka1ltVTFNRFpsTmpoaU5UQm1NekExTlRneU0yRXpaR0UxWTJVd05USTRaakUyTkRCa05USmpaamc0TmpFNE1UWmhZV0U1Wm1ObFlXWTBJanBiSW05WVpESnBlVU16ZUM5b1JXc3hlWFZoWTFoR04xbHFjWEpwVGs5QldVdHVaekZ0V0UwMU5WWktUSGM5SWwxOWZYMD0iCiAgICAgICAgfSwKICAgICAgICAic3BlY192ZXJzaW9uIjogIjEuMC4wIiwKICAgICAgICAidGFyZ2V0cyI6IHsKICAgICAgICAgICAgImVtcGxveWVlL0FQTV9UUkFDSU5HL3Rlc3RfcmNfd3JvbmdfdGFyZ2V0L3NlcnZpY2VfbmFtZSI6IHsKICAgICAgICAgICAgICAgICJoYXNoZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgInNoYTI1NiI6ICJhMTc3NzY4YjIwYjdjN2Y4NDQ5MzVjYWU2OWM1YzVlZDg4ZWFhZTIzNGUwMTgyYTc4MzU5OTczMzllNTUyNGJjIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJsZW5ndGgiOiAzNzQsCgkJCQkiY3VzdG9tIjogeyAidiI6IDEyMyB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJ2ZXJzaW9uIjogNjYyMDQzMjAKICAgIH0KfQo=",
"client_configs": ["employee/APM_TRACING/test_rc_wrong_target/service_name"],
"target_files": [
{
"path": "employee/APM_TRACING/test_rc_wrong_target/service_name",
"raw":
"eyAiaWQiOiAiODI3ZWFjZjhkYmMzYWIxNDM0ZDMyMWNiODFkZmJmN2FmZTY1NGE0YjYxMTFjZjE2NjBiNzFjY2Y4OTc4MTkzOCIsICJyZXZpc2lvbiI6IDE2OTgxNjcxMjYwNjQsICJzY2hlbWFfdmVyc2lvbiI6ICJ2MS4wLjAiLCAiYWN0aW9uIjogImVuYWJsZSIsICJsaWJfY29uZmlnIjogeyAibGlicmFyeV9sYW5ndWFnZSI6ICJhbGwiLCAibGlicmFyeV92ZXJzaW9uIjogImxhdGVzdCIsICJzZXJ2aWNlX25hbWUiOiAidGVzdHN2YyIsICJlbnYiOiAidGVzdCIsICJ0cmFjaW5nX2VuYWJsZWQiOiB0cnVlLCAidHJhY2luZ19zYW1wbGluZ19yYXRlIjogMC42IH0sICJzZXJ2aWNlX3RhcmdldCI6IHsgInNlcnZpY2UiOiAibm90LXRlc3RzdmMiLCAiZW52IjogInRlc3QiIH0gfQ=="
}
]
})",
// "service_target": { "service": "testsvc", "env": "dev" }
R"({
"targets":
"ewogICAgInNpZ25lZCI6IHsKICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiYWdlbnRfcmVmcmVzaF9pbnRlcnZhbCI6IDUsCiAgICAgICAgICAgICJvcGFxdWVfYmFja2VuZF9zdGF0ZSI6ICJleUoyWlhKemFXOXVJam95TENKemRHRjBaU0k2ZXlKbWFXeGxYMmhoYzJobGN5STZleUprWVhSaFpHOW5MekV3TURBeE1qVTROREF2UVZCTlgxUlNRVU5KVGtjdk9ESTNaV0ZqWmpoa1ltTXpZV0l4TkRNMFpETXlNV05pT0RGa1ptSm1OMkZtWlRZMU5HRTBZall4TVRGalpqRTJOakJpTnpGalkyWTRPVGM0TVRrek9DOHlPVEE0Tm1Ka1ltVTFNRFpsTmpoaU5UQm1NekExTlRneU0yRXpaR0UxWTJVd05USTRaakUyTkRCa05USmpaamc0TmpFNE1UWmhZV0U1Wm1ObFlXWTBJanBiSW05WVpESnBlVU16ZUM5b1JXc3hlWFZoWTFoR04xbHFjWEpwVGs5QldVdHVaekZ0V0UwMU5WWktUSGM5SWwxOWZYMD0iCiAgICAgICAgfSwKICAgICAgICAic3BlY192ZXJzaW9uIjogIjEuMC4wIiwKICAgICAgICAidGFyZ2V0cyI6IHsKICAgICAgICAgICAgImVtcGxveWVlL0FQTV9UUkFDSU5HL3Rlc3RfcmNfd3JvbmdfdGFyZ2V0L2Vudl9uYW1lIjogewogICAgICAgICAgICAgICAgImhhc2hlcyI6IHsKICAgICAgICAgICAgICAgICAgICAic2hhMjU2IjogImExNzc3NjhiMjBiN2M3Zjg0NDkzNWNhZTY5YzVjNWVkODhlYWFlMjM0ZTAxODJhNzgzNTk5NzMzOWU1NTI0YmMiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImxlbmd0aCI6IDM3NCwKCQkJCSJjdXN0b20iOiB7ICJ2IjogMTI0IH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInZlcnNpb24iOiA2NjIwNDMyMAogICAgfQp9Cg==",
"client_configs": ["employee/APM_TRACING/test_rc_wrong_target/env_name"],
"target_files": [
{
"path": "employee/APM_TRACING/test_rc_wrong_target/env_name",
"raw":
"eyAiaWQiOiAiODI3ZWFjZjhkYmMzYWIxNDM0ZDMyMWNiODFkZmJmN2FmZTY1NGE0YjYxMTFjZjE2NjBiNzFjY2Y4OTc4MTkzOCIsICJyZXZpc2lvbiI6IDE2OTgxNjcxMjYwNjQsICJzY2hlbWFfdmVyc2lvbiI6ICJ2MS4wLjAiLCAiYWN0aW9uIjogImVuYWJsZSIsICJsaWJfY29uZmlnIjogeyAibGlicmFyeV9sYW5ndWFnZSI6ICJhbGwiLCAibGlicmFyeV92ZXJzaW9uIjogImxhdGVzdCIsICJzZXJ2aWNlX25hbWUiOiAidGVzdHN2YyIsICJlbnYiOiAidGVzdCIsICJ0cmFjaW5nX2VuYWJsZWQiOiB0cnVlLCAidHJhY2luZ19zYW1wbGluZ19yYXRlIjogMC42IH0sICJzZXJ2aWNlX3RhcmdldCI6IHsgInNlcnZpY2UiOiAidGVzdHN2YyIsICJlbnYiOiAiZGV2IiB9IH0="
}
]
})"
}));
// clang-format on

CAPTURE(test_case);

const auto response_json =
nlohmann::json::parse(/* input = */ test_case,
/* parser_callback = */ nullptr,
/* allow_exceptions = */ false);

REQUIRE(!response_json.is_discarded());

auto tracing_listener = std::make_shared<FakeListener>();
tracing_listener->products = rc::product::APM_TRACING;

rc::Manager rc(tracer_signature, {tracing_listener}, logger);
rc.process_response(response_json);

CHECK(tracing_listener->count_on_update == 0);
CHECK(tracing_listener->count_on_revert == 0);
CHECK(tracing_listener->count_on_post_process == 1);

// Verify next request set the config status
const auto payload = rc.make_request_payload();
REQUIRE(payload.contains("/client/state/config_states"_json_pointer) ==
true);

constexpr auto error_state = 3;
const auto& config_states =
payload.at("/client/state/config_states"_json_pointer);
REQUIRE(config_states.size() == 1);
CHECK(config_states[0]["product"] == "APM_TRACING");
CHECK(config_states[0]["apply_state"] == error_state);
}

SECTION("update dispatch") {
// Verify configuration updates are dispatched to the correct listener
std::string_view rc_response = R"({
Expand Down
21 changes: 20 additions & 1 deletion test/test_config_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,33 @@ CONFIG_MANAGER_TEST("remote configuration handling") {
auto tracer_telemetry = std::make_shared<TracerTelemetry>(
false, default_clock, nullptr, tracer_signature, "", "");

ConfigManager config_manager(*finalize_config(config), tracer_telemetry);
ConfigManager config_manager(*finalize_config(config), tracer_signature,
tracer_telemetry);

rc::Listener::Configuration config_update{/* id = */ "id",
/* path = */ "",
/* content = */ "",
/* version = */ 1,
rc::product::Flag::APM_TRACING};

SECTION(
"configuration updates targetting the wrong tracer reports an error") {
// clang-format off
auto test_case = GENERATE(values<std::string>({
R"({ "service_target": { "service": "not-testsvc", "env": "test" } })",
R"({ "service_target": { "service": "testsvc", "env": "not-test" } })"
}));
// clang-format on

CAPTURE(test_case);

config_update.content = test_case;

// TODO: targetting wrong procut -> error
const auto err = config_manager.on_update(config_update);
CHECK(err);
}

SECTION("handling of `tracing_sampling_rate`") {
// SECTION("invalid value") {
// config_update.content = R"({
Expand Down
3 changes: 2 additions & 1 deletion test/test_datadog_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ TEST_CASE("Remote Configuration", "[datadog_agent]") {
finalized->report_telemetry, finalized->clock, finalized->logger,
signature, "", "");

auto config_manager = std::make_shared<ConfigManager>(*finalized, telemetry);
auto config_manager =
std::make_shared<ConfigManager>(*finalized, signature, telemetry);

const auto& agent_config =
std::get<FinalizedDatadogAgentConfig>(finalized->collector);
Expand Down

0 comments on commit 8e11e46

Please sign in to comment.