2121#include < olp/authentication/AuthenticationCredentials.h>
2222#include < olp/authentication/Settings.h>
2323#include < olp/authentication/TokenProvider.h>
24+ #include < olp/core/cache/CacheSettings.h>
25+ #include < olp/core/cache/KeyValueCache.h>
2426#include < olp/core/client/OlpClientSettings.h>
2527#include < olp/core/client/OlpClientSettingsFactory.h>
2628#include < olp/core/http/NetworkSettings.h>
2729#include < olp/core/logging/Log.h>
2830#include < olp/core/porting/make_unique.h>
31+ #include < olp/dataservice/read/FetchOptions.h>
2932#include < olp/dataservice/read/VersionedLayerClient.h>
3033#include < string>
3134#include < testutils/CustomParameters.hpp>
@@ -49,6 +52,94 @@ const auto kPartitionsResponsePath =
4952 " /metadata/v1/catalogs/hrn:here:data::olp-here-test:hereos-internal-test/"
5053 " layers/testlayer/partitions" ;
5154
55+ void WriteSubquadsToJson (rapidjson::Document& doc,
56+ const olp::geo::TileKey& root_tile,
57+ const std::vector<std::uint16_t >& sub_quads,
58+ rapidjson::Document::AllocatorType& allocator) {
59+ rapidjson::Value sub_quads_value;
60+ sub_quads_value.SetArray ();
61+ for (auto quad : sub_quads) {
62+ const auto partition = root_tile.AddedSubkey64 (quad).ToHereTile ();
63+ const auto data_handle =
64+ mockserver::DefaultResponses::GenerateDataHandle (partition);
65+
66+ rapidjson::Value item_value;
67+ item_value.SetObject ();
68+ olp::serializer::serialize (" subQuadKey" , std::to_string (quad), item_value,
69+ allocator);
70+ olp::serializer::serialize (" version" , 0 , item_value, allocator);
71+ olp::serializer::serialize (" dataHandle" , data_handle, item_value,
72+ allocator);
73+ olp::serializer::serialize (" dataSize" , 100 , item_value, allocator);
74+ sub_quads_value.PushBack (std::move (item_value), allocator);
75+ }
76+ doc.AddMember (" subQuads" , std::move (sub_quads_value), allocator);
77+ }
78+
79+ void WriteParentquadsToJson (rapidjson::Document& doc,
80+ const std::vector<std::uint64_t >& parent_quads,
81+ rapidjson::Document::AllocatorType& allocator) {
82+ rapidjson::Value parent_quads_value;
83+ parent_quads_value.SetArray ();
84+ for (auto parent : parent_quads) {
85+ const auto partition = std::to_string (parent);
86+ const auto data_handle =
87+ mockserver::DefaultResponses::GenerateDataHandle (partition);
88+
89+ rapidjson::Value item_value;
90+ item_value.SetObject ();
91+ olp::serializer::serialize (" partition" , std::to_string (parent), item_value,
92+ allocator);
93+ olp::serializer::serialize (" version" , 0 , item_value, allocator);
94+ olp::serializer::serialize (" dataHandle" , data_handle, item_value,
95+ allocator);
96+ olp::serializer::serialize (" dataSize" , 100 , item_value, allocator);
97+ parent_quads_value.PushBack (std::move (item_value), allocator);
98+ }
99+ doc.AddMember (" parentQuads" , std::move (parent_quads_value), allocator);
100+ }
101+
102+ std::string GenerateQuadTreeResponse (
103+ olp::geo::TileKey root_tile, std::uint32_t depth,
104+ const std::vector<std::uint32_t >& available_levels) {
105+ std::vector<std::uint16_t > sub_quads;
106+ std::vector<std::uint64_t > parent_quads;
107+
108+ // generate data
109+ for (auto level : available_levels) {
110+ if (level < root_tile.Level ()) {
111+ auto key = root_tile.ChangedLevelTo (level);
112+ parent_quads.push_back (key.ToQuadKey64 ());
113+ } else {
114+ const auto level_depth = level - root_tile.Level ();
115+ if (level_depth > depth) {
116+ continue ;
117+ }
118+
119+ const auto sub_tile =
120+ olp::geo::TileKey::FromRowColumnLevel (0 , 0 , level_depth);
121+ const auto start_level_id = sub_tile.ToQuadKey64 ();
122+ const auto tiles_count =
123+ olp::geo::QuadKey64Helper::ChildrenAtLevel (level_depth);
124+
125+ std::vector<std::uint64_t > layer_ids (tiles_count);
126+ std::iota (layer_ids.begin (), layer_ids.end (), start_level_id);
127+ sub_quads.insert (sub_quads.end (), layer_ids.begin (), layer_ids.end ());
128+ }
129+ }
130+
131+ rapidjson::Document doc;
132+ auto & allocator = doc.GetAllocator ();
133+ doc.SetObject ();
134+ WriteSubquadsToJson (doc, root_tile, sub_quads, allocator);
135+ WriteParentquadsToJson (doc, parent_quads, allocator);
136+
137+ rapidjson::StringBuffer buffer;
138+ rapidjson::Writer<rapidjson::StringBuffer> writer (buffer);
139+ doc.Accept (writer);
140+ return buffer.GetString ();
141+ }
142+
52143class VersionedLayerClientTest : public ::testing::Test {
53144 protected:
54145 void SetUp () override {
@@ -125,4 +216,184 @@ TEST_F(VersionedLayerClientTest, GetPartitions) {
125216 EXPECT_TRUE (mock_server_client_->Verify ());
126217}
127218
219+ TEST_F (VersionedLayerClientTest, GetAggregatedData) {
220+ olp::client::HRN hrn (kTestHrn );
221+
222+ constexpr auto kTileId = " 5901734" ;
223+ constexpr auto kLayer = " testlayer" ;
224+ constexpr auto kQuadTreeDepth = 4 ;
225+ constexpr auto kVersion = 44 ;
226+
227+ const auto root_tile = olp::geo::TileKey::FromHereTile (kTileId );
228+ const auto tile = root_tile.ChangedLevelTo (15 );
229+ const auto request = olp::dataservice::read::TileRequest ().WithTileKey (tile);
230+
231+ // authentification not needed for the test
232+ settings_->authentication_settings = boost::none;
233+
234+ {
235+ SCOPED_TRACE (" Requested tile" );
236+ const auto data_handle =
237+ mockserver::DefaultResponses::GenerateDataHandle (tile.ToHereTile ());
238+ const auto data = mockserver::DefaultResponses::GenerateData ();
239+
240+ {
241+ mock_server_client_->MockLookupResourceApiResponse (
242+ mockserver::DefaultResponses::GenerateResourceApisResponse (kTestHrn ));
243+ mock_server_client_->MockGetVersionResponse (
244+ mockserver::DefaultResponses::GenerateVersionResponse (kVersion ));
245+ mock_server_client_->MockGetResponse (
246+ kLayer , root_tile, kVersion ,
247+ GenerateQuadTreeResponse (root_tile, kQuadTreeDepth ,
248+ {1 , 3 , 12 , 13 , 14 , 15 }));
249+ mock_server_client_->MockGetResponse (kLayer , data_handle, data);
250+ }
251+
252+ auto client =
253+ std::make_unique<olp::dataservice::read::VersionedLayerClient>(
254+ hrn, kLayer , boost::none, *settings_);
255+
256+ auto future = client->GetAggregatedData (request).GetFuture ();
257+ auto response = future.get ();
258+ const auto result = response.MoveResult ();
259+ const auto & result_data = result.GetData ();
260+
261+ ASSERT_TRUE (response.IsSuccessful ())
262+ << response.GetError ().GetMessage ().c_str ();
263+ ASSERT_TRUE (result_data);
264+ ASSERT_EQ (result_data->size (), data.size ());
265+ EXPECT_TRUE (std::equal (data.begin (), data.end (), result_data->begin ()));
266+ EXPECT_EQ (result.GetTile (), tile);
267+ EXPECT_TRUE (mock_server_client_->Verify ());
268+ }
269+
270+ {
271+ SCOPED_TRACE (" Ancestor tile" );
272+ const auto expect_tile = tile.ChangedLevelTo (14 );
273+ const auto data_handle = mockserver::DefaultResponses::GenerateDataHandle (
274+ expect_tile.ToHereTile ());
275+ const auto data = mockserver::DefaultResponses::GenerateData ();
276+
277+ {
278+ SetUpMockServer (settings_->network_request_handler );
279+ mock_server_client_->MockLookupResourceApiResponse (
280+ mockserver::DefaultResponses::GenerateResourceApisResponse (kTestHrn ));
281+ mock_server_client_->MockGetVersionResponse (
282+ mockserver::DefaultResponses::GenerateVersionResponse (kVersion ));
283+ mock_server_client_->MockGetResponse (
284+ kLayer , root_tile, kVersion ,
285+ GenerateQuadTreeResponse (root_tile, kQuadTreeDepth ,
286+ {1 , 3 , 12 , 13 , 14 }));
287+ mock_server_client_->MockGetResponse (kLayer , data_handle, data);
288+ }
289+
290+ auto client =
291+ std::make_unique<olp::dataservice::read::VersionedLayerClient>(
292+ hrn, kLayer , boost::none, *settings_);
293+
294+ auto future = client->GetAggregatedData (request).GetFuture ();
295+ auto response = future.get ();
296+ const auto result = response.MoveResult ();
297+ const auto & result_data = result.GetData ();
298+
299+ ASSERT_TRUE (response.IsSuccessful ())
300+ << response.GetError ().GetMessage ().c_str ();
301+ ASSERT_TRUE (result.GetData ());
302+ ASSERT_EQ (result_data->size (), data.size ());
303+ EXPECT_TRUE (std::equal (data.begin (), data.end (), result_data->begin ()));
304+ EXPECT_EQ (result.GetTile (), expect_tile);
305+ EXPECT_TRUE (mock_server_client_->Verify ());
306+ }
307+
308+ {
309+ SCOPED_TRACE (" Parent tile" );
310+ const auto expect_tile = tile.ChangedLevelTo (3 );
311+ const auto data_handle = mockserver::DefaultResponses::GenerateDataHandle (
312+ expect_tile.ToHereTile ());
313+ const auto data = mockserver::DefaultResponses::GenerateData ();
314+
315+ {
316+ SetUpMockServer (settings_->network_request_handler );
317+ mock_server_client_->MockLookupResourceApiResponse (
318+ mockserver::DefaultResponses::GenerateResourceApisResponse (kTestHrn ));
319+ mock_server_client_->MockGetVersionResponse (
320+ mockserver::DefaultResponses::GenerateVersionResponse (kVersion ));
321+ mock_server_client_->MockGetResponse (
322+ kLayer , root_tile, kVersion ,
323+ GenerateQuadTreeResponse (root_tile, kQuadTreeDepth , {1 , 2 , 3 }));
324+ mock_server_client_->MockGetResponse (kLayer , data_handle, data);
325+ }
326+
327+ auto client =
328+ std::make_unique<olp::dataservice::read::VersionedLayerClient>(
329+ hrn, kLayer , boost::none, *settings_);
330+
331+ auto future = client->GetAggregatedData (request).GetFuture ();
332+ auto response = future.get ();
333+ const auto result = response.MoveResult ();
334+ const auto & result_data = result.GetData ();
335+
336+ ASSERT_TRUE (response.IsSuccessful ())
337+ << response.GetError ().GetMessage ().c_str ();
338+ ASSERT_TRUE (result.GetData ());
339+ ASSERT_EQ (result_data->size (), data.size ());
340+ EXPECT_TRUE (std::equal (data.begin (), data.end (), result_data->begin ()));
341+ EXPECT_EQ (result.GetTile (), expect_tile);
342+ EXPECT_TRUE (mock_server_client_->Verify ());
343+ }
344+
345+ {
346+ SCOPED_TRACE (" Check cache" );
347+ const auto data_handle =
348+ mockserver::DefaultResponses::GenerateDataHandle (tile.ToHereTile ());
349+ const auto data = mockserver::DefaultResponses::GenerateData ();
350+
351+ {
352+ SetUpMockServer (settings_->network_request_handler );
353+ mock_server_client_->MockLookupResourceApiResponse (
354+ mockserver::DefaultResponses::GenerateResourceApisResponse (kTestHrn ));
355+ mock_server_client_->MockGetVersionResponse (
356+ mockserver::DefaultResponses::GenerateVersionResponse (kVersion ));
357+ mock_server_client_->MockGetResponse (
358+ kLayer , root_tile, kVersion ,
359+ GenerateQuadTreeResponse (root_tile, kQuadTreeDepth , {15 }));
360+ mock_server_client_->MockGetResponse (kLayer , data_handle, data);
361+ }
362+
363+ settings_->cache =
364+ olp::client::OlpClientSettingsFactory::CreateDefaultCache ({});
365+ auto client =
366+ std::make_unique<olp::dataservice::read::VersionedLayerClient>(
367+ hrn, kLayer , boost::none, *settings_);
368+
369+ auto future = client->GetAggregatedData (request).GetFuture ();
370+ auto response = future.get ();
371+ auto result = response.MoveResult ();
372+ auto result_data = result.GetData ();
373+
374+ ASSERT_TRUE (response.IsSuccessful ())
375+ << response.GetError ().GetMessage ().c_str ();
376+ ASSERT_TRUE (result.GetData ());
377+ ASSERT_EQ (result_data->size (), data.size ());
378+ EXPECT_TRUE (std::equal (data.begin (), data.end (), result_data->begin ()));
379+ ASSERT_EQ (result.GetTile (), tile);
380+ EXPECT_TRUE (mock_server_client_->Verify ());
381+
382+ const auto request =
383+ olp::dataservice::read::TileRequest ().WithTileKey (tile).WithFetchOption (
384+ olp::dataservice::read::CacheOnly);
385+ response = client->GetAggregatedData (request).GetFuture ().get ();
386+ result = response.MoveResult ();
387+ result_data = result.GetData ();
388+
389+ ASSERT_TRUE (response.IsSuccessful ())
390+ << response.GetError ().GetMessage ().c_str ();
391+ ASSERT_TRUE (result.GetData ());
392+ ASSERT_EQ (result_data->size (), data.size ());
393+ EXPECT_TRUE (std::equal (data.begin (), data.end (), result_data->begin ()));
394+ EXPECT_EQ (result.GetTile (), tile);
395+ EXPECT_TRUE (mock_server_client_->Verify ());
396+ }
397+ }
398+
128399} // namespace
0 commit comments