Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions configs/static_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,8 @@ components_manager:
method: GET
task_processor: main-task-processor

handler-get-hub-reports:
load-enabled: true
path: /admin/hub_reports
method: GET
task_processor: main-task-processor
50 changes: 50 additions & 0 deletions src/api/http/v1/admin/get_hub_reports.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "get_hub_reports.hpp"

#include <app/dto/admin/get_hub_reports.hpp>

#include <infra/components/admin/admin_service_component.hpp>
#include <infra/serializer/serializer.hpp>

#include <api/http/exceptions/handler_exceptions.hpp>

#include <userver/logging/log.hpp>

namespace NCoordinator::NApi::NHandlers {

////////////////////////////////////////////////////////////////////////////////

TGetHubReportsHandler::TGetHubReportsHandler(
const userver::components::ComponentConfig& config,
const userver::components::ComponentContext& context)
: HttpHandlerJsonBase(config, context)
, AdminService_(context.FindComponent<NInfra::NComponents::TAdminServiceComponent>().GetService())
{ }

userver::formats::json::Value TGetHubReportsHandler::HandleRequestJsonThrow(
const userver::server::http::HttpRequest& /*request*/,
const userver::formats::json::Value& /*request_json*/,
userver::server::request::RequestContext& /*request_context*/) const
{
NApp::NDto::TGetHubReportsResponse result;

try {
result = AdminService_.GetHubReports();
} catch (const NApp::NUseCase::TGetPartitionMapTemporaryUnavailable& ex) {
LOG_ERROR() << "Get hub reports unavailable: " << ex.what();
throw TServerException("Get hub reports temporary unavailable");
}

userver::formats::json::ValueBuilder builder;
builder["hub_reports"] = userver::formats::common::Type::kArray;

for (const auto& hubReport : result.HubReports) {
auto serializedReport = NInfra::SerializeHubReport(hubReport);
builder["hub_reports"].PushBack(serializedReport);
}

return builder.ExtractValue();
}

////////////////////////////////////////////////////////////////////////////////

} // namespace NChat::NApi::NHandlers
34 changes: 34 additions & 0 deletions src/api/http/v1/admin/get_hub_reports.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <app/services/admin/admin_service.hpp>

#include <userver/components/component_context.hpp>
#include <userver/server/handlers/http_handler_json_base.hpp>
#include <userver/ydb/component.hpp>

namespace NCoordinator::NApi::NHandlers {

////////////////////////////////////////////////////////////////////////////////

class TGetHubReportsHandler final
: public userver::server::handlers::HttpHandlerJsonBase
{
public:
static constexpr std::string_view kName = "handler-get-hub-reports";

TGetHubReportsHandler(
const userver::components::ComponentConfig&,
const userver::components::ComponentContext&);

userver::formats::json::Value HandleRequestJsonThrow(
const userver::server::http::HttpRequest& request,
const userver::formats::json::Value& request_json,
userver::server::request::RequestContext& context) const override;

private:
NApp::NService::TAdminService& AdminService_;
};

////////////////////////////////////////////////////////////////////////////////

} // namespace NChat::NApi::NHandlers
16 changes: 16 additions & 0 deletions src/app/dto/admin/get_hub_reports.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <core/hub/hub_report.hpp>
#include <core/common/hub_params.hpp>

namespace NCoordinator::NApp::NDto {

////////////////////////////////////////////////////////////////////////////////

struct TGetHubReportsResponse {
std::vector<NCore::NDomain::THubReport> HubReports;
};

////////////////////////////////////////////////////////////////////////////////

} // namespace NCoordinator::NApp::NDto
10 changes: 9 additions & 1 deletion src/app/services/admin/admin_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ namespace NCoordinator::NApp::NService {

TAdminService::TAdminService(
NCore::NDomain::ICoordinationRepository& coordinationRepository,
NCore::NDomain::ICoordinationGateway& coordinationGateway)
NCore::NDomain::ICoordinationGateway& coordinationGateway,
NCore::NDomain::IHubGateway& hubGateway)
: GetContextUseCase_(coordinationRepository)
, GetPartitionMapUseCase_(coordinationGateway)
, GetHubReportsUseCase_(coordinationGateway, hubGateway)
{ }

NDto::TGetContextResponse TAdminService::GetCoordinationContext() const
Expand All @@ -21,6 +23,12 @@ NDto::TGetPartitionMapResponse TAdminService::GetPartitionMap() const
return GetPartitionMapUseCase_.Execute();
}

NDto::TGetHubReportsResponse TAdminService::GetHubReports() const
{
return GetHubReportsUseCase_.Execute();
}


////////////////////////////////////////////////////////////////////////////////

} // namespace NCoordinator::NApp::NService
7 changes: 6 additions & 1 deletion src/app/services/admin/admin_service.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#pragma once

#include <app/dto/admin/get_context.hpp>
#include <app/dto/admin/get_hub_reports.hpp>
#include <app/dto/admin/get_partition_map.hpp>
#include <app/use_cases/admin/get_context/get_context.hpp>
#include <app/use_cases/admin/get_partition_map/get_partition_map.hpp>
#include <app/use_cases/admin/get_hub_reports/get_hub_reports.hpp>
#include <core/coordination/coordination_gateway.hpp>
#include <core/coordination/coordination_repository.hpp>
#include <core/hub/hub_gateway.hpp>
Expand All @@ -17,14 +19,17 @@ class TAdminService final
public:
TAdminService(
NCore::NDomain::ICoordinationRepository& coordinationRepository,
NCore::NDomain::ICoordinationGateway& coordinationGateway);
NCore::NDomain::ICoordinationGateway& coordinationGateway,
NCore::NDomain::IHubGateway& hubGateway);

NDto::TGetContextResponse GetCoordinationContext() const;
NDto::TGetPartitionMapResponse GetPartitionMap() const;
NDto::TGetHubReportsResponse GetHubReports() const;

private:
NUseCase::TGetContextUseCase GetContextUseCase_;
NUseCase::TGetPartitionMapUseCase GetPartitionMapUseCase_;
NUseCase::TGetHubReportsUseCase GetHubReportsUseCase_;
};

////////////////////////////////////////////////////////////////////////////////
Expand Down
40 changes: 40 additions & 0 deletions src/app/use_cases/admin/get_hub_reports/get_hub_reports.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "get_hub_reports.hpp"

#include <core/coordination/coordination_state.hpp>

#include <userver/logging/log.hpp>

#include <fmt/format.h>

namespace NCoordinator::NApp::NUseCase {

////////////////////////////////////////////////////////////////////////////////

TGetHubReportsUseCase::TGetHubReportsUseCase(
NCore::NDomain::ICoordinationGateway& coordinationGateway,
NCore::NDomain::IHubGateway& hubGateway)
: CoordinationGateway_(coordinationGateway)
, HubGateway_(hubGateway)
{ }

NDto::TGetHubReportsResponse TGetHubReportsUseCase::Execute() const
{
std::vector<NCore::NDomain::THubReport> hubReports;

try {
auto hubDiscovery = CoordinationGateway_.GetHubDiscovery();
hubReports = HubGateway_.GetHubReports(hubDiscovery);
} catch (std::exception& ex) {
throw TGetHubReportsTemporaryUnavailable(fmt::format("Failed to get hub reports: {}", ex.what()));
}

NDto::TGetHubReportsResponse response{
.HubReports = std::move(hubReports),
};

return response;
}

////////////////////////////////////////////////////////////////////////////////

} // namespace NCoordinator::NApp::NUseCase
34 changes: 34 additions & 0 deletions src/app/use_cases/admin/get_hub_reports/get_hub_reports.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <app/exceptions.hpp>
#include <app/dto/admin/get_hub_reports.hpp>
#include <core/coordination/coordination_gateway.hpp>
#include <core/hub/hub_gateway.hpp>

namespace NCoordinator::NApp::NUseCase {

////////////////////////////////////////////////////////////////////////////////

class TGetHubReportsTemporaryUnavailable
: public TApplicationException
{
using TApplicationException::TApplicationException;
};

class TGetHubReportsUseCase final
{
public:
TGetHubReportsUseCase(
NCore::NDomain::ICoordinationGateway& coordinationGateway,
NCore::NDomain::IHubGateway& hubGateway);

NDto::TGetHubReportsResponse Execute() const;

private:
NCore::NDomain::ICoordinationGateway& CoordinationGateway_;
NCore::NDomain::IHubGateway& HubGateway_;
};

////////////////////////////////////////////////////////////////////////////////

} // namespace NCoordinator::NApp::NUseCase
5 changes: 4 additions & 1 deletion src/infra/components/admin/admin_service_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <infra/components/coordination/coordination_gateway_component.hpp>
#include <infra/components/coordination/coordination_repository_component.hpp>
#include <infra/components/hub/hub_gateway_component.hpp>

#include <userver/components/component.hpp>
#include <userver/components/component_context.hpp>
Expand All @@ -19,9 +20,11 @@ TAdminServiceComponent::TAdminServiceComponent(
context.FindComponent<NComponents::TCoordinationRepositoryComponent>().GetRepository();
auto& coordinationGateway =
context.FindComponent<NComponents::TCoordinationGatewayComponent>().GetGateway();
auto& hubGateway =
context.FindComponent<NComponents::THubGatewayComponent>().GetGateway();


Service_ = std::make_unique<NApp::NService::TAdminService>(coordinationRepository, coordinationGateway);
Service_ = std::make_unique<NApp::NService::TAdminService>(coordinationRepository, coordinationGateway,hubGateway);
}

NApp::NService::TAdminService& TAdminServiceComponent::GetService()
Expand Down
2 changes: 2 additions & 0 deletions src/infra/components/components.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "components.hpp"

#include <api/http/v1/admin/get_context.hpp>
#include <api/http/v1/admin/get_hub_reports.hpp>
#include <api/http/v1/admin/get_partition_map.hpp>
#include <infra/components/admin/admin_service_component.hpp>
#include <infra/components/leader/leader_service_component.hpp>
Expand Down Expand Up @@ -65,6 +66,7 @@ void RegisterServices(userver::components::ComponentList& list)
void RegisterHandlers(userver::components::ComponentList& list)
{
list.Append<NApi::NHandlers::TGetContextHandler>()
.Append<NApi::NHandlers::TGetHubReportsHandler>()
.Append<NApi::NHandlers::TGetPartitionMapHandler>();
}

Expand Down
42 changes: 34 additions & 8 deletions src/infra/serializer/serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ namespace {
////////////////////////////////////////////////////////////////////////////////

constexpr inline std::string_view EPOCH_KEY = "epoch";
constexpr inline std::string_view DC_KEY = "dc";
constexpr inline std::string_view LOAD_FACTOR_KEY = "load_factor";
constexpr inline std::string_view PARTITIONS_KEY = "partitions";
constexpr inline std::string_view PARTITION_ID_KEY = "id";
constexpr inline std::string_view PARTITION_WEIGHT_KEY = "partition_weight";
constexpr inline std::string_view PARTITIONS_CONTEXT_KEY = "partitions_context";
constexpr inline std::string_view HUB_ENDPOINT_KEY = "hub";
constexpr inline std::string_view HUB_KEY = "hub";
constexpr inline std::string_view ENDPOINT_KEY = "endpoint";
constexpr inline std::string_view COOLDOWN_EPOCH_KEY = "cooldown_epoch";

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -38,7 +41,7 @@ userver::formats::json::Value SerializePartitionMap(
for (const auto& [partition, hub] : partitionMap.Partitions) {
userver::formats::json::ValueBuilder pair;
pair[PARTITION_ID_KEY.data()] = partition.GetUnderlying();
pair[HUB_ENDPOINT_KEY.data()] = hub.GetUnderlying();
pair[HUB_KEY.data()] = hub.GetUnderlying();

result[PARTITIONS_KEY.data()].PushBack(pair.ExtractValue());
}
Expand Down Expand Up @@ -77,6 +80,29 @@ userver::formats::json::Value SerializeCoordinationContext(const NCore::NDomain:
return result.ExtractValue();
}

userver::formats::json::Value SerializeHubReport(const NCore::NDomain::THubReport& report)
{
userver::formats::json::ValueBuilder builder;

builder[EPOCH_KEY.data()] = std::to_string(report.Epoch.GetUnderlying());

builder[ENDPOINT_KEY.data()] = report.Endpoint.GetUnderlying();
builder[DC_KEY.data()] = report.DC.GetUnderlying();

builder[LOAD_FACTOR_KEY.data()] = report.LoadFactor.GetUnderlying();

userver::formats::json::ValueBuilder partitionsBuilder(userver::formats::common::Type::kObject);

for (const auto& [partitionId, partitionWeight] : report.PartitionWeights) {
partitionsBuilder[std::to_string(partitionId.GetUnderlying())] =
std::to_string(partitionWeight.GetUnderlying());
}

builder[PARTITIONS_KEY.data()] = partitionsBuilder;

return builder.ExtractValue();
}

NCore::NDomain::TPartitionMap DeserializePartitionMap(const userver::formats::json::Value& jsonValue)
{
NCore::NDomain::TPartitionMap result;
Expand All @@ -89,7 +115,7 @@ NCore::NDomain::TPartitionMap DeserializePartitionMap(const userver::formats::js
pair[PARTITION_ID_KEY.data()].As<NCore::NDomain::TPartitionId::UnderlyingType>()
};
NCore::NDomain::THubEndpoint hubEndpoint{
pair[HUB_ENDPOINT_KEY.data()].As<NCore::NDomain::THubEndpoint::UnderlyingType>()
pair[HUB_KEY.data()].As<NCore::NDomain::THubEndpoint::UnderlyingType>()
};

result.Partitions.emplace_back(std::move(partitionId), std::move(hubEndpoint));
Expand Down Expand Up @@ -124,19 +150,19 @@ NCore::NDomain::THubReport DeserializeHubReport(const userver::formats::json::Va
NCore::NDomain::THubReport report;

report.Epoch = NCore::NDomain::TEpoch{
std::stoull(jsonValue["epoch"].As<std::string>())
std::stoull(jsonValue[EPOCH_KEY.data()].As<std::string>())
};
report.Endpoint = NCore::NDomain::THubEndpoint{
jsonValue["endpoint"].As<std::string>()
jsonValue[ENDPOINT_KEY.data()].As<std::string>()
};
report.DC = NCore::NDomain::THubDC{
jsonValue["dc"].As<std::string>()
jsonValue[DC_KEY.data()].As<std::string>()
};
report.LoadFactor = NCore::NDomain::TLoadFactor{
jsonValue["load_factor"].As<std::uint64_t>()
jsonValue[LOAD_FACTOR_KEY.data()].As<std::uint64_t>()
};

const auto& partitionsJson = jsonValue["partitions"];
const auto& partitionsJson = jsonValue[PARTITIONS_KEY];
for (auto it = partitionsJson.begin(); it != partitionsJson.end(); ++it) {
NCore::NDomain::TPartitionId partitionId{
std::stoull(it.GetName())
Expand Down
2 changes: 2 additions & 0 deletions src/infra/serializer/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ userver::formats::json::Value SerializePartitionMap(const NCore::NDomain::TParti

userver::formats::json::Value SerializeCoordinationContext(const NCore::NDomain::TCoordinationContext& context);

userver::formats::json::Value SerializeHubReport(const NCore::NDomain::THubReport& report);

NCore::NDomain::TPartitionMap DeserializePartitionMap(const userver::formats::json::Value& jsonValue);

NCore::NDomain::TCoordinationContext DeserializeCoordinationContext(const userver::formats::json::Value& json);
Expand Down
Loading