blob: 3df4da54f27a7a17f88c21f8f15fb48ffde5ac10 [file] [log] [blame]
// Copyright 2017 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 "garnet/bin/cobalt/app/cobalt_app.h"
#include "garnet/bin/cobalt/app/utils.h"
namespace cobalt {
using config::ClientConfig;
using encoder::ClientSecret;
using encoder::CobaltEncoderFactoryImpl;
using encoder::LegacyShippingManager;
using encoder::ShippingManager;
// Each "send attempt" is actually a cycle of potential retries. These
// two parameters configure the SendRetryer.
const std::chrono::seconds kInitialRpcDeadline(10);
const std::chrono::seconds kDeadlinePerSendAttempt(60);
const size_t kMaxBytesPerEnvelope = 512 * 1024; // 0.5 MiB.
const size_t kMaxBytesTotal = 1024 * 1024; // 1 MiB
const size_t kMinEnvelopeSendSize = 10 * 1024; // 10 K
constexpr char kCloudShufflerUri[] = "shuffler.cobalt-api.fuchsia.com:443";
constexpr char kConfigBinProtoPath[] = "/pkg/data/cobalt_config.binproto";
constexpr char kAnalyzerPublicKeyPemPath[] =
"/pkg/data/certs/cobaltv0.1/analyzer_public.pem";
constexpr char kShufflerPublicKeyPemPath[] =
"/pkg/data/certs/cobaltv0.1/shuffler_public.pem";
CobaltApp::CobaltApp(async_t* async, std::chrono::seconds schedule_interval,
std::chrono::seconds min_interval,
const std::string& product_name)
: system_data_(product_name),
context_(fuchsia::sys::StartupContext::CreateFromStartupInfo()),
shuffler_client_(kCloudShufflerUri, true),
send_retryer_(&shuffler_client_),
timer_manager_(async),
controller_impl_(new CobaltControllerImpl(async, &shipping_dispatcher_)) {
auto size_params = ShippingManager::SizeParams(
cobalt::kMaxBytesPerObservation, kMaxBytesPerEnvelope, kMaxBytesTotal,
kMinEnvelopeSendSize);
auto schedule_params =
ShippingManager::ScheduleParams(schedule_interval, min_interval);
auto envelope_maker_params = ShippingManager::EnvelopeMakerParams(
ReadPublicKeyPem(kAnalyzerPublicKeyPemPath),
EncryptedMessage::HYBRID_ECDH_V1,
ReadPublicKeyPem(kShufflerPublicKeyPemPath),
EncryptedMessage::HYBRID_ECDH_V1);
shipping_dispatcher_.Register(
ObservationMetadata::LEGACY_BACKEND,
std::make_unique<LegacyShippingManager>(
size_params, schedule_params, envelope_maker_params,
ShippingManager::SendRetryerParams(kInitialRpcDeadline,
kDeadlinePerSendAttempt),
&send_retryer_));
shipping_dispatcher_.Start();
// Open the cobalt config file.
std::ifstream config_file_stream;
config_file_stream.open(kConfigBinProtoPath);
FXL_CHECK(config_file_stream && config_file_stream.good())
<< "Could not open the Cobalt config file: " << kConfigBinProtoPath;
std::string cobalt_config_bytes;
cobalt_config_bytes.assign(
(std::istreambuf_iterator<char>(config_file_stream)),
std::istreambuf_iterator<char>());
FXL_CHECK(!cobalt_config_bytes.empty())
<< "Could not read the Cobalt config file: " << kConfigBinProtoPath;
// Parse the data as a CobaltConfig, then extract the metric and encoding
// configs and construct a ClientConfig to house them.
client_config_.reset(
ClientConfig::CreateFromCobaltConfigBytes(cobalt_config_bytes).release());
FXL_CHECK(client_config_)
<< "Could not parse the Cobalt config file: " << kConfigBinProtoPath;
factory_impl_.reset(new CobaltEncoderFactoryImpl(
client_config_, getClientSecret(), &shipping_dispatcher_, &system_data_,
&timer_manager_));
context_->outgoing().AddPublicService<CobaltEncoderFactory>(
[this](fidl::InterfaceRequest<CobaltEncoderFactory> request) {
factory_bindings_.AddBinding(factory_impl_.get(), std::move(request));
});
context_->outgoing().AddPublicService<CobaltController>(
[this](fidl::InterfaceRequest<CobaltController> request) {
controller_bindings_.AddBinding(controller_impl_.get(),
std::move(request));
});
}
ClientSecret CobaltApp::getClientSecret() {
// TODO(rudominer): Generate a client secret only once, store it
// persistently and reuse it in future instances.
return ClientSecret::GenerateNewSecret();
}
} // namespace cobalt