blob: fae42a246f573ae204e164173fe14c2c8d57a9f5 [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 "dockyard_proxy_grpc.h"
#include <zircon/status.h>
#include <chrono>
#include <memory>
#include <string>
#include "dockyard_proxy.h"
#include "garnet/lib/system_monitor/protos/dockyard.grpc.pb.h"
#include "src/lib/fxl/logging.h"
namespace harvester {
namespace {
constexpr DockyardProxyStatus ToDockyardProxyStatus(
const grpc::Status& status) {
return status.ok() ? DockyardProxyStatus::OK : DockyardProxyStatus::ERROR;
}
} // namespace
DockyardProxyStatus DockyardProxyGrpc::Init() {
dockyard_proto::InitRequest request;
request.set_device_name("TODO SET DEVICE NAME");
request.set_version(dockyard::DOCKYARD_VERSION);
auto now = std::chrono::system_clock::now();
uint64_t nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
now.time_since_epoch())
.count();
request.set_device_time_ns(nanoseconds);
dockyard_proto::InitReply reply;
grpc::ClientContext context;
grpc::Status status = stub_->Init(&context, request, &reply);
if (status.ok()) {
return DockyardProxyStatus::OK;
}
FXL_LOG(ERROR) << status.error_code() << ": " << status.error_message();
FXL_LOG(ERROR) << "Unable to send to dockyard.";
return DockyardProxyStatus::ERROR;
}
DockyardProxyStatus DockyardProxyGrpc::SendInspectJson(
const std::string& dockyard_path, const std::string& json) {
auto now = std::chrono::system_clock::now();
uint64_t nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
now.time_since_epoch())
.count();
dockyard::DockyardId dockyard_id;
grpc::Status status = GetDockyardIdForPath(&dockyard_id, dockyard_path);
if (status.ok()) {
return ToDockyardProxyStatus(
SendInspectJsonById(nanoseconds, dockyard_id, json));
}
return ToDockyardProxyStatus(status);
}
DockyardProxyStatus DockyardProxyGrpc::SendSample(
const std::string& dockyard_path, uint64_t value) {
// TODO(smbug.com/35): system_clock might be at usec resolution. Consider
// using high_resolution_clock.
auto now = std::chrono::system_clock::now();
uint64_t nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
now.time_since_epoch())
.count();
dockyard::DockyardId dockyard_id;
grpc::Status status = GetDockyardIdForPath(&dockyard_id, dockyard_path);
if (status.ok()) {
return ToDockyardProxyStatus(
SendSampleById(nanoseconds, dockyard_id, value));
}
return ToDockyardProxyStatus(status);
}
DockyardProxyStatus DockyardProxyGrpc::SendSampleList(const SampleList list) {
// TODO(smbug.com/35): system_clock might be at usec resolution. Consider
// using high_resolution_clock.
auto now = std::chrono::system_clock::now();
uint64_t nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
now.time_since_epoch())
.count();
SampleListById by_id(list.size());
auto path_iter = list.begin();
auto id_iter = by_id.begin();
for (; path_iter != list.end(); ++path_iter, ++id_iter) {
dockyard::DockyardId dockyard_id;
grpc::Status status = GetDockyardIdForPath(&dockyard_id, path_iter->first);
if (!status.ok()) {
return ToDockyardProxyStatus(status);
}
id_iter->first = dockyard_id;
id_iter->second = path_iter->second;
}
return ToDockyardProxyStatus(SendSampleListById(nanoseconds, by_id));
}
grpc::Status DockyardProxyGrpc::SendInspectJsonById(
uint64_t time, dockyard::DockyardId dockyard_id, const std::string& json) {
// Data we are sending to the server.
dockyard_proto::InspectJson inspect;
inspect.set_time(time);
inspect.set_dockyard_id(dockyard_id);
inspect.set_json(json);
grpc::ClientContext context;
std::shared_ptr<grpc::ClientReaderWriter<dockyard_proto::InspectJson,
dockyard_proto::EmptyMessage>>
stream(stub_->SendInspectJson(&context));
stream->Write(inspect);
stream->WritesDone();
return stream->Finish();
}
grpc::Status DockyardProxyGrpc::SendSampleById(uint64_t time,
dockyard::DockyardId dockyard_id,
uint64_t value) {
// Data we are sending to the server.
dockyard_proto::RawSample sample;
sample.set_time(time);
sample.mutable_sample()->set_key(dockyard_id);
sample.mutable_sample()->set_value(value);
grpc::ClientContext context;
std::shared_ptr<grpc::ClientReaderWriter<dockyard_proto::RawSample,
dockyard_proto::EmptyMessage>>
stream(stub_->SendSample(&context));
stream->Write(sample);
stream->WritesDone();
return stream->Finish();
}
grpc::Status DockyardProxyGrpc::SendSampleListById(uint64_t time,
const SampleListById list) {
// Data we are sending to the server.
dockyard_proto::RawSamples samples;
samples.set_time(time);
for (auto iter = list.begin(); iter != list.end(); ++iter) {
auto sample = samples.add_sample();
sample->set_key(iter->first);
sample->set_value(iter->second);
}
grpc::ClientContext context;
std::shared_ptr<grpc::ClientReaderWriter<dockyard_proto::RawSamples,
dockyard_proto::EmptyMessage>>
stream(stub_->SendSamples(&context));
stream->Write(samples);
stream->WritesDone();
return stream->Finish();
}
grpc::Status DockyardProxyGrpc::GetDockyardIdForPath(
dockyard::DockyardId* dockyard_id, const std::string& dockyard_path) {
auto iter = dockyard_path_to_id_.find(dockyard_path);
if (iter != dockyard_path_to_id_.end()) {
*dockyard_id = iter->second;
return grpc::Status::OK;
}
dockyard_proto::DockyardPathMessage path;
path.set_path(dockyard_path);
// Container for the data we expect from the server.
dockyard_proto::DockyardIdMessage reply;
grpc::ClientContext context;
grpc::Status status = stub_->GetDockyardIdForPath(&context, path, &reply);
if (status.ok()) {
*dockyard_id = reply.id();
// Memoize it.
dockyard_path_to_id_.emplace(dockyard_path, *dockyard_id);
}
return status;
}
} // namespace harvester