diff --git a/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/CatalogClient.h b/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/CatalogClient.h index 7a282d5ca..d6d498551 100644 --- a/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/CatalogClient.h +++ b/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/CatalogClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -31,6 +31,7 @@ #include #include #include +#include namespace olp { @@ -137,6 +138,32 @@ class DATASERVICE_READ_API CatalogClient final { client::CancellableFuture GetLatestVersion( CatalogVersionRequest request); + /** + * @brief Gets the catalog versions list. + * + * @param request The `VersionsRequest` instance that contains + * a complete set of request parameters. + * @param callback The `VersionsResponseCallback` object that is invoked if + * the list of versions is available or an error is encountered. + * + * @return A token that can be used to cancel this request. + */ + client::CancellationToken ListVersions(VersionsRequest request, + VersionsResponseCallback callback); + + /** + * @brief Gets the catalog versions list. + * + * @param request The `VersionsRequest` instance that contains + * a complete set of request parameters. + * + * @return CancellableFuture` that contains the `VersionsResponse` + * instance with the list of versions or an error. You can also + * use `CancellableFuture` to cancel this request. + */ + client::CancellableFuture ListVersions( + VersionsRequest request); + private: std::unique_ptr impl_; }; diff --git a/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/VersionsRequest.h b/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/VersionsRequest.h index ac2058686..78acc208a 100644 --- a/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/VersionsRequest.h +++ b/olp-cpp-sdk-dataservice-read/include/olp/dataservice/read/VersionsRequest.h @@ -164,13 +164,11 @@ class DATASERVICE_READ_API VersionsRequest final { /** * @brief Creates a readable format for the request. * - * @param layer_id The ID of the layer that is used for the request. - * * @return A string representation of the request. */ - inline std::string CreateKey(const std::string& layer_id) const { + inline std::string CreateKey() const { std::stringstream out; - out << layer_id << "["; + out << "["; out << GetStartVersion() << ", " << GetEndVersion(); out << "]"; if (GetBillingTag()) { diff --git a/olp-cpp-sdk-dataservice-read/src/CatalogClient.cpp b/olp-cpp-sdk-dataservice-read/src/CatalogClient.cpp index a26c456da..8abf1e775 100644 --- a/olp-cpp-sdk-dataservice-read/src/CatalogClient.cpp +++ b/olp-cpp-sdk-dataservice-read/src/CatalogClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -61,6 +61,16 @@ client::CancellableFuture CatalogClient::GetLatestVersion(CatalogVersionRequest request) { return impl_->GetLatestVersion(std::move(request)); } + +client::CancellationToken CatalogClient::ListVersions( + VersionsRequest request, VersionsResponseCallback callback) { + return impl_->ListVersions(std::move(request), std::move(callback)); +} + +client::CancellableFuture CatalogClient::ListVersions( + VersionsRequest request) { + return impl_->ListVersions(std::move(request)); +} } // namespace read } // namespace dataservice } // namespace olp diff --git a/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.cpp b/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.cpp index 56982d098..6aee07333 100644 --- a/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.cpp +++ b/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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,6 +19,8 @@ #include "CatalogClientImpl.h" +#include + #include #include #include @@ -31,14 +33,13 @@ namespace olp { namespace dataservice { namespace read { -using namespace repository; -using namespace olp::client; namespace { constexpr auto kLogTag = "CatalogClientImpl"; } -CatalogClientImpl::CatalogClientImpl(HRN catalog, OlpClientSettings settings) +CatalogClientImpl::CatalogClientImpl(client::HRN catalog, + client::OlpClientSettings settings) : catalog_(std::move(catalog)), settings_(std::move(settings)) { if (!settings_.cache) { settings_.cache = client::OlpClientSettingsFactory::CreateDefaultCache({}); @@ -60,7 +61,7 @@ bool CatalogClientImpl::CancelPendingRequests() { return pending_requests_->CancelAll(); } -CancellationToken CatalogClientImpl::GetCatalog( +client::CancellationToken CatalogClientImpl::GetCatalog( CatalogRequest request, CatalogResponseCallback callback) { auto schedule_get_catalog = [&](CatalogRequest request, CatalogResponseCallback callback) { @@ -81,7 +82,7 @@ CancellationToken CatalogClientImpl::GetCatalog( std::move(callback)); } -CancellableFuture CatalogClientImpl::GetCatalog( +client::CancellableFuture CatalogClientImpl::GetCatalog( CatalogRequest request) { auto promise = std::make_shared>(); auto cancel_token = @@ -92,7 +93,7 @@ CancellableFuture CatalogClientImpl::GetCatalog( std::move(promise)); } -CancellationToken CatalogClientImpl::GetLatestVersion( +client::CancellationToken CatalogClientImpl::GetLatestVersion( CatalogVersionRequest request, CatalogVersionCallback callback) { OLP_SDK_LOG_TRACE_F(kLogTag, "GetCatalog '%s'", request.CreateKey().c_str()); auto schedule_get_latest_version = [&](CatalogVersionRequest request, @@ -114,8 +115,8 @@ CancellationToken CatalogClientImpl::GetLatestVersion( std::move(request), std::move(callback)); } -CancellableFuture CatalogClientImpl::GetLatestVersion( - CatalogVersionRequest request) { +client::CancellableFuture +CatalogClientImpl::GetLatestVersion(CatalogVersionRequest request) { auto promise = std::make_shared>(); auto cancel_token = GetLatestVersion( std::move(request), [promise](CatalogVersionResponse response) { @@ -124,6 +125,48 @@ CancellableFuture CatalogClientImpl::GetLatestVersion( return client::CancellableFuture( std::move(cancel_token), std::move(promise)); } + +client::CancellationToken CatalogClientImpl::ListVersions( + VersionsRequest request, VersionsResponseCallback callback) { + if (request.GetFetchOption() == CacheWithUpdate) { + auto task = [](client::CancellationContext) -> VersionsResponse { + return {{client::ErrorCode::InvalidArgument, + "CacheWithUpdate option can not be used for versioned catalog"}}; + }; + return AddTask(settings_.task_scheduler, pending_requests_, std::move(task), + std::move(callback)); + } + + auto schedule_get_versions_list = [&](VersionsRequest request, + VersionsResponseCallback callback) { + auto catalog = catalog_; + auto settings = settings_; + auto pending_requests = pending_requests_; + + auto versions_list_task = + [=](client::CancellationContext context) -> VersionsResponse { + return repository::CatalogRepository::GetVersionsList( + std::move(catalog), context, std::move(request), std::move(settings)); + }; + + return AddTask(settings.task_scheduler, pending_requests, + std::move(versions_list_task), std::move(callback)); + }; + + return ScheduleFetch(std::move(schedule_get_versions_list), + std::move(request), std::move(callback)); +} + +client::CancellableFuture CatalogClientImpl::ListVersions( + VersionsRequest request) { + auto promise = std::make_shared>(); + auto cancel_token = + ListVersions(std::move(request), [promise](VersionsResponse response) { + promise->set_value(std::move(response)); + }); + return client::CancellableFuture(std::move(cancel_token), + std::move(promise)); +} } // namespace read } // namespace dataservice } // namespace olp diff --git a/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.h b/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.h index df99a044c..cf6f22e41 100644 --- a/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.h +++ b/olp-cpp-sdk-dataservice-read/src/CatalogClientImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -28,6 +28,7 @@ #include #include #include +#include namespace olp { namespace client { @@ -61,6 +62,12 @@ class CatalogClientImpl final { client::CancellableFuture GetLatestVersion( CatalogVersionRequest request); + client::CancellationToken ListVersions(VersionsRequest request, + VersionsResponseCallback callback); + + client::CancellableFuture ListVersions( + VersionsRequest request); + private: client::HRN catalog_; client::OlpClientSettings settings_; diff --git a/olp-cpp-sdk-dataservice-read/src/generated/serializer/VersionInfosSerializer.cpp b/olp-cpp-sdk-dataservice-read/src/generated/serializer/VersionInfosSerializer.cpp new file mode 100644 index 000000000..6da55e72d --- /dev/null +++ b/olp-cpp-sdk-dataservice-read/src/generated/serializer/VersionInfosSerializer.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +#include + +#include "VersionInfosSerializer.h" + +#include + +namespace olp { +namespace serializer { + +void to_json(const dataservice::read::model::VersionDependency& x, + rapidjson::Value& value, + rapidjson::Document::AllocatorType& allocator) { + value.SetObject(); + serialize("hrn", x.GetHrn(), value, allocator); + serialize("version", x.GetVersion(), value, allocator); + serialize("direct", x.GetDirect(), value, allocator); +} + +void to_json(const dataservice::read::model::VersionInfo& x, + rapidjson::Value& value, + rapidjson::Document::AllocatorType& allocator) { + value.SetObject(); + serialize("dependencies", x.GetDependencies(), value, allocator); + serialize("timestamp", x.GetTimestamp(), value, allocator); + serialize("version", x.GetVersion(), value, allocator); + serialize("partitionCounts", x.GetPartitionCounts(), value, allocator); +} + +void to_json(const dataservice::read::model::VersionInfos& x, + rapidjson::Value& value, + rapidjson::Document::AllocatorType& allocator) { + value.SetObject(); + serialize("versions", x.GetVersions(), value, allocator); +} +} // namespace serializer +} // namespace olp diff --git a/olp-cpp-sdk-dataservice-read/src/generated/serializer/VersionInfosSerializer.h b/olp-cpp-sdk-dataservice-read/src/generated/serializer/VersionInfosSerializer.h new file mode 100644 index 000000000..c57e9c339 --- /dev/null +++ b/olp-cpp-sdk-dataservice-read/src/generated/serializer/VersionInfosSerializer.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +#pragma once + +#include + +#include "olp/dataservice/read/model/VersionInfos.h" + +namespace olp { +namespace serializer { + +void to_json(const dataservice::read::model::VersionDependency& x, + rapidjson::Value& value, + rapidjson::Document::AllocatorType& allocator); + +void to_json(const dataservice::read::model::VersionInfo& x, + rapidjson::Value& value, + rapidjson::Document::AllocatorType& allocator); + +void to_json(const dataservice::read::model::VersionInfos& x, + rapidjson::Value& value, + rapidjson::Document::AllocatorType& allocator); +} // namespace serializer +} // namespace olp diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.cpp b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.cpp index c5ad00725..16ee6f467 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.cpp +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -26,10 +26,12 @@ // clang-format off #include "generated/parser/CatalogParser.h" +#include "generated/parser/VersionInfosParser.h" #include "generated/parser/VersionResponseParser.h" #include #include "generated/serializer/CatalogSerializer.h" #include "generated/serializer/VersionResponseSerializer.h" +#include "generated/serializer/VersionInfosSerializer.h" #include "generated/serializer/JsonSerializer.h" // clang-format on @@ -46,6 +48,11 @@ std::string CreateKey(const std::string& hrn) { return hrn + "::catalog"; } std::string VersionKey(const std::string& hrn) { return hrn + "::latestVersion"; } +std::string VersionInfosKey(const std::string& hrn, std::int16_t start, + std::int16_t end) { + return hrn + "::" + std::to_string(start) + "::" + std::to_string(end) + + "::versionInfos"; +} time_t ConvertTime(std::chrono::seconds time) { return time == kChronoSecondsMax ? kTimetMax : time.count(); @@ -111,6 +118,31 @@ boost::optional CatalogCacheRepository::GetVersion() { return boost::any_cast(cached_version); } +void CatalogCacheRepository::PutVersionInfos( + std::int64_t start, std::int64_t end, const model::VersionInfos& versions) { + std::string hrn(hrn_.ToCatalogHRNString()); + OLP_SDK_LOG_DEBUG_F(kLogTag, "PutVersionInfos -> '%s'", hrn.c_str()); + + cache_->Put(VersionInfosKey(hrn, start, end), versions, + [&]() { return olp::serializer::serialize(versions); }, + kCatalogVersionExpiryTime); +} +boost::optional CatalogCacheRepository::GetVersionInfos( + std::int64_t start, std::int64_t end) { + std::string hrn(hrn_.ToCatalogHRNString()); + auto key = VersionInfosKey(hrn, start, end); + OLP_SDK_LOG_DEBUG_F(kLogTag, "GetVersionInfos -> '%s'", key.c_str()); + + auto cached_versions = cache_->Get(key, [](const std::string& value) { + return parser::parse(value); + }); + + if (cached_versions.empty()) { + return boost::none; + } + return boost::any_cast(cached_versions); +} + void CatalogCacheRepository::Clear() { std::string hrn(hrn_.ToCatalogHRNString()); OLP_SDK_LOG_INFO_F(kLogTag, "Clear -> '%s'", CreateKey(hrn).c_str()); diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.h b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.h index 6352ba5de..b5128cd2e 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.h +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogCacheRepository.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -51,6 +52,12 @@ class CatalogCacheRepository final { boost::optional GetVersion(); + void PutVersionInfos(std::int64_t start, std::int64_t end, + const model::VersionInfos& versions); + + boost::optional GetVersionInfos(std::int64_t start, + std::int64_t end); + void Clear(); private: diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp index 09428bd78..6aed5be31 100644 --- a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp +++ b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -33,6 +33,7 @@ #include "generated/api/MetadataApi.h" #include "olp/dataservice/read/CatalogRequest.h" #include "olp/dataservice/read/CatalogVersionRequest.h" +#include "olp/dataservice/read/VersionsRequest.h" namespace { constexpr auto kLogTag = "CatalogRepository"; @@ -152,6 +153,51 @@ CatalogVersionResponse CatalogRepository::GetLatestVersion( return version_response; } +VersionsResponse CatalogRepository::GetVersionsList( + client::HRN catalog, client::CancellationContext cancellation_context, + VersionsRequest request, client::OlpClientSettings settings) { + auto fetch_option = request.GetFetchOption(); + repository::CatalogCacheRepository repository(catalog, settings.cache); + + if (fetch_option != OnlineOnly && fetch_option != CacheWithUpdate) { + auto cached_version = repository.GetVersionInfos(request.GetStartVersion(), + request.GetEndVersion()); + if (cached_version) { + OLP_SDK_LOG_DEBUG_F( + kLogTag, "GetVersionsList found in cache, hrn='%s', key='%s'", + catalog.ToCatalogHRNString().c_str(), request.CreateKey().c_str()); + return cached_version.value(); + } else if (fetch_option == CacheOnly) { + OLP_SDK_LOG_INFO_F( + kLogTag, "GetVersionsList not found in cache, hrn='%s', key='%s'", + catalog.ToCatalogHRNString().c_str(), request.CreateKey().c_str()); + return {{client::ErrorCode::NotFound, + "CacheOnly: resource not found in cache"}}; + } + } + + auto metadata_api = ApiClientLookup::LookupApi( + std::move(catalog), cancellation_context, "metadata", "v1", fetch_option, + std::move(settings)); + + if (!metadata_api.IsSuccessful()) { + return metadata_api.GetError(); + } + + const client::OlpClient& client = metadata_api.GetResult(); + + auto response = MetadataApi::ListVersions( + client, request.GetStartVersion(), request.GetEndVersion(), + request.GetBillingTag(), cancellation_context); + + if (response.IsSuccessful() && fetch_option != OnlineOnly) { + repository.PutVersionInfos(request.GetStartVersion(), + request.GetEndVersion(), response.GetResult()); + } + + return response; +} + } // namespace repository } // namespace read } // namespace dataservice diff --git a/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h b/olp-cpp-sdk-dataservice-read/src/repositories/CatalogRepository.h index f3b9a424e..cd188c02b 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 HERE Europe B.V. + * Copyright (C) 2019-2020 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. @@ -32,6 +32,7 @@ namespace read { class CatalogRequest; class CatalogVersionRequest; +class VersionsRequest; namespace repository { @@ -45,6 +46,10 @@ class CatalogRepository final { static CatalogVersionResponse GetLatestVersion( client::HRN catalog, client::CancellationContext cancellation_context, CatalogVersionRequest request, client::OlpClientSettings settings); + + static VersionsResponse GetVersionsList( + client::HRN catalog, client::CancellationContext cancellation_context, + VersionsRequest request, client::OlpClientSettings settings); }; } // namespace repository