diff options
| author | zousar <[email protected]> | 2025-09-22 16:38:15 -0600 |
|---|---|---|
| committer | zousar <[email protected]> | 2025-09-22 16:38:15 -0600 |
| commit | 1c591941878e5c5009d51a82ff61986a63bd2e11 (patch) | |
| tree | 3860ab5ebddf1919aab3cca019422fa76cfcdda4 /src/zenutil | |
| parent | Change batch put responses for client reporting (diff) | |
| parent | 5.7.2-pre1 (diff) | |
| download | zen-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.cpp | 18 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/buildstoragecache.h | 9 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/jupiter/jupiterbuildstorage.h | 7 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/jupiter/jupiterhost.h | 35 | ||||
| -rw-r--r-- | src/zenutil/jupiter/jupiterbuildstorage.cpp | 47 | ||||
| -rw-r--r-- | src/zenutil/jupiter/jupiterhost.cpp | 66 |
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 |