Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add asynchronous methods for GetLatestVersion functionality #1306

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ MetadataApi::PartitionsExtendedResponse MetadataApi::GetPartitions(
auto partitions_response =
parser::parse_result<PartitionsResponse>(http_response.response);

if (!partitions_response.IsSuccessful()) {
if (!partitions_response) {
return {{partitions_response.GetError()},
http_response.GetNetworkStatistics()};
}
Expand All @@ -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<std::string> billing_tag,
const client::CancellationContext& context) {
std::multimap<std::string, std::string> header_params;
header_params.emplace("Accept", "application/json");

std::multimap<std::string, std::string> 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);
}
Expand All @@ -158,6 +158,34 @@ MetadataApi::CatalogVersionResponse MetadataApi::GetLatestCatalogVersion(
return parser::parse_result<CatalogVersionResponse>(api_response.response);
}

client::CancellationToken MetadataApi::GetLatestCatalogVersion(
const client::OlpClient& client, int64_t start_version,
boost::optional<std::string> billing_tag, CatalogVersionCallback callback) {
std::multimap<std::string, std::string> header_params;
header_params.emplace("Accept", "application/json");

std::multimap<std::string, std::string> 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;
}
dudnyk marked this conversation as resolved.
Show resolved Hide resolved

callback(parser::parse_result<CatalogVersionResponse>(
api_response.response));
});
}

MetadataApi::VersionsResponse MetadataApi::ListVersions(
const client::OlpClient& client, std::int64_t start_version,
std::int64_t end_version, boost::optional<std::string> billing_tag,
Expand Down
21 changes: 21 additions & 0 deletions olp-cpp-sdk-dataservice-read/src/generated/api/MetadataApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <boost/optional.hpp>
#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"
Expand Down Expand Up @@ -130,6 +131,26 @@ class MetadataApi {
boost::optional<std::string> 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(
dudnyk marked this conversation as resolved.
Show resolved Hide resolved
const client::OlpClient& client, int64_t start_version,
boost::optional<std::string> billing_tag,
read::CatalogVersionCallback callback);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
read::CatalogVersionCallback callback);
CatalogVersionCallback callback);


static VersionsResponse ListVersions(
const client::OlpClient& client, int64_t start_version,
int64_t end_version, boost::optional<std::string> billing_tag,
Expand Down
159 changes: 140 additions & 19 deletions olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
dudnyk marked this conversation as resolved.
Show resolved Hide resolved
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pessimizing-move
More info: https://stackoverflow.com/questions/62061433/how-to-avoid-the-pessimizing-move-warning-of-nrvo

Suggested change
return std::move(version_response);
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);
}

return std::move(version_response);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pessimizing-move
More info: https://stackoverflow.com/questions/62061433/how-to-avoid-the-pessimizing-move-warning-of-nrvo

Suggested change
return std::move(version_response);
return version_response;

}

} // namespace

namespace olp {
Expand All @@ -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();
Expand All @@ -80,18 +137,19 @@ CatalogResponse CatalogRepository::GetCatalog(
"config", "v1", static_cast<client::FetchOptions>(fetch_options),
context);

if (!config_api.IsSuccessful()) {
if (!config_api) {
return config_api.GetError();
}

const client::OlpClient& config_client = config_api.GetResult();
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) {
dudnyk marked this conversation as resolved.
Show resolved Hide resolved
const auto& error = catalog_response.GetError();
if (error.GetHttpStatusCode() == http::HttpStatusCode::FORBIDDEN) {
OLP_SDK_LOG_WARNING_F(kLogTag,
Expand All @@ -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
dudnyk marked this conversation as resolved.
Show resolved Hide resolved
// the cache
CatalogVersionResponse version_response = {
{client::ErrorCode::NotFound, "Failed to find version."}};

Expand All @@ -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(
Expand All @@ -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()) {
Expand All @@ -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(
Expand All @@ -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();
}

Expand All @@ -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();
}

Expand All @@ -216,13 +316,34 @@ CatalogVersionResponse CatalogRepository::GetLatestVersionOnline(
context);
}

client::CancellationToken CatalogRepository::GetLatestVersionOnline(
const boost::optional<std::string>& 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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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);

Expand All @@ -61,6 +64,10 @@ class CatalogRepository final {
const boost::optional<std::string>& billing_tag,
client::CancellationContext context);

client::CancellationToken GetLatestVersionOnline(
const boost::optional<std::string>& billing_tag,
CatalogVersionCallback callback);

client::HRN catalog_;
client::OlpClientSettings settings_;
client::ApiLookupClient lookup_client_;
Expand Down
Loading