diff --git a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp index 6f1109ad7..73a031d88 100644 --- a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp +++ b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp @@ -124,7 +124,7 @@ MetadataApi::PartitionsExtendedResponse MetadataApi::GetPartitions( auto partitions_response = parser::parse_result(http_response.response); - if (!partitions_response.IsSuccessful()) { + if (!partitions_response) { return {{partitions_response.GetError()}, http_response.GetNetworkStatistics()}; } @@ -134,14 +134,14 @@ MetadataApi::PartitionsExtendedResponse MetadataApi::GetPartitions( } MetadataApi::CatalogVersionResponse MetadataApi::GetLatestCatalogVersion( - const client::OlpClient& client, std::int64_t startVersion, + const client::OlpClient& client, std::int64_t start_version, boost::optional billing_tag, const client::CancellationContext& context) { std::multimap header_params; header_params.emplace("Accept", "application/json"); std::multimap query_params; - query_params.emplace("startVersion", std::to_string(startVersion)); + query_params.emplace("startVersion", std::to_string(start_version)); if (billing_tag) { query_params.emplace("billingTag", *billing_tag); } @@ -158,6 +158,34 @@ MetadataApi::CatalogVersionResponse MetadataApi::GetLatestCatalogVersion( return parser::parse_result(api_response.response); } +client::CancellationToken MetadataApi::GetLatestCatalogVersion( + const client::OlpClient& client, int64_t start_version, + boost::optional billing_tag, CatalogVersionCallback callback) { + std::multimap header_params; + header_params.emplace("Accept", "application/json"); + + std::multimap query_params; + query_params.emplace("startVersion", std::to_string(start_version)); + if (billing_tag) { + query_params.emplace("billingTag", *billing_tag); + } + + std::string metadata_uri = "/versions/latest"; + + return client.CallApi( + metadata_uri, "GET", query_params, header_params, {}, nullptr, "", + [callback](client::HttpResponse api_response) { + if (api_response.status != http::HttpStatusCode::OK) { + callback(client::ApiError(api_response.status, + api_response.response.str())); + return; + } + + callback(parser::parse_result( + api_response.response)); + }); +} + MetadataApi::VersionsResponse MetadataApi::ListVersions( const client::OlpClient& client, std::int64_t start_version, std::int64_t end_version, boost::optional billing_tag, diff --git a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h index 8b517a76f..e1e581ec2 100644 --- a/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h +++ b/olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h @@ -27,6 +27,7 @@ #include #include "ExtendedApiResponse.h" #include "generated/model/LayerVersions.h" +#include "olp/dataservice/read/Types.h" #include "olp/dataservice/read/model/Partitions.h" #include "olp/dataservice/read/model/VersionInfos.h" #include "olp/dataservice/read/model/VersionResponse.h" @@ -130,6 +131,26 @@ class MetadataApi { boost::optional billing_tag, const client::CancellationContext& context); + /** + * @brief Retrieves the latest metadata version for the catalog. + * + * @param client Instance of OlpClient used to make REST request. + * @param start_version The catalog version returned from a prior request. + * Save the version from each request so it can used in the startVersion + * parameter of subsequent requests. If the version from a prior request is + * not avaliable, set the parameter to -1. + * @param billing_tag An optional free-form tag which is used for grouping + * billing records together. If supplied, it must be between 4 - 16 + * characters, contain only alpha/numeric ASCII characters [A-Za-z0-9]. + * @param callback The callback which returns a result of the operation. + * + * @return The `CancellationToken` instance. + */ + static client::CancellationToken GetLatestCatalogVersion( + const client::OlpClient& client, int64_t start_version, + boost::optional billing_tag, + read::CatalogVersionCallback callback); + static VersionsResponse ListVersions( const client::OlpClient& client, int64_t start_version, int64_t end_version, boost::optional billing_tag, diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp index f5150ca71..a9cba193e 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp @@ -35,7 +35,64 @@ #include "olp/dataservice/read/VersionsRequest.h" namespace { +constexpr auto kDefaultStartVersion = 0; constexpr auto kLogTag = "CatalogRepository"; + +// The function retrieves the maximum version among cached/online/user-provided +// versions. +// Update the cache, if the retrieved version is greater than the cached one. +olp::dataservice::read::CatalogVersionResponse RetrieveLatestVersion( + const olp::client::HRN& catalog, + const olp::dataservice::read::CatalogVersionRequest& request, + olp::dataservice::read::repository::CatalogCacheRepository& repository, + olp::dataservice::read::CatalogVersionResponse&& version_response) { + auto cached_version = repository.GetVersion(); + auto fetch_option = request.GetFetchOption(); + + // Using `GetStartVersion` to set up a new latest version for CacheOnly + // requests in case of absence of the previous latest version or it's less + // than the new user set version. + if (fetch_option == olp::dataservice::read::FetchOptions::CacheOnly) { + const auto start_version = request.GetStartVersion(); + if (start_version >= kDefaultStartVersion && + (!cached_version || start_version > cached_version->GetVersion())) { + olp::dataservice::read::model::VersionResponse new_response; + new_response.SetVersion(start_version); + version_response = std::move(new_response); + } + } + + if (version_response) { + const auto new_version = version_response.GetResult().GetVersion(); + + // Write or update a version in the cache, updating happens only when the + // new version is greater than cached. + if (!cached_version || cached_version->GetVersion() < new_version) { + repository.PutVersion(version_response.GetResult()); + if (fetch_option == olp::dataservice::read::FetchOptions::CacheOnly) { + OLP_SDK_LOG_DEBUG_F( + kLogTag, "Latest user set version, hrn='%s', version=%" PRId64, + catalog.ToCatalogHRNString().c_str(), new_version); + } else { + OLP_SDK_LOG_DEBUG_F(kLogTag, + "Latest online version, hrn='%s', version=%" PRId64, + catalog.ToCatalogHRNString().c_str(), new_version); + } + } + + return std::move(version_response); + } + + if (cached_version) { + OLP_SDK_LOG_DEBUG_F( + kLogTag, "Latest cached version, hrn='%s', version=%" PRId64, + catalog.ToCatalogHRNString().c_str(), cached_version->GetVersion()); + version_response = std::move(*cached_version); + } + + return std::move(version_response); +} + } // namespace namespace olp { @@ -56,8 +113,8 @@ CatalogResponse CatalogRepository::GetCatalog( const auto fetch_options = request.GetFetchOption(); const auto catalog_str = catalog_.ToCatalogHRNString(); - repository::CatalogCacheRepository repository( - catalog_, settings_.cache, settings_.default_cache_expiration); + CatalogCacheRepository repository(catalog_, settings_.cache, + settings_.default_cache_expiration); if (fetch_options != OnlineOnly && fetch_options != CacheWithUpdate) { auto cached = repository.Get(); @@ -80,7 +137,7 @@ CatalogResponse CatalogRepository::GetCatalog( "config", "v1", static_cast(fetch_options), context); - if (!config_api.IsSuccessful()) { + if (!config_api) { return config_api.GetError(); } @@ -88,10 +145,11 @@ CatalogResponse CatalogRepository::GetCatalog( auto catalog_response = ConfigApi::GetCatalog( config_client, catalog_str, request.GetBillingTag(), context); - if (catalog_response.IsSuccessful() && fetch_options != OnlineOnly) { + if (catalog_response && fetch_options != OnlineOnly) { repository.Put(catalog_response.GetResult()); } - if (!catalog_response.IsSuccessful()) { + + if (!catalog_response) { const auto& error = catalog_response.GetError(); if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) { OLP_SDK_LOG_WARNING_F(kLogTag, @@ -107,12 +165,12 @@ CatalogResponse CatalogRepository::GetCatalog( CatalogVersionResponse CatalogRepository::GetLatestVersion( const CatalogVersionRequest& request, client::CancellationContext context) { - repository::CatalogCacheRepository repository( - catalog_, settings_.cache, settings_.default_cache_expiration); + CatalogCacheRepository repository(catalog_, settings_.cache, + settings_.default_cache_expiration); const auto fetch_option = request.GetFetchOption(); - // in case get version online was never called and version was not found in - // cache + // In case `GetVersionOnline` was never called and version was not found in + // the cache CatalogVersionResponse version_response = { {client::ErrorCode::NotFound, "Failed to find version."}}; @@ -124,7 +182,7 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( return version_response; } - if (!version_response.IsSuccessful()) { + if (!version_response) { const auto& error = version_response.GetError(); if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) { OLP_SDK_LOG_WARNING_F( @@ -143,8 +201,6 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( // requests in case of absence of previous latest version or it less than the // new user set version if (fetch_option == CacheOnly) { - constexpr auto kDefaultStartVersion = 0; - auto user_set_version = request.GetStartVersion(); if (user_set_version >= kDefaultStartVersion) { if (!cached_version || user_set_version > cached_version->GetVersion()) { @@ -155,11 +211,11 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( } } - if (version_response.IsSuccessful()) { + if (version_response) { const auto new_version = version_response.GetResult().GetVersion(); // Write or update the version in cache, updating happens only when the new // version is greater than cached. - if (!cached_version || (*cached_version).GetVersion() < new_version) { + if (!cached_version || cached_version->GetVersion() < new_version) { repository.PutVersion(version_response.GetResult()); if (fetch_option == CacheOnly) { OLP_SDK_LOG_DEBUG_F( @@ -171,25 +227,69 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( catalog_.ToCatalogHRNString().c_str(), new_version); } } + return version_response; } if (cached_version) { OLP_SDK_LOG_DEBUG_F( kLogTag, "Latest cached version, hrn='%s', version=%" PRId64, - catalog_.ToCatalogHRNString().c_str(), (*cached_version).GetVersion()); - version_response = *std::move(cached_version); + catalog_.ToCatalogHRNString().c_str(), cached_version->GetVersion()); + version_response = std::move(*cached_version); } return version_response; } +client::CancellationToken CatalogRepository::GetLatestVersion( + const CatalogVersionRequest& request, CatalogVersionCallback callback) { + CatalogCacheRepository repository(catalog_, settings_.cache, + settings_.default_cache_expiration); + + const auto fetch_option = request.GetFetchOption(); + + if (fetch_option == CacheOnly) { + // Initialize response to an error. It will be overwritten in case a valid + // version is found in the cache or user request. + CatalogVersionResponse version_response{ + {client::ErrorCode::NotFound, "Failed to find a catalog version."}}; + + callback(RetrieveLatestVersion(catalog_, request, repository, + std::move(version_response))); + return client::CancellationToken(); + } + + return GetLatestVersionOnline( + request.GetBillingTag(), [=](CatalogVersionResponse response) mutable { + if (fetch_option == OnlineOnly) { + callback(std::move(response)); + return; + } + + if (!response) { + const auto& error = response.GetError(); + if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) { + OLP_SDK_LOG_WARNING_F( + kLogTag, + "Latest version request ended with 403 HTTP code, hrn='%s'", + catalog_.ToCatalogHRNString().c_str()); + repository.Clear(); + callback(std::move(response)); + return; + } + } + + callback(RetrieveLatestVersion(catalog_, request, repository, + std::move(response))); + }); +} + VersionsResponse CatalogRepository::GetVersionsList( const VersionsRequest& request, client::CancellationContext context) { auto metadata_api = lookup_client_.LookupApi("metadata", "v1", client::OnlineOnly, context); - if (!metadata_api.IsSuccessful()) { + if (!metadata_api) { return metadata_api.GetError(); } @@ -206,7 +306,7 @@ CatalogVersionResponse CatalogRepository::GetLatestVersionOnline( auto metadata_api = lookup_client_.LookupApi( "metadata", "v1", client::OnlineIfNotFound, context); - if (!metadata_api.IsSuccessful()) { + if (!metadata_api) { return metadata_api.GetError(); } @@ -216,13 +316,34 @@ CatalogVersionResponse CatalogRepository::GetLatestVersionOnline( context); } +client::CancellationToken CatalogRepository::GetLatestVersionOnline( + const boost::optional& billing_tag, + CatalogVersionCallback callback) { + return lookup_client_.LookupApi( + "metadata", "v1", client::OnlineIfNotFound, + [=](client::ApiLookupClient::LookupApiResponse response) { + if (!response) { + callback(response.GetError()); + return client::CancellationToken(); + } + + const auto& metadata_client = response.GetResult(); + + return MetadataApi::GetLatestCatalogVersion( + metadata_client, -1, billing_tag, + [=](CatalogVersionResponse catalog_version_response) { + callback(std::move(catalog_version_response)); + }); + }); +} + CompatibleVersionsResponse CatalogRepository::GetCompatibleVersions( const CompatibleVersionsRequest& request, client::CancellationContext context) { auto metadata_api = lookup_client_.LookupApi("metadata", "v1", client::OnlineOnly, context); - if (!metadata_api.IsSuccessful()) { + if (!metadata_api) { return metadata_api.GetError(); } diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h index 1aeb6e88c..8d1924c3e 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 HERE Europe B.V. + * Copyright (C) 2019-2022 HERE Europe B.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,9 @@ class CatalogRepository final { CatalogVersionResponse GetLatestVersion(const CatalogVersionRequest& request, client::CancellationContext context); + client::CancellationToken GetLatestVersion( + const CatalogVersionRequest& request, CatalogVersionCallback callback); + VersionsResponse GetVersionsList(const VersionsRequest& request, client::CancellationContext context); @@ -61,6 +64,10 @@ class CatalogRepository final { const boost::optional& billing_tag, client::CancellationContext context); + client::CancellationToken GetLatestVersionOnline( + const boost::optional& billing_tag, + CatalogVersionCallback callback); + client::HRN catalog_; client::OlpClientSettings settings_; client::ApiLookupClient lookup_client_; diff --git a/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp b/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp index ce004c2ea..00fd69ab4 100644 --- a/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp +++ b/olp-cpp-sdk-dataservice-read/tests/CatalogRepositoryTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 HERE Europe B.V. + * Copyright (C) 2019-2022 HERE Europe B.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,13 @@ #include "repositories/CatalogRepository.h" -#include +#include #include #include #include #include +#include +#include #include "ApiClientLookup.h" #include "olp/dataservice/read/CatalogRequest.h" #include "olp/dataservice/read/CatalogVersionRequest.h" @@ -36,6 +38,8 @@ constexpr auto kResponseLookupMetadata = R"jsonString([{"api":"metadata","version":"v1","baseURL":"https://metadata.data.api.platform.here.com/metadata/v1/catalogs/hereos-internal-test-v2","parameters":{}}])jsonString"; constexpr auto kLatestCatalogVersion = R"(https://metadata.data.api.platform.here.com/metadata/v1/catalogs/hereos-internal-test-v2/versions/latest?startVersion=-1)"; +constexpr auto kLatestCatalogVersionWithBillingTag = + R"(https://metadata.data.api.platform.here.com/metadata/v1/catalogs/hereos-internal-test-v2/versions/latest?billingTag=OlpCppSdkTest&startVersion=-1)"; constexpr auto kResponseLatestCatalogVersion = R"jsonString({"version":4})jsonString"; constexpr auto kUrlConfig = @@ -59,10 +63,12 @@ constexpr auto kHttpResponse = namespace { namespace read = olp::dataservice::read; +namespace client = olp::client; +namespace http = olp::http; namespace model = olp::dataservice::read::model; namespace repository = olp::dataservice::read::repository; -using olp::client::ApiLookupClient; -using ::testing::_; +using client::ApiLookupClient; +using testing::_; const std::string kCatalog = "hrn:here:data::olp-here-test:hereos-internal-test-v2"; @@ -80,7 +86,8 @@ const std::string kLookupUrl = kCatalog + "/apis/" + kMetadataServiceName + "/" + kServiceVersion; const std::string kVersionInfosCacheKey = kCatalog + "::3::4::versionInfos"; -const auto kHrn = olp::client::HRN::FromString(kCatalog); +const auto kHrn = client::HRN::FromString(kCatalog); +constexpr auto kMaxWaitMs = std::chrono::milliseconds(150); class CatalogRepositoryTest : public ::testing::Test { protected: @@ -91,8 +98,7 @@ class CatalogRepositoryTest : public ::testing::Test { settings_.network_request_handler = network_; settings_.cache = cache_; - lookup_client_ = - std::make_shared(kHrn, settings_); + lookup_client_ = std::make_shared(kHrn, settings_); } void TearDown() override { @@ -105,126 +111,245 @@ class CatalogRepositoryTest : public ::testing::Test { std::shared_ptr cache_; std::shared_ptr network_; - olp::client::OlpClientSettings settings_; - std::shared_ptr lookup_client_; + client::OlpClientSettings settings_; + std::shared_ptr lookup_client_; }; TEST_F(CatalogRepositoryTest, GetLatestVersionCacheOnlyFound) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); - - request.WithFetchOption(read::CacheOnly); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); model::VersionResponse cached_version; cached_version.SetVersion(10); EXPECT_CALL(*cache_, Get(kLatestVersionCacheKey, _)) - .Times(1) .WillOnce(testing::Return(cached_version)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); EXPECT_EQ(10, response.GetResult().GetVersion()); } TEST_F(CatalogRepositoryTest, GetLatestVersionCacheOnlyNotFound) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); - request.WithFetchOption(read::CacheOnly); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); + + ON_CALL(*network_, Send(_, _, _, _, _)) + .WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Should not be called with CacheOnly"; + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + const auto response = repository.GetLatestVersion(request, context); + + EXPECT_FALSE(response); + EXPECT_EQ(response.GetError().GetErrorCode(), client::ErrorCode::NotFound); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionCacheOnlyNotFound) { + client::CancellationContext context; - EXPECT_CALL(*cache_, Get(_, _)) - .Times(1) - .WillOnce(testing::Return(boost::any{})); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); + + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called with CacheOnly"; - return olp::http::SendOutcome(olp::http::ErrorCode::UNKNOWN_ERROR); - }); + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); - EXPECT_FALSE(response.IsSuccessful()); - EXPECT_EQ(response.GetError().GetErrorCode(), - olp::client::ErrorCode::NotFound); + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetErrorCode(), client::ErrorCode::NotFound); } TEST_F(CatalogRepositoryTest, GetLatestVersionCacheOnlyRequestWithMinVersion) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); - request.WithFetchOption(olp::dataservice::read::CacheOnly) - .WithStartVersion(kStartVersion); + const auto request = read::CatalogVersionRequest() + .WithFetchOption(olp::dataservice::read::CacheOnly) + .WithStartVersion(kStartVersion); - EXPECT_CALL(*cache_, Get(_, _)) - .Times(1) - .WillOnce(testing::Return(boost::any{})); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); EXPECT_CALL(*cache_, Put(_, _, _, _)).Times(1); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called with CacheOnly"; - return olp::http::SendOutcome(olp::http::ErrorCode::UNKNOWN_ERROR); - }); + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - EXPECT_TRUE(response.IsSuccessful()); + EXPECT_TRUE(response); EXPECT_EQ(response.GetResult().GetVersion(), kStartVersion); } -TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyNotFound) { - olp::client::CancellationContext context; +TEST_F(CatalogRepositoryTest, + AsyncGetLatestVersionCacheOnlyRequestWithMinVersion) { + const auto request = read::CatalogVersionRequest() + .WithFetchOption(olp::dataservice::read::CacheOnly) + .WithStartVersion(kStartVersion); - auto request = read::CatalogVersionRequest(); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); - request.WithFetchOption(read::OnlineOnly); + EXPECT_CALL(*cache_, Put(_, _, _, _)).Times(1); - ON_CALL(*cache_, Get(_, _)) - .WillByDefault([](const std::string&, const olp::cache::Decoder&) { - ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; - return boost::any{}; + ON_CALL(*network_, Send(_, _, _, _, _)) + .WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Should not be called with CacheOnly"; + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + + const auto response = repository.GetLatestVersion( + request, [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); }); + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_TRUE(result); + EXPECT_EQ(result.GetResult().GetVersion(), kStartVersion); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionCacheOnly) { + const auto request = read::CatalogVersionRequest() + .WithFetchOption(olp::dataservice::read::CacheOnly) + .WithStartVersion(-1); + + auto cached_version = read::model::VersionResponse(); + cached_version.SetVersion(1); + EXPECT_CALL(*cache_, Get(kLatestVersionCacheKey, _)) + .WillOnce(testing::Return(cached_version)); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_TRUE(result); + EXPECT_EQ(result.GetResult().GetVersion(), cached_version.GetVersion()); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyNotFound) { + auto request = + read::CatalogVersionRequest().WithFetchOption(read::OnlineOnly); + + ON_CALL(*cache_, Get(_, _)).WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; + return boost::any{}; + })); + EXPECT_CALL(*cache_, Get(testing::Eq(kMetadataCacheKey), _)) .WillOnce(testing::Return(boost::any())); EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .Times(1) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::NOT_FOUND), - "")); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::NOT_FOUND), + "")); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); - EXPECT_FALSE(response.IsSuccessful()); + std::promise promise; + auto future = promise.get_future(); + const auto response = repository.GetLatestVersion( + request, [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetErrorCode(), client::ErrorCode::NotFound); } -TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyFound) { - olp::client::CancellationContext context; +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyForbidden) { + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::OnlineIfNotFound); - auto request = read::CatalogVersionRequest(); + ON_CALL(*cache_, Get(_, _)).WillByDefault(testing::WithoutArgs([]() { + ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; + return boost::any{}; + })); - request.WithFetchOption(read::OnlineOnly); + EXPECT_CALL(*cache_, RemoveKeysWithPrefix(_)); + + EXPECT_CALL(*cache_, Get(testing::Eq(kMetadataCacheKey), _)) + .WillOnce(testing::Return(boost::any())); + + EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::FORBIDDEN), + "")); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + const auto response = repository.GetLatestVersion( + request, [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetHttpStatusCode(), + http::HttpStatusCode::FORBIDDEN); +} + +TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyFound2) { + client::CancellationContext context; + + auto request = + read::CatalogVersionRequest().WithFetchOption(read::OnlineOnly); ON_CALL(*cache_, Get(_, _)) .WillByDefault([](const std::string&, const olp::cache::Decoder&) { @@ -236,156 +361,209 @@ TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyFound) { .WillOnce(testing::Return(boost::any())); EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); EXPECT_CALL(*cache_, Put(testing::Eq(kMetadataCacheKey), _, _, _)).Times(1); EXPECT_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLatestCatalogVersion)); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLatestCatalogVersion)); EXPECT_CALL(*cache_, Put(testing::Eq(kLatestVersionCacheKey), _, _, _)) .Times(0); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); ASSERT_EQ(4, response.GetResult().GetVersion()); } -TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyUserCancelled1) { - olp::client::CancellationContext context; +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyFound) { + const auto request = read::CatalogVersionRequest() + .WithFetchOption(read::OnlineOnly) + .WithBillingTag("OlpCppSdkTest"); + + ON_CALL(*cache_, Get(_, _)) + .WillByDefault([](const std::string&, const olp::cache::Decoder&) { + ADD_FAILURE() << "Cache should not be used in OnlineOnly request"; + return boost::any{}; + }); + + EXPECT_CALL(*cache_, Get(testing::Eq(kMetadataCacheKey), _)) + .WillOnce(testing::Return(boost::any())); + + EXPECT_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); + + EXPECT_CALL(*cache_, Put(testing::Eq(kMetadataCacheKey), _, _, _)).Times(1); + + EXPECT_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersionWithBillingTag), + _, _, _, _)) + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLatestCatalogVersion)); - auto request = read::CatalogVersionRequest(); + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); - std::promise cancelled; + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_TRUE(result); + ASSERT_EQ(result.GetResult().GetVersion(), 4); +} + +TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyUserCancelled1) { + client::CancellationContext context; + + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault([&context](olp::http::NetworkRequest, - olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&context]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called. Previous request was cancelled."; constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetLatestVersionOnlineOnlyUserCancelled2) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); +} + +TEST_F(CatalogRepositoryTest, AsyncGetLatestVersionOnlineOnlyUserCancelled2) { + const auto request = read::CatalogVersionRequest(); + + ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); + + ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) + .WillByDefault(testing::WithoutArgs([]() { + return http::SendOutcome(http::ErrorCode::CANCELLED_ERROR); + })); + + ApiLookupClient lookup_client(kHrn, settings_); + repository::CatalogRepository repository(kHrn, settings_, lookup_client); + + std::promise promise; + auto future = promise.get_future(); + repository.GetLatestVersion(request, + [&](read::CatalogVersionResponse response) { + promise.set_value(std::move(response)); + }); + + ASSERT_EQ(future.wait_for(kMaxWaitMs), std::future_status::ready); + const auto result = future.get(); + + EXPECT_FALSE(result); + EXPECT_EQ(result.GetError().GetErrorCode(), client::ErrorCode::Cancelled); } TEST_F(CatalogRepositoryTest, GetLatestVersionCancelledBeforeExecution) { settings_.retry_settings.timeout = 0; - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called on cancelled operation"; constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); context.CancelOperation(); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetLatestVersionTimeouted) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); + const auto request = read::CatalogVersionRequest(); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kLatestCatalogVersion), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); settings_.retry_settings.timeout = 0; ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::RequestTimeout, + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::RequestTimeout, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyFound) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); request.WithFetchOption(read::OnlineOnly); @@ -401,24 +579,24 @@ TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyFound) { EXPECT_CALL(*cache_, Put(testing::Eq(kConfigCacheKey), _, _, _)).Times(0); ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupConfig)); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseConfig)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); } TEST_F(CatalogRepositoryTest, GetCatalogCacheOnlyFound) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); @@ -428,46 +606,39 @@ TEST_F(CatalogRepositoryTest, GetCatalogCacheOnlyFound) { cached_version.SetHrn(kCatalog); EXPECT_CALL(*cache_, Get(kCatalogCacheKey, _)) - .Times(1) .WillOnce(testing::Return(cached_version)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); EXPECT_EQ(kCatalog, response.GetResult().GetHrn()); } TEST_F(CatalogRepositoryTest, GetCatalogCacheOnlyNotFound) { - olp::client::CancellationContext context; + client::CancellationContext context; - auto request = read::CatalogVersionRequest(); - - request.WithFetchOption(read::CacheOnly); + const auto request = + read::CatalogVersionRequest().WithFetchOption(read::CacheOnly); - EXPECT_CALL(*cache_, Get(_, _)) - .Times(1) - .WillOnce(testing::Return(boost::any{})); + EXPECT_CALL(*cache_, Get(_, _)).WillOnce(testing::Return(boost::any{})); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called with CacheOnly"; - return olp::http::SendOutcome(olp::http::ErrorCode::UNKNOWN_ERROR); - }); + return http::SendOutcome(http::ErrorCode::UNKNOWN_ERROR); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); - auto response = repository.GetLatestVersion(request, context); + const auto response = repository.GetLatestVersion(request, context); - EXPECT_FALSE(response.IsSuccessful()); + EXPECT_FALSE(response); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyNotFound) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); @@ -480,33 +651,29 @@ TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyNotFound) { }); EXPECT_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .Times(1) - .WillOnce(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::NOT_FOUND), - "")); + .WillOnce(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::NOT_FOUND), + "")); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - EXPECT_FALSE(response.IsSuccessful()); + EXPECT_FALSE(response); } TEST_F(CatalogRepositoryTest, GetCatalogCancelledBeforeExecution) { settings_.retry_settings.timeout = 0; - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); ON_CALL(*network_, Send(_, _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called on cancelled operation"; constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); context.CancelOperation(); @@ -514,106 +681,89 @@ TEST_F(CatalogRepositoryTest, GetCatalogCancelledBeforeExecution) { repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyUserCancelled1) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); - std::promise cancelled; - ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault([&context](olp::http::NetworkRequest, - olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&context]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault([](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { ADD_FAILURE() << "Should not be called. Previous request was cancelled."; constexpr auto unused_request_id = 5; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogOnlineOnlyUserCancelled2) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupConfig)); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([&]() { std::thread([&]() { context.CancelOperation(); }).detach(); constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::Cancelled, - response.GetError().GetErrorCode()); + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::Cancelled, response.GetError().GetErrorCode()); } TEST_F(CatalogRepositoryTest, GetCatalogTimeout) { - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::CatalogRequest(); ON_CALL(*network_, Send(IsGetRequest(kUrlLookupConfig), _, _, _, _)) - .WillByDefault(ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupConfig)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupConfig)); ON_CALL(*network_, Send(IsGetRequest(kUrlConfig), _, _, _, _)) - .WillByDefault([&](olp::http::NetworkRequest, olp::http::Network::Payload, - olp::http::Network::Callback, - olp::http::Network::HeaderCallback, - olp::http::Network::DataCallback) { + .WillByDefault(testing::WithoutArgs([]() { constexpr auto unused_request_id = 10; - return olp::http::SendOutcome(unused_request_id); - }); + return http::SendOutcome(unused_request_id); + })); + settings_.retry_settings.timeout = 0; ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetCatalog(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::RequestTimeout, + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::RequestTimeout, response.GetError().GetErrorCode()); } @@ -621,28 +771,26 @@ TEST_F(CatalogRepositoryTest, GetVersionsList) { { SCOPED_TRACE("Get versions list"); - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::VersionsRequest() .WithStartVersion(kStartVersion) .WithEndVersion(kEndVersion); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kUrlVersionsList), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kHttpResponse)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kHttpResponse)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetVersionsList(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); auto result = response.GetResult(); ASSERT_EQ(1u, result.GetVersions().size()); @@ -653,28 +801,26 @@ TEST_F(CatalogRepositoryTest, GetVersionsList) { { SCOPED_TRACE("Get versions list start version -1"); - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::VersionsRequest().WithStartVersion(-1).WithEndVersion( kEndVersion); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kUrlVersionsListStartMinus), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kHttpResponse)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kHttpResponse)); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetVersionsList(request, context); - ASSERT_TRUE(response.IsSuccessful()); + ASSERT_TRUE(response); auto result = response.GetResult(); ASSERT_EQ(1u, result.GetVersions().size()); @@ -685,29 +831,27 @@ TEST_F(CatalogRepositoryTest, GetVersionsList) { { SCOPED_TRACE("Get versions list response forbiden"); - olp::client::CancellationContext context; + client::CancellationContext context; auto request = read::VersionsRequest() .WithStartVersion(kStartVersion) .WithEndVersion(kEndVersion); ON_CALL(*network_, Send(IsGetRequest(kLookupMetadata), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::OK), - kResponseLookupMetadata)); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::OK), + kResponseLookupMetadata)); ON_CALL(*network_, Send(IsGetRequest(kUrlVersionsList), _, _, _, _)) - .WillByDefault( - ReturnHttpResponse(olp::http::NetworkResponse().WithStatus( - olp::http::HttpStatusCode::FORBIDDEN), - "Forbidden")); + .WillByDefault(ReturnHttpResponse( + http::NetworkResponse().WithStatus(http::HttpStatusCode::FORBIDDEN), + "Forbidden")); ApiLookupClient lookup_client(kHrn, settings_); repository::CatalogRepository repository(kHrn, settings_, lookup_client); auto response = repository.GetVersionsList(request, context); - ASSERT_FALSE(response.IsSuccessful()); - EXPECT_EQ(olp::client::ErrorCode::AccessDenied, + ASSERT_FALSE(response); + EXPECT_EQ(client::ErrorCode::AccessDenied, response.GetError().GetErrorCode()); } }