| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "config/client_config.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "./logging.h" |
| #include "config/cobalt_registry.pb.h" |
| #include "config/encoding_config.h" |
| #include "config/encodings.pb.h" |
| #include "config/metric_config.h" |
| #include "config/metrics.pb.h" |
| #include "util/crypto_util/base64.h" |
| |
| namespace cobalt { |
| namespace config { |
| |
| namespace { |
| std::string ErrorMessage(Status status) { |
| switch (status) { |
| case kOK: |
| return "No error"; |
| |
| case kFileOpenError: |
| return "Unable to open file: "; |
| |
| case kParsingError: |
| return "Error while parsing file: "; |
| |
| case kDuplicateRegistration: |
| return "Duplicate ID found in file: "; |
| |
| default: |
| return "Unknown problem with: "; |
| } |
| } |
| } // namespace |
| |
| std::unique_ptr<ClientConfig> ClientConfig::CreateFromCobaltRegistryBase64( |
| const std::string& cobalt_registry_base64) { |
| std::string cobalt_registry_bytes; |
| if (!crypto::Base64Decode(cobalt_registry_base64, &cobalt_registry_bytes)) { |
| LOG(ERROR) << "Unable to parse the provided string as base-64"; |
| return nullptr; |
| } |
| return CreateFromCobaltRegistryBytes(cobalt_registry_bytes); |
| } |
| |
| std::unique_ptr<ClientConfig> ClientConfig::CreateFromCobaltRegistryBytes( |
| const std::string& cobalt_registry_bytes) { |
| auto cobalt_registry = std::make_unique<CobaltRegistry>(); |
| if (!cobalt_registry->ParseFromString(cobalt_registry_bytes)) { |
| LOG(ERROR) << "Unable to parse a CobaltRegistry from the provided bytes."; |
| return nullptr; |
| } |
| return CreateFromCobaltRegistryProto(std::move(cobalt_registry)); |
| } |
| |
| std::unique_ptr<ClientConfig> ClientConfig::CreateFromCobaltRegistryProto( |
| std::unique_ptr<CobaltRegistry> cobalt_registry) { |
| RegisteredEncodings registered_encodings; |
| registered_encodings.mutable_element()->Swap( |
| cobalt_registry->mutable_encoding_configs()); |
| auto encoding_registry_and_status = |
| EncodingRegistry::TakeFrom(®istered_encodings, nullptr); |
| if (encoding_registry_and_status.second != config::kOK) { |
| LOG(ERROR) << "Invalid EncodingConfigs. " |
| << ErrorMessage(encoding_registry_and_status.second); |
| return std::unique_ptr<ClientConfig>(nullptr); |
| } |
| |
| RegisteredMetrics registered_metrics; |
| registered_metrics.mutable_element()->Swap( |
| cobalt_registry->mutable_metric_configs()); |
| auto metrics_registry_and_status = |
| MetricRegistry::TakeFrom(®istered_metrics, nullptr); |
| if (metrics_registry_and_status.second != config::kOK) { |
| LOG(ERROR) << "Error getting Metrics from registry. " |
| << ErrorMessage(metrics_registry_and_status.second); |
| return std::unique_ptr<ClientConfig>(nullptr); |
| } |
| |
| return std::make_unique<ClientConfig>( |
| std::move(encoding_registry_and_status.first), |
| std::move(metrics_registry_and_status.first)); |
| } |
| |
| const EncodingConfig* ClientConfig::EncodingConfig( |
| uint32_t customer_id, uint32_t project_id, uint32_t encoding_config_id) { |
| return encoding_configs_->Get(customer_id, project_id, encoding_config_id); |
| } |
| |
| const Metric* ClientConfig::Metric(uint32_t customer_id, uint32_t project_id, |
| uint32_t metric_id) { |
| return metrics_->Get(customer_id, project_id, metric_id); |
| } |
| |
| const Metric* ClientConfig::Metric(uint32_t customer_id, uint32_t project_id, |
| const std::string& metric_name) { |
| return metrics_->Get(customer_id, project_id, metric_name); |
| } |
| |
| ClientConfig::ClientConfig( |
| std::shared_ptr<config::EncodingRegistry> encoding_configs, |
| std::shared_ptr<config::MetricRegistry> metrics) |
| : encoding_configs_(std::move(encoding_configs)), |
| metrics_(std::move(metrics)) { |
| CHECK(metrics_); |
| CHECK(encoding_configs_); |
| is_empty_ = encoding_configs_->size() == 0 && metrics_->size() == 0; |
| DetermineIfSingleProject(); |
| } |
| |
| void ClientConfig::DetermineIfSingleProject() { |
| is_single_project_ = false; |
| if (is_empty_) { |
| return; |
| } |
| |
| bool first = true; |
| for (const class EncodingConfig& encoding_config : *encoding_configs_) { |
| if (first) { |
| first = false; |
| is_single_project_ = true; |
| single_customer_id_ = encoding_config.customer_id(); |
| single_project_id_ = encoding_config.project_id(); |
| } else if (encoding_config.customer_id() != single_customer_id_ || |
| encoding_config.project_id() != single_project_id_) { |
| is_single_project_ = false; |
| return; |
| } |
| } |
| for (const class Metric& metric : *metrics_) { |
| if (first) { |
| first = false; |
| is_single_project_ = true; |
| single_customer_id_ = metric.customer_id(); |
| single_project_id_ = metric.project_id(); |
| } else if (metric.customer_id() != single_customer_id_ || |
| metric.project_id() != single_project_id_) { |
| is_single_project_ = false; |
| return; |
| } |
| } |
| } |
| |
| } // namespace config |
| } // namespace cobalt |