blob: 5d8e04593337ed148ce2411e1ab8150fc8aab679 [file] [log] [blame]
// 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(&registered_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(&registered_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