Skip to content

Commit 951ca3e

Browse files
Bohdan Kurylovychdiachenko-mischa
authored andcommitted
Added sync version of LookupApiClient in dataservice-write
Implemented the sync version of ApiClientLookup::LookupApiClient in dataservice-write component in the same way it is done in dataservice-read component. Also, covered this new function with unit tests. Relates to: OLPEDGE-1103 Signed-off-by: Bohdan Kurylovych <[email protected]> Signed-off-by: Diachenko Mykahilo <[email protected]>
1 parent 8108d15 commit 951ca3e

File tree

4 files changed

+452
-0
lines changed

4 files changed

+452
-0
lines changed

olp-cpp-sdk-dataservice-write/src/ApiClientLookup.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "ApiClientLookup.h"
2121

2222
#include <olp/core/client/ApiError.h>
23+
#include <olp/core/client/Condition.h>
2324
#include <olp/core/client/HRN.h>
2425
#include <olp/core/client/OlpClient.h>
26+
#include <olp/core/cache/KeyValueCache.h>
2527
#include <olp/core/logging/Log.h>
2628
#include "generated/PlatformApi.h"
2729
#include "generated/ResourcesApi.h"
@@ -45,6 +47,13 @@ std::string GetDatastoreServerUrl(const std::string& partition) {
4547
? "https://api-lookup." + server_url->second + "/lookup/v1"
4648
: "";
4749
}
50+
51+
std::string CreateKeyForCache(const std::string& hrn,
52+
const std::string& service,
53+
const std::string& service_version) {
54+
return hrn + "::" + service + "::" + service_version + "::api";
55+
}
56+
4857
} // namespace
4958

5059
client::CancellationToken ApiClientLookup::LookupApi(
@@ -126,6 +135,110 @@ client::CancellationToken ApiClientLookup::LookupApiClient(
126135
});
127136
}
128137

138+
ApiClientLookup::ApiClientResponse ApiClientLookup::LookupApiClient(
139+
const client::HRN& catalog,
140+
client::CancellationContext cancellation_context, std::string service,
141+
std::string service_version, client::OlpClientSettings settings) {
142+
auto cache_key =
143+
CreateKeyForCache(catalog.ToCatalogHRNString(), service, service_version);
144+
// first, try to find the corresponding Base URL from cache
145+
auto cache = settings.cache;
146+
if (cache) {
147+
auto url =
148+
cache->Get(cache_key, [](const std::string& value) { return value; });
149+
if (!url.empty()) {
150+
auto base_url = boost::any_cast<std::string>(url);
151+
OLP_SDK_LOG_INFO_F(kLogTag, "LookupApiClient(%s, %s) -> from cache",
152+
service.c_str(), service_version.c_str());
153+
client::OlpClient client;
154+
client.SetSettings(settings);
155+
client.SetBaseUrl(base_url);
156+
return ApiClientResponse{client};
157+
}
158+
}
159+
160+
client::Condition condition;
161+
// when the network operation took too much time we cancel it and exit
162+
// execution, to make sure that network callback will not access dangling
163+
// references we protect them with atomic bool flag.
164+
auto flag = std::make_shared<std::atomic_bool>(true);
165+
166+
ApiClientResponse api_response;
167+
auto api_callback = [&, flag](ApiClientResponse response) {
168+
if (flag->exchange(false)) {
169+
api_response = std::move(response);
170+
condition.Notify();
171+
}
172+
};
173+
174+
cancellation_context.ExecuteOrCancelled(
175+
[&, flag]() {
176+
auto client_ptr = std::make_shared<olp::client::OlpClient>();
177+
client_ptr->SetSettings(settings);
178+
179+
auto token = ApiClientLookup::LookupApiClient(
180+
client_ptr, service, service_version, catalog, api_callback);
181+
return client::CancellationToken([&, token, flag]() {
182+
if (flag->exchange(false)) {
183+
token.Cancel();
184+
condition.Notify();
185+
}
186+
});
187+
},
188+
[&]() {
189+
// if context was cancelled before the execution setup, unblock the
190+
// upcoming wait routine.
191+
condition.Notify();
192+
});
193+
if (!condition.Wait(std::chrono::seconds(settings.retry_settings.timeout))) {
194+
cancellation_context.CancelOperation();
195+
OLP_SDK_LOG_INFO_F(kLogTag, "LookupApi(%s/%s): %s - timeout",
196+
service.c_str(), service_version.c_str(),
197+
catalog.partition.c_str());
198+
return client::ApiError(client::ErrorCode::RequestTimeout,
199+
"Network request timed out.");
200+
}
201+
202+
flag->store(false);
203+
204+
if (cancellation_context.IsCancelled()) {
205+
// We can't use api response here because it could potentially be
206+
// uninitialized.
207+
OLP_SDK_LOG_INFO_F(kLogTag, "LookupApi(%s/%s): %s - cancelled",
208+
service.c_str(), service_version.c_str(),
209+
catalog.partition.c_str());
210+
return client::ApiError(client::ErrorCode::Cancelled,
211+
"Operation cancelled.");
212+
}
213+
214+
if (!api_response.IsSuccessful()) {
215+
return api_response.GetError();
216+
}
217+
218+
auto client = api_response.GetResult();
219+
if (client.GetBaseUrl().empty()) {
220+
OLP_SDK_LOG_WARNING_F(kLogTag, "LookupApi(%s/%s): %s - empty base URL",
221+
service.c_str(), service_version.c_str(),
222+
catalog.partition.c_str());
223+
}
224+
225+
if (cache) {
226+
const auto& base_url = client.GetBaseUrl();
227+
228+
constexpr time_t kExpiryTimeInSecs = 3600;
229+
if (cache->Put(cache_key, base_url, [base_url]() { return base_url; },
230+
kExpiryTimeInSecs)) {
231+
OLP_SDK_LOG_TRACE_F(kLogTag, "Put '%s' to cache", cache_key.c_str());
232+
} else {
233+
OLP_SDK_LOG_WARNING_F(kLogTag, "Failed to put '%s' to cache",
234+
cache_key.c_str());
235+
}
236+
}
237+
238+
client.SetSettings(settings);
239+
return ApiClientResponse{std::move(client)};
240+
}
241+
129242
} // namespace write
130243
} // namespace dataservice
131244
} // namespace olp

olp-cpp-sdk-dataservice-write/src/ApiClientLookup.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class ApiClientLookup {
5151
std::shared_ptr<client::OlpClient> client, const std::string& service,
5252
const std::string& service_version, const client::HRN& hrn,
5353
const ApiClientCallback& callback);
54+
55+
static ApiClientResponse LookupApiClient(
56+
const client::HRN& catalog,
57+
client::CancellationContext cancellation_context, std::string service,
58+
std::string service_version, client::OlpClientSettings settings);
5459
};
5560

5661
} // namespace write

0 commit comments

Comments
 (0)