|
7 | 7 | #include <ydb/library/actors/core/event_local.h>
|
8 | 8 | #include <ydb/library/actors/core/actor_bootstrapped.h>
|
9 | 9 | #include <library/cpp/string_utils/base64/base64.h>
|
| 10 | +#include <ydb/public/sdk/cpp/client/draft/ydb_replication.h> |
10 | 11 | #include <ydb/public/sdk/cpp/client/ydb_driver/driver.h>
|
11 | 12 | #include <ydb/public/sdk/cpp/client/ydb_scheme/scheme.h>
|
12 | 13 | #include <ydb/public/sdk/cpp/client/ydb_table/table.h>
|
13 | 14 | #include <ydb/public/sdk/cpp/client/ydb_topic/topic.h>
|
| 15 | +#include <ydb/public/sdk/cpp/client/ydb_query/client.h> |
14 | 16 | #include <ydb/public/sdk/cpp/client/ydb_types/status_codes.h>
|
| 17 | +#include <ydb/public/sdk/cpp/client/ydb_value/value.h> |
15 | 18 | #include <ydb/public/sdk/cpp/client/resources/ydb_resources.h>
|
| 19 | +#include <ydb/public/sdk/cpp/client/ydb_proto/accessor.h> |
16 | 20 | #include <ydb/public/api/protos/ydb_operation.pb.h>
|
17 | 21 | #include <ydb/public/api/protos/ydb_cms.pb.h>
|
18 | 22 | #include <ydb/public/lib/deprecated/client/grpc_client.h>
|
19 | 23 | #include <ydb/library/yql/public/issue/yql_issue_message.h>
|
20 | 24 | #include <ydb/library/yql/public/issue/yql_issue_manager.h>
|
| 25 | +#include <ydb/public/api/protos/draft/ydb_replication.pb.h> |
21 | 26 | #include "appdata.h"
|
22 | 27 | #include "merger.h"
|
23 | 28 | #include "core_ydb.h"
|
@@ -79,6 +84,9 @@ struct THandlerActorYdb {
|
79 | 84 | EvExplainYqlResponse,
|
80 | 85 | EvDescribeTopicResult,
|
81 | 86 | EvDescribeConsumerResult,
|
| 87 | + EvDescribeReplicationResult, |
| 88 | + EvExecuteQueryIterator, |
| 89 | + EvExecuteQueryPart, |
82 | 90 | EvEnd
|
83 | 91 | };
|
84 | 92 |
|
@@ -134,6 +142,14 @@ struct THandlerActorYdb {
|
134 | 142 | {}
|
135 | 143 | };
|
136 | 144 |
|
| 145 | + struct TEvDescribeReplicationResult : NActors::TEventLocal<TEvDescribeReplicationResult, EvDescribeReplicationResult> { |
| 146 | + NYdb::NReplication::TDescribeReplicationResult Result; |
| 147 | + |
| 148 | + TEvDescribeReplicationResult(NYdb::NReplication::TDescribeReplicationResult&& result) |
| 149 | + : Result(std::move(result)) { |
| 150 | + } |
| 151 | + }; |
| 152 | + |
137 | 153 | struct TEvDataStreamsListResponse : NActors::TEventLocal<TEvDataStreamsListResponse, EvDataStreamsListResponse> {
|
138 | 154 | NYdb::NDataStreams::V1::TListStreamsResult Result;
|
139 | 155 |
|
@@ -447,6 +463,24 @@ struct THandlerActorYdb {
|
447 | 463 | struct TEvRetryRequest : NActors::TEventLocal<TEvRetryRequest, EvRetryRequest> {
|
448 | 464 | };
|
449 | 465 |
|
| 466 | + struct TEvExecuteQueryIterator : NActors::TEventLocal<TEvExecuteQueryIterator, EvExecuteQueryIterator> { |
| 467 | + NYdb::NQuery::TExecuteQueryIterator Iterator; |
| 468 | + |
| 469 | + TEvExecuteQueryIterator() = delete; |
| 470 | + TEvExecuteQueryIterator(NYdb::NQuery::TExecuteQueryIterator&& iterator) |
| 471 | + : Iterator(std::move(iterator)) |
| 472 | + {} |
| 473 | + }; |
| 474 | + |
| 475 | + struct TEvExecuteQueryPart : NActors::TEventLocal<TEvExecuteQueryPart, EvExecuteQueryPart> { |
| 476 | + NYdb::NQuery::TExecuteQueryPart Part; |
| 477 | + |
| 478 | + TEvExecuteQueryPart() = delete; |
| 479 | + TEvExecuteQueryPart(NYdb::NQuery::TExecuteQueryPart&& part) |
| 480 | + : Part(std::move(part)) |
| 481 | + {} |
| 482 | + }; |
| 483 | + |
450 | 484 | struct TEvErrorResponse : NActors::TEventLocal<TEvErrorResponse, EvErrorResponse> {
|
451 | 485 | TString Status;
|
452 | 486 | TString Message;
|
@@ -611,6 +645,48 @@ struct THandlerActorYdb {
|
611 | 645 | }
|
612 | 646 | }
|
613 | 647 |
|
| 648 | + static NJson::TJsonValue TypedValueToJsonValue(const Ydb::TypedValue& typedValue) { |
| 649 | + NYdb::TType type(typedValue.type()); |
| 650 | + NYdb::TValue value(type, typedValue.value()); |
| 651 | + NYdb::TValueParser parser(value); |
| 652 | + return ColumnValueToJsonValue(parser); |
| 653 | + } |
| 654 | + |
| 655 | + static void WriteColumns(NJson::TJsonValue& columns, |
| 656 | + const NYdb::NTable::TTableDescription& tableDescription, |
| 657 | + const std::function<void(NJson::TJsonValue&, NYdb::TType)>& columnTypeFormatter = ColumnTypeToString) { |
| 658 | + auto columnsMeta = tableDescription.GetColumns(); |
| 659 | + auto columnsKeysMeta = tableDescription.GetPrimaryKeyColumns(); |
| 660 | + auto proto = NYdb::TProtoAccessor::GetProto(tableDescription); |
| 661 | + int columnsSize = std::min<int>(proto.columns_size(), columnsMeta.size()); |
| 662 | + for (int columnNum = 0; columnNum < columnsSize; ++columnNum) { |
| 663 | + const NYdb::TColumn& columnMeta = columnsMeta[columnNum]; |
| 664 | + const Ydb::Table::ColumnMeta& columnProto = proto.columns(columnNum); |
| 665 | + NJson::TJsonValue& column = columns.AppendValue(NJson::TJsonValue()); |
| 666 | + column["name"] = columnMeta.Name; |
| 667 | + columnTypeFormatter(column["type"], columnMeta.Type); |
| 668 | + auto itKey = Find(columnsKeysMeta, columnMeta.Name); |
| 669 | + if (itKey != columnsKeysMeta.end()) { |
| 670 | + column["key"] = true; |
| 671 | + column["keyOrder"] = itKey - columnsKeysMeta.begin(); |
| 672 | + } |
| 673 | + if (columnProto.not_null()) { |
| 674 | + column["not_null"] = true; |
| 675 | + } |
| 676 | + switch (columnProto.default_value_case()) { |
| 677 | + case Ydb::Table::ColumnMeta::DEFAULT_VALUE_NOT_SET: |
| 678 | + case Ydb::Table::ColumnMeta::kEmptyDefault: |
| 679 | + break; |
| 680 | + case Ydb::Table::ColumnMeta::kFromLiteral: |
| 681 | + column["defaultValue"] = TypedValueToJsonValue(columnProto.from_literal()); |
| 682 | + break; |
| 683 | + case Ydb::Table::ColumnMeta::kFromSequence: |
| 684 | + column["defaultSequence"] = columnProto.from_sequence().name(); |
| 685 | + break; |
| 686 | + } |
| 687 | + } |
| 688 | + } |
| 689 | + |
614 | 690 | static void WriteIndexes(NJson::TJsonValue& indexes,
|
615 | 691 | const TVector<NYdb::NTable::TIndexDescription>& indexesMeta) {
|
616 | 692 | indexes.SetType(NJson::JSON_ARRAY);
|
@@ -707,6 +783,27 @@ struct THandlerActorYdb {
|
707 | 783 | }
|
708 | 784 | }
|
709 | 785 |
|
| 786 | + static TString BlackBoxTokenFromSessionId(TStringBuf sessionId, TStringBuf userIp = NKikimr::NSecurity::DefaultUserIp()) { |
| 787 | + return NKikimr::NSecurity::BlackBoxTokenFromSessionId(sessionId, userIp); |
| 788 | + } |
| 789 | + |
| 790 | + static TString GetAuthToken(NHttp::THttpIncomingRequestPtr request) { |
| 791 | + NHttp::THeaders headers(request->Headers); |
| 792 | + NHttp::TCookies cookies(headers["Cookie"]); |
| 793 | + TStringBuf sessionId = cookies["Session_id"]; |
| 794 | + if (!sessionId.empty()) { |
| 795 | + return BlackBoxTokenFromSessionId(sessionId); |
| 796 | + } |
| 797 | + TStringBuf authorization = headers["Authorization"]; |
| 798 | + if (!authorization.empty()) { |
| 799 | + TStringBuf scheme = authorization.NextTok(' '); |
| 800 | + if (scheme == "OAuth" || scheme == "Bearer") { |
| 801 | + return TString(authorization); |
| 802 | + } |
| 803 | + } |
| 804 | + return TString(); |
| 805 | + } |
| 806 | + |
710 | 807 | static void CopyHeader(const NHttp::THeaders& request, NHttp::THeadersBuilder& headers, TStringBuf header) {
|
711 | 808 | if (request.Has(header)) {
|
712 | 809 | headers.Set(header, request[header]);
|
@@ -763,6 +860,65 @@ struct THandlerActorYdb {
|
763 | 860 | return false;
|
764 | 861 | }
|
765 | 862 |
|
| 863 | + static NHttp::THttpOutgoingResponsePtr CreateStatusResponseForQuery(NHttp::THttpIncomingRequestPtr request, const NYdb::TStatus& status, const TJsonSettings& jsonSettings = TJsonSettings()) { |
| 864 | + Ydb::Operations::Operation operation; |
| 865 | + operation.set_status(static_cast<Ydb::StatusIds_StatusCode>(status.GetStatus())); |
| 866 | + IssuesToMessage(status.GetIssues(), operation.mutable_issues()); |
| 867 | + return CreateStatusResponseForQuery(request, operation, jsonSettings); |
| 868 | + } |
| 869 | + |
| 870 | + static NHttp::THttpOutgoingResponsePtr CreateStatusResponseForQuery(NHttp::THttpIncomingRequestPtr request, const Ydb::Operations::Operation& operation, const TJsonSettings& jsonSettings = TJsonSettings()) { |
| 871 | + TStringBuf status = "503"; |
| 872 | + TStringBuf message = "Service Unavailable"; |
| 873 | + switch ((int)operation.status()) { |
| 874 | + case Ydb::StatusIds::SUCCESS: |
| 875 | + case Ydb::StatusIds::SCHEME_ERROR: |
| 876 | + case Ydb::StatusIds::GENERIC_ERROR: |
| 877 | + case Ydb::StatusIds::TIMEOUT: |
| 878 | + case (int)NYdb::EStatus::CLIENT_DEADLINE_EXCEEDED: |
| 879 | + status = "200"; |
| 880 | + message = "OK"; |
| 881 | + break; |
| 882 | + case Ydb::StatusIds::UNAUTHORIZED: |
| 883 | + case (int)NYdb::EStatus::CLIENT_UNAUTHENTICATED: |
| 884 | + status = "401"; |
| 885 | + message = "Unauthorized"; |
| 886 | + break; |
| 887 | + case Ydb::StatusIds::BAD_REQUEST: |
| 888 | + case Ydb::StatusIds::BAD_SESSION: |
| 889 | + case Ydb::StatusIds::PRECONDITION_FAILED: |
| 890 | + case Ydb::StatusIds::ALREADY_EXISTS: |
| 891 | + case Ydb::StatusIds::SESSION_EXPIRED: |
| 892 | + case Ydb::StatusIds::UNDETERMINED: |
| 893 | + case Ydb::StatusIds::ABORTED: |
| 894 | + case Ydb::StatusIds::UNSUPPORTED: |
| 895 | + status = "400"; |
| 896 | + message = "Bad Request"; |
| 897 | + break; |
| 898 | + case Ydb::StatusIds::NOT_FOUND: |
| 899 | + status = "404"; |
| 900 | + message = "Not Found"; |
| 901 | + break; |
| 902 | + case Ydb::StatusIds::OVERLOADED: |
| 903 | + status = "429"; |
| 904 | + message = "Overloaded"; |
| 905 | + break; |
| 906 | + case Ydb::StatusIds::INTERNAL_ERROR: |
| 907 | + status = "500"; |
| 908 | + message = "Internal Server Error"; |
| 909 | + break; |
| 910 | + case Ydb::StatusIds::UNAVAILABLE: |
| 911 | + status = "503"; |
| 912 | + message = "Service Unavailable"; |
| 913 | + break; |
| 914 | + default: |
| 915 | + break; |
| 916 | + } |
| 917 | + TStringStream stream; |
| 918 | + TProtoToJson::ProtoToJson(stream, operation, jsonSettings); |
| 919 | + return request->CreateResponse(status, message, "application/json", stream.Str()); |
| 920 | + } |
| 921 | + |
766 | 922 | static NHttp::THttpOutgoingResponsePtr CreateStatusResponse(NHttp::THttpIncomingRequestPtr request, const NYdb::TStatus& status, const TJsonSettings& jsonSettings = TJsonSettings()) {
|
767 | 923 | Ydb::Operations::Operation operation;
|
768 | 924 | operation.set_status(static_cast<Ydb::StatusIds_StatusCode>(status.GetStatus()));
|
@@ -813,6 +969,7 @@ struct THandlerActorYdb {
|
813 | 969 | message = "Service Unavailable";
|
814 | 970 | break;
|
815 | 971 | case Ydb::StatusIds::TIMEOUT:
|
| 972 | + case (int)NYdb::EStatus::CLIENT_DEADLINE_EXCEEDED: |
816 | 973 | status = "504";
|
817 | 974 | message = "Gateway Time-out";
|
818 | 975 | break;
|
|
0 commit comments