aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfedor-miron <fedor-miron@yandex-team.com>2023-10-26 19:54:00 +0300
committerfedor-miron <fedor-miron@yandex-team.com>2023-10-26 20:42:45 +0300
commit9fc3c43b3476e61fe0df7d4c9906e44768bc7fa8 (patch)
tree0e6a3c86e7498aa399754153c7d6432dc8572286
parentb16aeda846e10a5c9df3b862583b2e36f2ef7c6a (diff)
downloadydb-9fc3c43b3476e61fe0df7d4c9906e44768bc7fa8.tar.gz
YQL-16949: emit warning instead of exception on yt folder access denied
-rw-r--r--ydb/library/yql/providers/yt/gateway/lib/yt_helpers.cpp15
-rw-r--r--ydb/library/yql/providers/yt/gateway/lib/yt_helpers.h2
-rw-r--r--ydb/library/yql/providers/yt/gateway/native/ut/yql_yt_native_folders_ut.cpp33
-rw-r--r--ydb/library/yql/providers/yt/gateway/native/yql_yt_native.cpp3
-rw-r--r--ydb/library/yql/providers/yt/gateway/native/yql_yt_native_folders.cpp24
5 files changed, 62 insertions, 15 deletions
diff --git a/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.cpp b/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.cpp
index 6ed2dcb3a7..316a880306 100644
--- a/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.cpp
+++ b/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.cpp
@@ -570,12 +570,16 @@ void CreateParents(const TVector<TString>& tables, NYT::IClientBasePtr tx) {
}
}
+TIssue MakeIssueFromYtError(const NYT::TYtError& e, TStringBuf what, TPosition pos, bool shortErrors) {
+ TString errMsg = shortErrors || GetEnv("YQL_DETERMINISTIC_MODE") ? e.ShortDescription() : TString(what);
+ EYqlIssueCode rootIssueCode = IssueCodeForYtError(e);
+ return YqlIssue(pos, rootIssueCode, errMsg);
+}
+
namespace {
void FillResultFromOperationError(NCommon::TOperationResult& result, const NYT::TOperationFailedError& e, TPosition pos, bool shortErrors) {
- TString errMsg = shortErrors || GetEnv("YQL_DETERMINISTIC_MODE") ? e.GetError().ShortDescription() : TString(e.what());
- EYqlIssueCode rootIssueCode = IssueCodeForYtError(e.GetError());
- TIssue rootIssue = YqlIssue(pos, rootIssueCode, errMsg);
+ TIssue rootIssue = MakeIssueFromYtError(e.GetError(), e.what(), pos, shortErrors);
if (!e.GetFailedJobInfo().empty()) {
TSet<TString> uniqueErrors;
@@ -600,10 +604,7 @@ void FillResultFromOperationError(NCommon::TOperationResult& result, const NYT::
}
void FillResultFromErrorResponse(NCommon::TOperationResult& result, const NYT::TErrorResponse& e, TPosition pos, bool shortErrors) {
- TString errMsg = shortErrors || GetEnv("YQL_DETERMINISTIC_MODE") ? e.GetError().ShortDescription() : TString(e.what());
-
- EYqlIssueCode rootIssueCode = IssueCodeForYtError(e.GetError());
- TIssue rootIssue = YqlIssue(pos, rootIssueCode, errMsg);
+ TIssue rootIssue = MakeIssueFromYtError(e.GetError(), e.what(), pos, shortErrors);
result.SetStatus(TIssuesIds::DEFAULT_ERROR);
result.AddIssue(rootIssue);
diff --git a/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.h b/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.h
index 151399ede7..7c5c3cce63 100644
--- a/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.h
+++ b/ydb/library/yql/providers/yt/gateway/lib/yt_helpers.h
@@ -67,4 +67,6 @@ IYtGateway::TCanonizedPath CanonizedPath(const TString& path);
void EnsureSpecDoesntUseNativeYtTypes(const NYT::TNode& spec, TStringBuf tableName, bool read);
+TIssue MakeIssueFromYtError(const NYT::TYtError& e, TStringBuf what, TPosition pos = {}, bool shortErrors = false);
+
} // NYql
diff --git a/ydb/library/yql/providers/yt/gateway/native/ut/yql_yt_native_folders_ut.cpp b/ydb/library/yql/providers/yt/gateway/native/ut/yql_yt_native_folders_ut.cpp
index 3d2a54f58b..9b2a0716e6 100644
--- a/ydb/library/yql/providers/yt/gateway/native/ut/yql_yt_native_folders_ut.cpp
+++ b/ydb/library/yql/providers/yt/gateway/native/ut/yql_yt_native_folders_ut.cpp
@@ -37,6 +37,12 @@ constexpr auto CYPRES_NODE_A_CONTENT = R"(
"broken" = %true;
"type" = "link";
> "link_broken";
+ <
+ "user_attributes" = {};
+ "target_path" = "//link_access_denied";
+ "broken" = %false;
+ "type" = "link";
+ > "link_access_denied";
];
};
]
@@ -51,10 +57,23 @@ constexpr auto CYPRES_LINK_DEST = R"(
};
]
)";
+
+constexpr auto CYPRES_ACCESS_ERROR = R"(
+[
+ {
+ "error" = {
+ "code" = 901;
+ "message" = "Access denied";
+ }
+ }
+]
+)";
+
TVector<IYtGateway::TFolderResult::TFolderItem> EXPECTED_ITEMS {
{"test/a/a", "table", R"({"user_attributes"={}})"},
{"test/a/b", "table", R"({"user_attributes"={}})"},
- {"test/a/link", "table", R"({"user_attributes"={}})"}
+ {"test/a/link", "table", R"({"user_attributes"={}})"},
+ {"test/a/link_access_denied", "unknown", "{}"}
};
TGatewaysConfig MakeGatewaysConfig(size_t port)
@@ -99,6 +118,10 @@ public:
private:
void CheckReqAttributes(TStringBuf path, const NYT::TNode& attributes) {
+ if (!requiredAttributes.contains(path)) {
+ return;
+ }
+
THashSet<TString> attributesSet;
for (const auto& attribute : attributes.AsList()) {
attributesSet.insert(attribute.AsString());
@@ -125,6 +148,10 @@ private:
resp.SetContent(CYPRES_LINK_DEST);
return resp;
}
+ if (path == "//link_access_denied") {
+ resp.SetContent(CYPRES_ACCESS_ERROR);
+ return resp;
+ }
return THttpResponse{HTTP_NOT_FOUND};
}
@@ -187,10 +214,14 @@ Y_UNIT_TEST(GetFolder) {
folderFuture.Wait();
ytState->Gateway->CloseSession({ytState->SessionId});
auto folderRes = folderFuture.GetValue();
+
UNIT_ASSERT_EQUAL_C(folderRes.Success(), true, folderRes.Issues().ToString());
UNIT_ASSERT_EQUAL(
folderRes.ItemsOrFileLink,
(std::variant<TVector<IYtGateway::TFolderResult::TFolderItem>, TFileLinkPtr>(EXPECTED_ITEMS)));
+
+ UNIT_ASSERT_EQUAL(folderRes.Issues().Size(), 1);
+ UNIT_ASSERT_EQUAL(folderRes.Issues().back().Severity, TSeverityIds::S_WARNING);
}
}
diff --git a/ydb/library/yql/providers/yt/gateway/native/yql_yt_native.cpp b/ydb/library/yql/providers/yt/gateway/native/yql_yt_native.cpp
index 26b770adbe..2247d7b753 100644
--- a/ydb/library/yql/providers/yt/gateway/native/yql_yt_native.cpp
+++ b/ydb/library/yql/providers/yt/gateway/native/yql_yt_native.cpp
@@ -523,8 +523,9 @@ public:
auto resolveRes = f.GetValue();
TFolderResult res;
+ res.AddIssues(resolveRes.Issues());
+
if (!resolveRes.Success()) {
- res.AddIssues(resolveRes.Issues());
res.SetStatus(resolveRes.Status());
return res;
}
diff --git a/ydb/library/yql/providers/yt/gateway/native/yql_yt_native_folders.cpp b/ydb/library/yql/providers/yt/gateway/native/yql_yt_native_folders.cpp
index 1fdc86f8ef..84b83d6fdd 100644
--- a/ydb/library/yql/providers/yt/gateway/native/yql_yt_native_folders.cpp
+++ b/ydb/library/yql/providers/yt/gateway/native/yql_yt_native_folders.cpp
@@ -116,11 +116,12 @@ TFileLinkPtr SaveItemsToTempFile(const TExecContext<IYtGateway::TBatchFolderOpti
IYtGateway::TBatchFolderResult ExecResolveLinks(const TExecContext<IYtGateway::TResolveOptions>::TPtr& execCtx) {
try {
auto batchGet = execCtx->GetEntry()->Tx->CreateBatchRequest();
- TVector<TFuture<IYtGateway::TBatchFolderResult::TFolderItem>> batchRes;
+ using TFolderItemWithWarning = std::pair<IYtGateway::TBatchFolderResult::TFolderItem, TMaybe<TIssue>>;
+ TVector<TFuture<TFolderItemWithWarning>> batchRes;
for (const auto& [item, reqAttributes]: execCtx->Options_.Items()) {
if (item.Type != "link") {
- batchRes.push_back(MakeFuture<IYtGateway::TBatchFolderResult::TFolderItem>(std::move(item)));
+ batchRes.push_back(MakeFuture<TFolderItemWithWarning>({std::move(item), {}}));
continue;
}
if (item.Attributes["broken"].AsBool()) {
@@ -132,9 +133,16 @@ IYtGateway::TBatchFolderResult ExecResolveLinks(const TExecContext<IYtGateway::T
batchRes.push_back(
batchGet->Get(targetPath, TGetOptions().AttributeFilter(attrFilter))
- .Apply([path] (const auto& f) {
- const auto linkNode = f.GetValue();
- return MakeFolderItem(linkNode, path);
+ .Apply([path, pos = execCtx->Options_.Pos()] (const auto& f) ->TFolderItemWithWarning {
+ try {
+ const auto linkNode = f.GetValue();
+ return {MakeFolderItem(linkNode, path), {}};
+ } catch (const NYT::TErrorResponse& e) {
+ auto warn = MakeIssueFromYtError(e.GetError(), e.what(), pos);
+ warn.Severity = TSeverityIds::S_WARNING;
+
+ return {MakeFolderItem(NYT::TNode::CreateMap(), path), MakeMaybe(warn)};
+ }
})
);
}
@@ -148,7 +156,11 @@ IYtGateway::TBatchFolderResult ExecResolveLinks(const TExecContext<IYtGateway::T
batchGet->ExecuteBatch();
WaitAll(batchRes).Wait();
for (auto& f : batchRes) {
- res.Items.emplace_back(f.ExtractValue());
+ auto [item, maybeWarn] = f.ExtractValue();
+ if (maybeWarn) {
+ res.AddIssue(maybeWarn.GetRef());
+ }
+ res.Items.push_back(std::move(item));
}
return res;
}