@@ -27,11 +27,14 @@ using TEvExportToYtRequest = TGrpcRequestOperationCall<Ydb::Export::ExportToYtRe
2727 Ydb::Export::ExportToYtResponse>;
2828using TEvExportToS3Request = TGrpcRequestOperationCall<Ydb::Export::ExportToS3Request,
2929 Ydb::Export::ExportToS3Response>;
30+ using TEvExportToFsRequest = TGrpcRequestOperationCall<Ydb::Export::ExportToFsRequest,
31+ Ydb::Export::ExportToFsResponse>;
3032
3133template <typename TDerived, typename TEvRequest>
3234class TExportRPC : public TRpcOperationRequestActor <TDerived, TEvRequest, true >, public TExportConv {
3335 static constexpr bool IsS3Export = std::is_same_v<TEvRequest, TEvExportToS3Request>;
3436 static constexpr bool IsYtExport = std::is_same_v<TEvRequest, TEvExportToYtRequest>;
37+ static constexpr bool IsFsExport = std::is_same_v<TEvRequest, TEvExportToFsRequest>;
3538
3639 struct TExportItemInfo {
3740 TString Destination;
@@ -102,6 +105,16 @@ class TExportRPC: public TRpcOperationRequestActor<TDerived, TEvRequest, true>,
102105 item->set_destination_prefix (info.Destination );
103106 }
104107 }
108+ if constexpr (IsFsExport) {
109+ auto * exportSettings = createExport.MutableExportToFsSettings ();
110+ *exportSettings = request.settings ();
111+ exportSettings->clear_items ();
112+ for (const auto & [sourcePath, info] : ExportItems) {
113+ auto * item = exportSettings->add_items ();
114+ item->set_source_path (sourcePath);
115+ item->set_destination_path (info.Destination );
116+ }
117+ }
105118
106119 return ev.Release ();
107120 }
@@ -130,6 +143,9 @@ class TExportRPC: public TRpcOperationRequestActor<TDerived, TEvRequest, true>,
130143 if constexpr (IsYtExport) {
131144 it->second .Destination = item.destination_path ();
132145 }
146+ if constexpr (IsFsExport) {
147+ it->second .Destination = item.destination_path ();
148+ }
133149 }
134150
135151 if constexpr (IsS3Export) {
@@ -446,6 +462,24 @@ class TExportRPC: public TRpcOperationRequestActor<TDerived, TEvRequest, true>,
446462 }
447463 }
448464 }
465+ if constexpr (IsFsExport) {
466+ if (!settings.base_path ().StartsWith (" /" )) {
467+ return this ->Reply (StatusIds::BAD_REQUEST, TIssuesIds::DEFAULT_ERROR,
468+ " base_path must be an absolute path" );
469+ }
470+
471+ if (settings.compression ()) {
472+ StatusIds::StatusCode status;
473+ TString error;
474+ if (!CheckCompression (settings.compression (), status, error)) {
475+ return this ->Reply (status, TIssuesIds::DEFAULT_ERROR, error);
476+ }
477+ }
478+
479+ if (settings.items ().empty ()) {
480+ return this ->Reply (StatusIds::BAD_REQUEST, TIssuesIds::DEFAULT_ERROR, " Items are not set" );
481+ }
482+ }
449483
450484 if constexpr (std::is_same_v<TEvRequest, TEvExportToS3Request>) {
451485 if (settings.compression ()) {
@@ -496,6 +530,11 @@ class TExportToS3RPC: public TExportRPC<TExportToS3RPC, TEvExportToS3Request> {
496530 using TExportRPC::TExportRPC;
497531};
498532
533+ class TExportToFsRPC : public TExportRPC <TExportToFsRPC, TEvExportToFsRequest> {
534+ public:
535+ using TExportRPC::TExportRPC;
536+ };
537+
499538void DoExportToYtRequest (std::unique_ptr<IRequestOpCtx> p, const IFacilityProvider& f) {
500539 f.RegisterActor (new TExportToYtRPC (p.release ()));
501540}
@@ -504,5 +543,9 @@ void DoExportToS3Request(std::unique_ptr<IRequestOpCtx> p, const IFacilityProvid
504543 f.RegisterActor (new TExportToS3RPC (p.release ()));
505544}
506545
546+ void DoExportToFsRequest (std::unique_ptr<IRequestOpCtx> p, const IFacilityProvider& f) {
547+ f.RegisterActor (new TExportToFsRPC (p.release ()));
548+ }
549+
507550} // namespace NGRpcService
508551} // namespace NKikimr
0 commit comments