// Copyright Epic Games, Inc. All Rights Reserved. #include #include #include #include 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 { std::vector 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["assumeHttp2"].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, const bool HttpVerbose) { HttpClientSettings TestClientSettings{.LogCategory = "httpbuildsclient", .ConnectTimeout = std::chrono::milliseconds{2000}, .Timeout = std::chrono::milliseconds{3000}, .AssumeHttp2 = AssumeHttp2, .AllowResume = true, .RetryCount = 1, .Verbose = HttpVerbose}; HttpClient TestHttpClient(BaseUrl, TestClientSettings); HttpClient::Response TestResponse = TestHttpClient.Get("/health/live"); if (TestResponse.IsSuccess()) { LatencyTestResult LatencyResult = MeasureLatency(TestHttpClient, "/health/ready"); if (!LatencyResult.Success) { return {.Success = false, .FailureReason = LatencyResult.FailureReason}; } return {.Success = true, .LatencySeconds = LatencyResult.LatencySeconds}; } return {.Success = false, .FailureReason = TestResponse.ErrorMessage("")}; } } // namespace zen