| // 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 |