aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil
diff options
context:
space:
mode:
authorzousar <[email protected]>2025-09-22 16:38:15 -0600
committerzousar <[email protected]>2025-09-22 16:38:15 -0600
commit1c591941878e5c5009d51a82ff61986a63bd2e11 (patch)
tree3860ab5ebddf1919aab3cca019422fa76cfcdda4 /src/zenutil
parentChange batch put responses for client reporting (diff)
parent5.7.2-pre1 (diff)
downloadzen-1c591941878e5c5009d51a82ff61986a63bd2e11.tar.xz
zen-1c591941878e5c5009d51a82ff61986a63bd2e11.zip
Merge branch 'main' into zs/put-overwrite-policy-response
Diffstat (limited to 'src/zenutil')
-rw-r--r--src/zenutil/buildstoragecache.cpp18
-rw-r--r--src/zenutil/include/zenutil/buildstoragecache.h9
-rw-r--r--src/zenutil/include/zenutil/jupiter/jupiterbuildstorage.h7
-rw-r--r--src/zenutil/include/zenutil/jupiter/jupiterhost.h35
-rw-r--r--src/zenutil/jupiter/jupiterbuildstorage.cpp47
-rw-r--r--src/zenutil/jupiter/jupiterhost.cpp66
6 files changed, 182 insertions, 0 deletions
diff --git a/src/zenutil/buildstoragecache.cpp b/src/zenutil/buildstoragecache.cpp
index e5e8db8d2..376d967d1 100644
--- a/src/zenutil/buildstoragecache.cpp
+++ b/src/zenutil/buildstoragecache.cpp
@@ -413,4 +413,22 @@ CreateZenBuildStorageCache(HttpClient& HttpClient,
return std::make_unique<ZenBuildStorageCache>(HttpClient, Stats, Namespace, Bucket, TempFolderPath, BoostBackgroundThreadCount);
}
+ZenCacheEndpointTestResult
+TestZenCacheEndpoint(std::string_view BaseUrl, const bool AssumeHttp2)
+{
+ HttpClientSettings TestClientSettings{.LogCategory = "httpcacheclient",
+ .ConnectTimeout = std::chrono::milliseconds{1000},
+ .Timeout = std::chrono::milliseconds{2000},
+ .AssumeHttp2 = AssumeHttp2,
+ .AllowResume = true,
+ .RetryCount = 0};
+ HttpClient TestHttpClient(BaseUrl, TestClientSettings);
+ HttpClient::Response TestResponse = TestHttpClient.Get("/status/builds");
+ if (TestResponse.IsSuccess())
+ {
+ return {.Success = true};
+ }
+ return {.Success = false, .FailureReason = TestResponse.ErrorMessage("")};
+};
+
} // namespace zen
diff --git a/src/zenutil/include/zenutil/buildstoragecache.h b/src/zenutil/include/zenutil/buildstoragecache.h
index a0690a16a..e6ca2c5e4 100644
--- a/src/zenutil/include/zenutil/buildstoragecache.h
+++ b/src/zenutil/include/zenutil/buildstoragecache.h
@@ -57,4 +57,13 @@ std::unique_ptr<BuildStorageCache> CreateZenBuildStorageCache(HttpClient& H
std::string_view Bucket,
const std::filesystem::path& TempFolderPath,
bool BoostBackgroundThreadCount);
+
+struct ZenCacheEndpointTestResult
+{
+ bool Success = false;
+ std::string FailureReason;
+};
+
+ZenCacheEndpointTestResult TestZenCacheEndpoint(std::string_view BaseUrl, const bool AssumeHttp2);
+
} // namespace zen
diff --git a/src/zenutil/include/zenutil/jupiter/jupiterbuildstorage.h b/src/zenutil/include/zenutil/jupiter/jupiterbuildstorage.h
index bbf070993..f25d8933b 100644
--- a/src/zenutil/include/zenutil/jupiter/jupiterbuildstorage.h
+++ b/src/zenutil/include/zenutil/jupiter/jupiterbuildstorage.h
@@ -15,4 +15,11 @@ std::unique_ptr<BuildStorage> CreateJupiterBuildStorage(LoggerRef InLog,
std::string_view Bucket,
bool AllowRedirect,
const std::filesystem::path& TempFolderPath);
+
+bool ParseBuildStorageUrl(std::string_view InUrl,
+ std::string& OutHost,
+ std::string& OutNamespace,
+ std::string& OutBucket,
+ std::string& OutBuildId);
+
} // namespace zen
diff --git a/src/zenutil/include/zenutil/jupiter/jupiterhost.h b/src/zenutil/include/zenutil/jupiter/jupiterhost.h
new file mode 100644
index 000000000..3bbc700b8
--- /dev/null
+++ b/src/zenutil/include/zenutil/jupiter/jupiterhost.h
@@ -0,0 +1,35 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace zen {
+
+struct HttpClientSettings;
+
+struct JupiterServerDiscovery
+{
+ struct EndPoint
+ {
+ std::string Name;
+ std::string BaseUrl;
+ bool AssumeHttp2 = false;
+ };
+ std::vector<EndPoint> ServerEndPoints;
+ std::vector<EndPoint> CacheEndPoints;
+};
+
+JupiterServerDiscovery DiscoverJupiterEndpoints(std::string_view Host, const HttpClientSettings& ClientSettings);
+
+struct JupiterEndpointTestResult
+{
+ bool Success = false;
+ std::string FailureReason;
+};
+
+JupiterEndpointTestResult TestJupiterEndpoint(std::string_view BaseUrl, const bool AssumeHttp2);
+
+} // namespace zen
diff --git a/src/zenutil/jupiter/jupiterbuildstorage.cpp b/src/zenutil/jupiter/jupiterbuildstorage.cpp
index 386a91cb3..6eb3489dc 100644
--- a/src/zenutil/jupiter/jupiterbuildstorage.cpp
+++ b/src/zenutil/jupiter/jupiterbuildstorage.cpp
@@ -14,6 +14,8 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <tsl/robin_map.h>
ZEN_THIRD_PARTY_INCLUDES_END
+#include <regex>
+
namespace zen {
using namespace std::literals;
@@ -511,4 +513,49 @@ CreateJupiterBuildStorage(LoggerRef InLog,
return std::make_unique<JupiterBuildStorage>(InLog, InHttpClient, Stats, Namespace, Bucket, AllowRedirect, TempFolderPath);
}
+bool
+ParseBuildStorageUrl(std::string_view InUrl,
+ std::string& OutHost,
+ std::string& OutNamespace,
+ std::string& OutBucket,
+ std::string& OutBuildId)
+{
+ std::string Url(InUrl);
+ const std::string_view ExtendedApiString = "api/v2/builds/";
+ if (auto ApiString = ToLower(Url).find(ExtendedApiString); ApiString != std::string::npos)
+ {
+ Url.erase(ApiString, ExtendedApiString.length());
+ }
+
+ const std::string ArtifactURLRegExString = R"((http[s]?:\/\/.*?)\/(.*?)\/(.*?)\/(.*))";
+ const std::regex ArtifactURLRegEx(ArtifactURLRegExString, std::regex::ECMAScript | std::regex::icase);
+ std::match_results<std::string_view::const_iterator> MatchResults;
+ std::string_view UrlToParse(Url);
+ if (regex_match(begin(UrlToParse), end(UrlToParse), MatchResults, ArtifactURLRegEx) && MatchResults.size() == 5)
+ {
+ auto GetMatch = [&MatchResults](uint32_t Index) -> std::string_view {
+ ZEN_ASSERT(Index < MatchResults.size());
+
+ const auto& Match = MatchResults[Index];
+
+ return std::string_view(&*Match.first, Match.second - Match.first);
+ };
+
+ const std::string_view Host = GetMatch(1);
+ const std::string_view Namespace = GetMatch(2);
+ const std::string_view Bucket = GetMatch(3);
+ const std::string_view BuildId = GetMatch(4);
+
+ OutHost = Host;
+ OutNamespace = Namespace;
+ OutBucket = Bucket;
+ OutBuildId = BuildId;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
} // namespace zen
diff --git a/src/zenutil/jupiter/jupiterhost.cpp b/src/zenutil/jupiter/jupiterhost.cpp
new file mode 100644
index 000000000..d06229cbf
--- /dev/null
+++ b/src/zenutil/jupiter/jupiterhost.cpp
@@ -0,0 +1,66 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zenutil/jupiter/jupiterhost.h>
+
+#include <zencore/compactbinary.h>
+#include <zencore/fmtutils.h>
+#include <zenhttp/httpclient.h>
+
+namespace zen {
+
+JupiterServerDiscovery
+DiscoverJupiterEndpoints(std::string_view Host, const HttpClientSettings& ClientSettings)
+{
+ JupiterServerDiscovery Result;
+
+ HttpClient DiscoveryHttpClient(Host, ClientSettings);
+ HttpClient::Response ServerInfoResponse = DiscoveryHttpClient.Get("/api/v1/status/servers", HttpClient::Accept(HttpContentType::kJSON));
+ if (!ServerInfoResponse.IsSuccess())
+ {
+ ServerInfoResponse.ThrowError(fmt::format("Failed to get list of servers from discovery url '{}'", Host));
+ }
+ std::string_view JsonResponse = ServerInfoResponse.AsText();
+ CbObject CbPayload = LoadCompactBinaryFromJson(JsonResponse).AsObject();
+ CbArrayView ServerEndpoints = CbPayload["serverEndpoints"].AsArrayView();
+ Result.ServerEndPoints.reserve(ServerEndpoints.Num());
+
+ auto ParseEndPoints = [](CbArrayView ServerEndpoints) -> std::vector<JupiterServerDiscovery::EndPoint> {
+ std::vector<JupiterServerDiscovery::EndPoint> Result;
+
+ Result.reserve(ServerEndpoints.Num());
+ for (CbFieldView ServerEndpointView : ServerEndpoints)
+ {
+ CbObjectView ServerEndPoint = ServerEndpointView.AsObjectView();
+ Result.push_back(JupiterServerDiscovery::EndPoint{.Name = std::string(ServerEndPoint["name"].AsString()),
+ .BaseUrl = std::string(ServerEndPoint["baseUrl"].AsString()),
+ .AssumeHttp2 = ServerEndPoint["baseUrl"].AsBool(false)});
+ }
+ return Result;
+ };
+
+ Result.ServerEndPoints = ParseEndPoints(CbPayload["serverEndpoints"].AsArrayView());
+ Result.CacheEndPoints = ParseEndPoints(CbPayload["cacheEndpoints"].AsArrayView());
+
+ return Result;
+}
+
+JupiterEndpointTestResult
+TestJupiterEndpoint(std::string_view BaseUrl, const bool AssumeHttp2)
+{
+ HttpClientSettings TestClientSettings{.LogCategory = "httpbuildsclient",
+ .ConnectTimeout = std::chrono::milliseconds{1000},
+ .Timeout = std::chrono::milliseconds{2000},
+ .AssumeHttp2 = AssumeHttp2,
+ .AllowResume = true,
+ .RetryCount = 0};
+
+ HttpClient TestHttpClient(BaseUrl, TestClientSettings);
+ HttpClient::Response TestResponse = TestHttpClient.Get("/health/live");
+ if (TestResponse.IsSuccess())
+ {
+ return {.Success = true};
+ }
+ return {.Success = false, .FailureReason = TestResponse.ErrorMessage("")};
+}
+
+} // namespace zen