@@ -30,9 +30,14 @@ constexpr std::array<uint8_t, sizeof(uint64_t)> capabilities_byte_array(
3030 return res;
3131}
3232
33- Optional<product::Flag> parse_config_path (StringView config_path) {
33+ struct ConfigKeyData {
34+ product::Flag product;
35+ StringView config_id;
36+ };
37+
38+ Optional<ConfigKeyData> parse_config_path (StringView config_path) {
3439 static const std::regex path_reg (
35- " ^(datadog/\\ d+|employee)/([^/]+)/[^/]+/[^/]+$" );
40+ " ^(datadog/\\ d+|employee)/([^/]+)/( [^/]+) /[^/]+$" );
3641
3742 std::cmatch match;
3843 if (!std::regex_match (config_path.data (),
@@ -42,12 +47,14 @@ Optional<product::Flag> parse_config_path(StringView config_path) {
4247 }
4348
4449 assert (match.ready ());
45- assert (match.size () == 3 );
50+ assert (match.size () == 4 );
4651
4752 StringView product_sv (config_path.data () + match.position (2 ),
4853 std::size_t (match.length (2 )));
54+ StringView config_id_sv{config_path.data () + match.position (3 ),
55+ static_cast <std::size_t >(match.length (3 ))};
4956
50- return parse_product (product_sv);
57+ return {{ parse_product (product_sv), config_id_sv}} ;
5158}
5259
5360} // namespace
@@ -199,15 +206,17 @@ void Manager::process_response(const nlohmann::json& json) {
199206 auto config_path = client_config.get <StringView>();
200207 visited_config.emplace (config_path);
201208
202- const auto product = parse_config_path (config_path);
203- if (!product ) {
209+ const auto config_key_data = parse_config_path (config_path);
210+ if (!config_key_data ) {
204211 std::string reason{config_path};
205212 reason += " is an invalid configuration path" ;
206213
207214 error (reason);
208215 return ;
209216 }
210217
218+ const auto product = config_key_data->product ;
219+
211220 const auto & config_metadata =
212221 targets.at (" /signed/targets" _json_pointer).at (config_path);
213222
@@ -231,41 +240,48 @@ void Manager::process_response(const nlohmann::json& json) {
231240 return ;
232241 }
233242
234- auto decoded_config =
235- base64_decode (target_it.value ().at (" raw" ).get <StringView>());
236-
237- const auto config_json = nlohmann::json::parse (decoded_config);
243+ auto raw_data = target_it->at (" raw" ).get <StringView>();
244+ auto decoded_config = base64_decode (raw_data);
238245
239246 Configuration new_config;
240- new_config.id = config_json.at (" id" );
247+ auto && config_id = config_key_data->config_id ;
248+ new_config.id = std::string{config_id.data (), config_id.size ()};
241249 new_config.path = std::string{config_path};
242250 new_config.hash = config_metadata.at (" /hashes/sha256" _json_pointer);
243251 new_config.content = std::move (decoded_config);
244- new_config.version = config_json.at (" revision" );
245- new_config.product = *product;
246-
247- const auto & targeted_service = config_json.at (" service_target" );
248- if (targeted_service.at (" service" ).get <StringView>() !=
249- tracer_signature_.default_service ||
250- targeted_service.at (" env" ).get <StringView>() !=
251- tracer_signature_.default_environment ) {
252- new_config.state = Configuration::State::error;
253- new_config.error_message = " Wrong service targeted" ;
254- } else {
255- for (const auto & listener : listeners_per_product_[*product]) {
256- // Q: Two listeners on the same product. What should be the behaviour
257- // if one of the listeners report an error?
258- // R(@dmehala): Unspecified. For now, the config is marked with an
259- // error.
260- if (auto error_msg = listener->on_update (new_config)) {
261- new_config.state = Configuration::State::error;
262- new_config.error_message = std::move (*error_msg);
263- } else {
264- new_config.state = Configuration::State::acknowledged;
265- }
252+ new_config.version = config_metadata.at (" /custom/v" _json_pointer);
253+ new_config.product = product;
254+
255+ // TODO: should be moved to the listener
256+ if (product == product::Flag::APM_TRACING) {
257+ const auto config_json = nlohmann::json::parse (new_config.content );
258+ new_config.version = config_json.at (" revision" );
259+
260+ const auto & targeted_service = config_json.at (" service_target" );
261+ if (targeted_service.at (" service" ).get <StringView>() !=
262+ tracer_signature_.default_service ||
263+ targeted_service.at (" env" ).get <StringView>() !=
264+ tracer_signature_.default_environment ) {
265+ new_config.state = Configuration::State::error;
266+ new_config.error_message = " Wrong service targeted" ;
267+ goto skip_listeners;
268+ }
269+ }
270+
271+ for (const auto & listener : listeners_per_product_[product]) {
272+ // Q: Two listeners on the same product. What should be the behaviour
273+ // if one of the listeners report an error?
274+ // R(@dmehala): Unspecified. For now, the config is marked with an
275+ // error.
276+ if (auto error_msg = listener->on_update (new_config)) {
277+ new_config.state = Configuration::State::error;
278+ new_config.error_message = std::move (*error_msg);
279+ } else {
280+ new_config.state = Configuration::State::acknowledged;
266281 }
267282 }
268283
284+ skip_listeners:
269285 applied_config_[std::string{config_path}] = new_config;
270286 }
271287
0 commit comments