blob: e770d1791f5af9698d08e0ea0a273d6598e95b80 [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.
#ifndef COBALT_ANALYZER_REPORT_MASTER_REPORT_EXPORTER_H_
#define COBALT_ANALYZER_REPORT_MASTER_REPORT_EXPORTER_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "analyzer/report_master/report_internal.pb.h"
#include "analyzer/report_master/report_row_iterator.h"
#include "analyzer/report_master/report_stream.h"
#include "config/report_configs.pb.h"
#include "grpc++/grpc++.h"
#include "util/gcs/gcs_util.h"
namespace cobalt {
namespace analyzer {
// An abstract interface for uploading serialized reports to Google Cloud
// Storage. This allows us to mock out the upload step in unit tests.
class GcsUploadInterface {
public:
virtual ~GcsUploadInterface() = default;
virtual grpc::Status UploadToGCS(const std::string& bucket,
const std::string& path,
const std::string& mime_type,
ReportStream* report_stream) = 0;
};
// An implementation of GcsUploadInterface that actually uploads files to
// Google Cloud Storage.
class GcsUploader : public GcsUploadInterface {
public:
virtual ~GcsUploader() = default;
grpc::Status UploadToGCS(const std::string& bucket, const std::string& path,
const std::string& mime_type,
ReportStream* report_stream) override;
private:
grpc::Status PingBucket(const std::string& bucket);
std::unique_ptr<util::gcs::GcsUtil> gcs_util_;
};
// A ReportExporter is used by the ReportMaster to export serialized reports
// to external systems.
//
// Usage:
// Construct an instance of ReportExporter passing in an instance of
// GcsUploadInterface. In production this should be an instance of
// GcsUploader but in a test this may be a mock. This instance may
// live for the lifetime of the program, but it is not thread-safe.
// Invoke ExportReport() repeatedly.
class ReportExporter {
public:
// Constructs an instance of ReportExporter that will use |uploader| for
// uploading to Google Cloud Storage.
explicit ReportExporter(std::shared_ptr<GcsUploadInterface> uploader);
// Serializes and exports the provided report to an external system, or else
// immediately returns grpc::OK, based on the data in the provided parameters,
// as described below.
//
// report_config: The ExportConfigs from here determine how to serialize the
// report (for example to a CSV file) and the locations of where to export
// the report (for example to a Google Cloud Storage bucket.) In the case of
// exporting to Google Cloud Storage, the ExportConfig specifies a bucket and
// a folder path, but not the file name. That is taken from the |export_name|
// field of |metadata|. If the |export_name| field of |metadata| is not set
// then no exporting will be done and this method will immediately return
// grpc::OK.
//
// There may be any number of ExportConfigs. If there are zero ExportConfigs
// then no exporting will be done and this method will immediately
// return grpc::OK. If there are one or more ExportConfigs then the
// report will be exported to one or more locations and grpc::OK will be
// returned just in case all of the exports are successful.
//
// Also, the metric part names within the ReportVariables are taken from
// |report_config| and used as the column headers for the value columns of
// the serialized report. Note that the |report_type| is not taken from here
// but rather from |metadata|. This is because the report being serialized may
// be an auxilliary report rather than the primary report for the
// ReportConfig.
//
// metadata. As described previously, if the |export_name| field
// from here is empty then no exporting will be done and this method will
// immediately return grpc::OK. Otherwise the |export_name| field specifes
// part of the location of where to export the file.
//
// Also the |report_type| is taken from |metadata|. Also the list of
// |variable_indices| from here determines which ReportVariables from
// |report_config| are used, and their order.
//
// row_iterator: An iterator that will yield the actual row data to be
// serialized and exported. The type of the rows must correspond to the
// |report_type| from |metadata|.
//
// Returns grpc::OK if either no exporter was done, or if all exporting
// was successful. Otherwise logs an error and returns some other status.
grpc::Status ExportReport(const ReportConfig& report_config,
const ReportMetadataLite& metadata,
ReportRowIterator* row_iterator);
private:
friend class ReportExporterTest;
std::shared_ptr<GcsUploadInterface> uploader_;
grpc::Status ExportReportOnce(const ReportConfig& report_config,
const ReportMetadataLite& metadata,
const ReportExportConfig& export_config,
ReportRowIterator* row_iterator);
grpc::Status ExportReportToGCS(const ReportConfig& report_config,
const GCSExportLocation& location,
const ReportMetadataLite& metadata,
const std::string& mime_type,
ReportStream* report_stream);
// Builds a file path for exporting to Google Cloud Storage by concatenating
// a folder path based on the report config id, the metadata export_name,
// and a dot extension based on the mime type.
static std::string GcsPath(const ReportConfig& report_config,
const ReportMetadataLite& metadata,
const std::string& mime_type);
};
} // namespace analyzer
} // namespace cobalt
#endif // COBALT_ANALYZER_REPORT_MASTER_REPORT_EXPORTER_H_