1 /*  $Id: state.cpp 617404 2020-09-30 19:02:00Z sadyrovr $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Rafael Sadyrov
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 
32 #include <connect/services/impl/netstorage_impl.hpp>
33 
34 #include "state.hpp"
35 
36 #include <limits>
37 #include <sstream>
38 
39 
40 BEGIN_NCBI_SCOPE
41 
42 
43 namespace NDirectNetStorageImpl
44 {
45 
46 
Read(void *,size_t,size_t *)47 ERW_Result CRWNotFound::Read(void*, size_t, size_t*)
48 {
49     NCBI_THROW_FMT(CNetStorageException, eNotExists, "On calling Read() cannot open " << GetLoc());
50     return eRW_Error; // Not reached
51 }
52 
53 
PendingCount(size_t *)54 ERW_Result CRWNotFound::PendingCount(size_t*)
55 {
56     NCBI_THROW_FMT(CNetStorageException, eNotExists, "On calling PendingCount() cannot open " << GetLoc());
57     return eRW_Error; // Not reached
58 }
59 
60 
Eof()61 bool CRWNotFound::Eof()
62 {
63     NCBI_THROW_FMT(CNetStorageException, eNotExists, "On calling Eof() cannot open " << GetLoc());
64     return false; // Not reached
65 }
66 
67 
Write(const void *,size_t,size_t *)68 ERW_Result CRWNotFound::Write(const void*, size_t, size_t*)
69 {
70     NCBI_THROW_FMT(CNetStorageException, eNotExists, "On calling Write() cannot open " << GetLoc());
71     return eRW_Error; // Not reached
72 }
73 
74 
Read(void * buf,size_t count,size_t * bytes_read)75 ERW_Result CRONetCache::Read(void* buf, size_t count, size_t* bytes_read)
76 {
77     try {
78         size_t bytes_read_local = 0;
79         ERW_Result rw_res = m_Reader->Read(buf, count, &bytes_read_local);
80         m_BytesRead += bytes_read_local;
81         if (bytes_read != NULL)
82             *bytes_read = bytes_read_local;
83         return rw_res;
84     }
85     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on reading " + GetLoc())
86     return eRW_Error; // Not reached
87 }
88 
89 
PendingCount(size_t * count)90 ERW_Result CRONetCache::PendingCount(size_t* count)
91 {
92     try {
93         return m_Reader->PendingCount(count);
94     }
95     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on writing " + GetLoc())
96     return eRW_Error; // Not reached
97 }
98 
99 
Eof()100 bool CRONetCache::Eof()
101 {
102     return m_BytesRead >= m_BlobSize;
103 }
104 
105 
Close()106 void CRONetCache::Close()
107 {
108     ExitState();
109     try {
110         m_Reader.reset();
111     }
112     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("after reading " + GetLoc())
113 }
114 
115 
Abort()116 void CRONetCache::Abort()
117 {
118     Close();
119 }
120 
121 
Write(const void * buf,size_t count,size_t * bytes_written)122 ERW_Result CWONetCache::Write(const void* buf, size_t count, size_t* bytes_written)
123 {
124     try {
125         return m_Writer->Write(buf, count, bytes_written);
126     }
127     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on writing " + GetLoc())
128     return eRW_Error; // Not reached
129 }
130 
131 
Flush()132 ERW_Result CWONetCache::Flush()
133 {
134     try {
135         return m_Writer->Flush();
136     }
137     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on writing " + GetLoc())
138     return eRW_Error; // Not reached
139 }
140 
141 
Close()142 void CWONetCache::Close()
143 {
144     ExitState();
145     try {
146         m_Writer->Close();
147         m_Writer.reset();
148     }
149     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("after writing " + GetLoc())
150 }
151 
152 
Abort()153 void CWONetCache::Abort()
154 {
155     ExitState();
156     m_Writer->Abort();
157     m_Writer.reset();
158 }
159 
160 
Read(void * buf,size_t count,size_t * bytes_read)161 ERW_Result CROFileTrack::Read(void* buf, size_t count, size_t* bytes_read)
162 {
163     return m_Request->Read(buf, count, bytes_read);
164 }
165 
166 
PendingCount(size_t * count)167 ERW_Result CROFileTrack::PendingCount(size_t* count)
168 {
169     *count = 0;
170     return eRW_Success;
171 }
172 
173 
Eof()174 bool CROFileTrack::Eof()
175 {
176     return m_Request->Eof();
177 }
178 
179 
Close()180 void CROFileTrack::Close()
181 {
182     ExitState();
183     m_Request->FinishDownload();
184     m_Request.Reset();
185 }
186 
187 
Abort()188 void CROFileTrack::Abort()
189 {
190     ExitState();
191     m_Request.Reset();
192 }
193 
194 
Write(const void * buf,size_t count,size_t * bytes_written)195 ERW_Result CWOFileTrack::Write(const void* buf, size_t count, size_t* bytes_written)
196 {
197     m_Request->Write(buf, count, bytes_written);
198     return eRW_Success;
199 }
200 
201 
Flush()202 ERW_Result CWOFileTrack::Flush()
203 {
204     return eRW_Success;
205 }
206 
207 
Close()208 void CWOFileTrack::Close()
209 {
210     ExitState();
211     m_Request->FinishUpload();
212     m_Request.Reset();
213 }
214 
215 
Abort()216 void CWOFileTrack::Abort()
217 {
218     ExitState();
219     m_Request.Reset();
220 }
221 
222 
SetLocator()223 void CNotFound::SetLocator()
224 {
225     NCBI_THROW_FMT(CNetStorageException, eNotExists,
226             "Cannot open \"" << GetLoc() << "\" for writing.");
227 }
228 
229 
StartRead(void * buf,size_t count,size_t * bytes_read,ERW_Result * result)230 INetStorageObjectState* CNotFound::StartRead(void* buf, size_t count,
231         size_t* bytes_read, ERW_Result* result)
232 {
233     _ASSERT(result);
234     *result = m_RW.Read(buf, count, bytes_read);
235     return &m_RW;
236 }
237 
238 
StartWrite(const void *,size_t,size_t *,ERW_Result *)239 INetStorageObjectState* CNotFound::StartWrite(const void*, size_t, size_t*, ERW_Result*)
240 {
241     NCBI_THROW_FMT(CNetStorageException, eInvalidArg,
242             "Object creation is disabled (no backend storages were provided)");
243     return NULL;
244 }
245 
246 
GetSize()247 Uint8 CNotFound::GetSize()
248 {
249     NCBI_THROW_FMT(CNetStorageException, eNotExists,
250             "NetStorageObject \"" << GetLoc() <<
251             "\" could not be found in any of the designated locations.");
252     return 0; // Not reached
253 }
254 
255 
GetInfo()256 CNetStorageObjectInfo CNotFound::GetInfo()
257 {
258     CNetStorageObjectLoc& object_loc(Locator());
259     return g_CreateNetStorageObjectInfo(object_loc.GetLocator(),
260             eNFL_NotFound, &object_loc, 0, NULL);
261 }
262 
263 
Exists()264 bool CNotFound::Exists()
265 {
266     return false;
267 }
268 
269 
Remove()270 ENetStorageRemoveResult CNotFound::Remove()
271 {
272     return eNSTRR_NotFound;
273 }
274 
275 
SetExpiration(const CTimeout &)276 void CNotFound::SetExpiration(const CTimeout&)
277 {
278     NCBI_THROW_FMT(CNetStorageException, eNotExists,
279             "NetStorageObject \"" << GetLoc() <<
280             "\" could not be found in any of the designated locations.");
281 }
282 
283 
FileTrack_Path()284 string CNotFound::FileTrack_Path()
285 {
286     NCBI_THROW_FMT(CNetStorageException, eNotExists,
287             "NetStorageObject \"" << GetLoc() <<
288             "\" could not be found in any of the designated locations.");
289     return kEmptyStr; // Not reached
290 }
291 
292 
GetUserInfo()293 pair<string, string> CNotFound::GetUserInfo()
294 {
295     NCBI_THROW_FMT(CNetStorageException, eNotExists,
296             "NetStorageObject \"" << GetLoc() <<
297             "\" could not be found in any of the designated locations.");
298     return make_pair(kEmptyStr, kEmptyStr); // Not reached
299 }
300 
301 
Init()302 bool CNetCache::Init()
303 {
304     if (!m_Client) {
305         CNetStorageObjectLoc& object_loc(Locator());
306         if (object_loc.GetLocation() == eNFL_NetCache) {
307             m_Client = CNetICacheClient(object_loc.GetNCServiceName(),
308                     object_loc.GetAppDomain(), kEmptyStr);
309         } else if (m_Context->icache_client)
310             m_Client = m_Context->icache_client;
311         else
312             return false;
313     }
314     return true;
315 }
316 
317 
SetLocator()318 void CNetCache::SetLocator()
319 {
320     CNetService service(m_Client.GetService());
321     const string& service_name(service.GetServiceName());
322 
323     Locator().SetLocation(service_name);
324 }
325 
326 
StartRead(void * buf,size_t count,size_t * bytes_read,ERW_Result * result)327 INetStorageObjectState* CNetCache::StartRead(void* buf, size_t count,
328         size_t* bytes_read, ERW_Result* result)
329 {
330     _ASSERT(result);
331 
332     CNetStorageObjectLoc& object_loc(Locator());
333 
334     try {
335         size_t blob_size;
336         CRONetCache::TReaderPtr reader;
337         const auto& key = object_loc.GetShortUniqueKey();
338         const auto& version = object_loc.GetVersion();
339         const auto& subkey = object_loc.GetSubKey();
340 
341         if (version.IsNull()) {
342             int not_used;
343             reader.reset(m_Client.GetReadStream(key, subkey, &not_used, &blob_size,
344                     (nc_caching_mode = CNetCacheAPI::eCaching_Disable,
345                     nc_cache_name = object_loc.GetAppDomain())));
346         } else {
347             reader.reset(m_Client.GetReadStream(key, version, subkey, &blob_size,
348                     (nc_caching_mode = CNetCacheAPI::eCaching_Disable,
349                     nc_cache_name = object_loc.GetAppDomain())));
350         }
351 
352         if (!reader.get()) {
353             return NULL;
354         }
355 
356         m_Read.Set(move(reader), blob_size);
357         *result =  m_Read.Read(buf, count, bytes_read);
358     }
359     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on reading " + object_loc.GetLocator())
360 
361     return &m_Read;
362 }
363 
364 
365 // Cannot make this code a function,
366 // as otherwise it would get into thrown exception instead of the methods using this code
367 #define NC_CHECK_VERSION(object_loc)                                                    \
368     if (object_loc.GetVersion().IsNull()) {                                             \
369         NCBI_THROW_FMT(CNetStorageException, eInvalidArg,                               \
370                 "Null version is not supported");                                       \
371     }
372 
373 #define NC_GET_ARGS(object_loc)                                                         \
374     object_loc.GetShortUniqueKey(), object_loc.GetVersion(), object_loc.GetSubKey(),    \
375     nc_cache_name = object_loc.GetAppDomain()
376 
377 
StartWrite(const void * buf,size_t count,size_t * bytes_written,ERW_Result * result)378 INetStorageObjectState* CNetCache::StartWrite(const void* buf, size_t count,
379         size_t* bytes_written, ERW_Result* result)
380 {
381     _ASSERT(result);
382 
383     CNetStorageObjectLoc& object_loc(Locator());
384 
385     try {
386         NC_CHECK_VERSION(object_loc);
387         CWONetCache::TWriterPtr writer(m_Client.GetNetCacheWriter(NC_GET_ARGS(object_loc)));
388 
389         _ASSERT(writer.get());
390 
391         m_Write.Set(move(writer));
392         *result = m_Write.Write(buf, count, bytes_written);
393     }
394     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on writing " + object_loc.GetLocator())
395 
396     SetLocator();
397     return &m_Write;
398 }
399 
400 
GetSize()401 Uint8 CNetCache::GetSize()
402 {
403     CNetStorageObjectLoc& object_loc(Locator());
404 
405     try {
406         NC_CHECK_VERSION(object_loc);
407         return m_Client.GetBlobSize(NC_GET_ARGS(object_loc));
408     }
409     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on accessing " + object_loc.GetLocator())
410     return 0; // Not reached
411 }
412 
413 
GetInfo()414 CNetStorageObjectInfo CNetCache::GetInfo()
415 {
416     CJsonNode blob_info = CJsonNode::NewObjectNode();
417     CNetStorageObjectLoc& object_loc(Locator());
418 
419     try {
420         NC_CHECK_VERSION(object_loc);
421         CNetServerMultilineCmdOutput output = m_Client.GetBlobInfo(NC_GET_ARGS(object_loc));
422 
423         string line, key, val;
424 
425         while (output.ReadLine(line))
426             if (NStr::SplitInTwo(line, ": ", key, val, NStr::fSplit_ByPattern))
427                 blob_info.SetByKey(key, CJsonNode::GuessType(val));
428     }
429     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on accessing " + GetLoc())
430 
431     CJsonNode size_node(blob_info.GetByKeyOrNull("Size"));
432 
433     Uint8 blob_size = size_node && size_node.IsInteger() ?
434             (Uint8) size_node.AsInteger() : GetSize();
435 
436     return g_CreateNetStorageObjectInfo(object_loc.GetLocator(), eNFL_NetCache,
437             &object_loc, blob_size, blob_info);
438 }
439 
440 
441 // Cannot use Exists() directly from other methods,
442 // as otherwise it would get into thrown exception instead of those methods
443 #define NC_EXISTS_IMPL(object_loc)                                          \
444     if (!m_Client.HasBlob(object_loc.GetShortUniqueKey(),                   \
445                 object_loc.GetSubKey(), nc_cache_name = object_loc.GetAppDomain())) { \
446         /* Have to throw to let other locations try */                      \
447         NCBI_THROW_FMT(CNetStorageException, eNotExists,                    \
448             "NetStorageObject \"" << object_loc.GetLocator() <<             \
449             "\" does not exist in NetCache.");                              \
450     }
451 
452 
Exists()453 bool CNetCache::Exists()
454 {
455     CNetStorageObjectLoc& object_loc(Locator());
456 
457     try {
458         NC_EXISTS_IMPL(object_loc);
459     }
460     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on accessing " + GetLoc())
461 
462     return true;
463 }
464 
465 
Remove()466 ENetStorageRemoveResult CNetCache::Remove()
467 {
468     CNetStorageObjectLoc& object_loc(Locator());
469 
470     try {
471         // NetCache returns OK on removing already-removed/non-existent blobs,
472         // so have to check for existence first and throw if not
473         NC_EXISTS_IMPL(object_loc);
474         NC_CHECK_VERSION(object_loc);
475         m_Client.RemoveBlob(NC_GET_ARGS(object_loc));
476     }
477     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on removing " + GetLoc())
478 
479     return eNSTRR_Removed;
480 }
481 
482 
SetExpiration(const CTimeout & requested_ttl)483 void CNetCache::SetExpiration(const CTimeout& requested_ttl)
484 {
485     CNetStorageObjectLoc& object_loc(Locator());
486 
487     try {
488         NC_EXISTS_IMPL(object_loc);
489 
490         CTimeout ttl(requested_ttl);
491 
492         if (!ttl.IsFinite()) {
493             // NetCache does not support infinite TTL, use max possible instead
494             ttl.Set(numeric_limits<unsigned>::max(), 0);
495         }
496 
497         m_Client.ProlongBlobLifetime(object_loc.GetShortUniqueKey(), object_loc.GetSubKey(), ttl,
498                 nc_cache_name = object_loc.GetAppDomain());
499     }
500     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on accessing " + GetLoc())
501 }
502 
503 
FileTrack_Path()504 string CNetCache::FileTrack_Path()
505 {
506     NCBI_THROW_FMT(CNetStorageException, eInvalidArg,
507             "NetStorageObject \"" << GetLoc() <<
508             "\" is not a FileTrack object");
509     return kEmptyStr; // Not reached
510 }
511 
512 
GetUserInfo()513 pair<string, string> CNetCache::GetUserInfo()
514 {
515     CNetStorageObjectLoc& object_loc(Locator());
516 
517     try {
518         NC_EXISTS_IMPL(object_loc);
519     }
520     NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on accessing " + GetLoc())
521 
522     // Not supported
523     return make_pair(kEmptyStr, kEmptyStr);
524 }
525 
526 
SetLocator()527 void CFileTrack::SetLocator()
528 {
529     Locator().SetLocation(kEmptyStr);
530 }
531 
532 
StartRead(void * buf,size_t count,size_t * bytes_read,ERW_Result * result)533 INetStorageObjectState* CFileTrack::StartRead(void* buf, size_t count,
534         size_t* bytes_read, ERW_Result* result)
535 {
536     _ASSERT(result);
537 
538     CROFileTrack::TRequest request = m_Context->filetrack_api.StartDownload(Locator());
539 
540     try {
541         m_Read.Set(request);
542         *result = m_Read.Read(buf, count, bytes_read);
543         return &m_Read;
544     }
545     catch (CNetStorageException& e) {
546         request.Reset();
547 
548         if (e.GetErrCode() != CNetStorageException::eNotExists) {
549             throw;
550         }
551     }
552 
553     return NULL;
554 }
555 
556 
StartWrite(const void * buf,size_t count,size_t * bytes_written,ERW_Result * result)557 INetStorageObjectState* CFileTrack::StartWrite(const void* buf, size_t count,
558         size_t* bytes_written, ERW_Result* result)
559 {
560     _ASSERT(result);
561 
562     CWOFileTrack::TRequest request = m_Context->filetrack_api.StartUpload(Locator());
563     m_Write.Set(request);
564     *result = m_Write.Write(buf, count, bytes_written);
565     SetLocator();
566     return &m_Write;
567 }
568 
569 
GetSize()570 Uint8 CFileTrack::GetSize()
571 {
572     return (Uint8) m_Context->filetrack_api.GetFileInfo(
573             Locator()).GetInteger("size");
574 }
575 
576 
GetInfo()577 CNetStorageObjectInfo CFileTrack::GetInfo()
578 {
579     CNetStorageObjectLoc& object_loc(Locator());
580     CJsonNode file_info_node =
581             m_Context->filetrack_api.GetFileInfo(object_loc);
582 
583     Uint8 file_size = 0;
584 
585     CJsonNode size_node = file_info_node.GetByKeyOrNull("size");
586 
587     if (size_node)
588         file_size = (Uint8) size_node.AsInteger();
589 
590     return g_CreateNetStorageObjectInfo(object_loc.GetLocator(),
591             eNFL_FileTrack, &object_loc, file_size, file_info_node);
592 }
593 
594 
595 // Cannot use Exists() directly from other methods,
596 // as otherwise it would get into thrown exception instead of those methods
597 #define FT_EXISTS_IMPL(object_loc)                                  \
598     if (!m_Context->filetrack_api.GetFileInfo(object_loc)) {        \
599         /* Have to throw to let other locations try */              \
600         NCBI_THROW_FMT(CNetStorageException, eNotExists,            \
601             "NetStorageObject \"" << object_loc.GetLocator() <<     \
602             "\" does not exist in FileTrack.");                     \
603     }
604 
605 
Exists()606 bool CFileTrack::Exists()
607 {
608     CNetStorageObjectLoc& object_loc(Locator());
609     FT_EXISTS_IMPL(object_loc);
610     return true;
611 }
612 
613 
Remove()614 ENetStorageRemoveResult CFileTrack::Remove()
615 {
616     CNetStorageObjectLoc& object_loc(Locator());
617     m_Context->filetrack_api.Remove(object_loc);
618     return eNSTRR_Removed;
619 }
620 
621 
SetExpiration(const CTimeout &)622 void CFileTrack::SetExpiration(const CTimeout&)
623 {
624     CNetStorageObjectLoc& object_loc(Locator());
625     // By default objects in FileTrack do not have expiration,
626     // so checking only object existence
627     FT_EXISTS_IMPL(object_loc);
628     NCBI_THROW_FMT(CNetStorageException, eNotSupported,
629             "SetExpiration() is not supported for FileTrack");
630 }
631 
632 
FileTrack_Path()633 string CFileTrack::FileTrack_Path()
634 {
635     return m_Context->filetrack_api.GetPath(Locator());
636 }
637 
638 
GetUserInfo()639 pair<string, string> CFileTrack::GetUserInfo()
640 {
641     CJsonNode file_info = m_Context->filetrack_api.GetFileInfo(Locator());
642     CJsonNode my_ncbi_id = file_info.GetByKeyOrNull("myncbi_id");
643 
644     if (my_ncbi_id) return make_pair(string("my_ncbi_id"), my_ncbi_id.Repr());
645 
646     return make_pair(kEmptyStr, kEmptyStr);
647 }
648 
649 
s_GetICClient(const SCombinedNetStorageConfig & c)650 CNetICacheClient s_GetICClient(const SCombinedNetStorageConfig& c)
651 {
652     if (c.nc_service.empty() || c.app_domain.empty() || c.client_name.empty()) {
653         return eVoid;
654     }
655 
656     return CNetICacheClient(c.nc_service, c.app_domain, c.client_name);
657 }
658 
659 
s_GetSection(const IRegistry & registry,const string & service,const string & name)660 string s_GetSection(const IRegistry& registry, const string& service,
661         const string& name)
662 {
663     if (!service.empty()) {
664         const string section = "service_" + service;
665 
666         if (registry.HasEntry(section, name)) {
667             return section;
668         }
669     }
670 
671     return "netstorage_api";
672 }
673 
674 
s_GetFTConfig(const IRegistry & registry,const string & service)675 SFileTrackConfig s_GetFTConfig(const IRegistry& registry, const string& service)
676 {
677     const string param_name = "filetrack";
678     const string service_section = s_GetSection(registry, service, param_name);
679     const string ft_section = registry.Get(service_section, param_name);
680     return ft_section.empty() ? eVoid : SFileTrackConfig(registry, ft_section);
681 }
682 
683 
s_GetICClient(const IRegistry & registry,const string & service)684 CNetICacheClient s_GetICClient(const IRegistry& registry, const string& service)
685 {
686     const string param_name = "netcache";
687     const string service_section = s_GetSection(registry, service, param_name);
688     const string nc_section = registry.Get(service_section, param_name);
689     return nc_section.empty() ? eVoid : CNetICacheClient(registry, nc_section);
690 }
691 
692 
s_GetAppDomain(const string & app_domain,CNetICacheClient & nc_client)693 string s_GetAppDomain(const string& app_domain, CNetICacheClient& nc_client)
694 {
695     // In general, app_domain may not be avaiable.
696     // Since its value does not actually affect anything,
697     // we just use cache name from CNetICacheClient.
698     // If that is not avaiable, "default" value is used instead.
699 
700     if (!app_domain.empty()) return app_domain;
701 
702     if (nc_client) {
703         const string cache_name(nc_client.GetCacheName());
704 
705         if (!cache_name.empty()) return cache_name;
706     }
707 
708     return "default";
709 }
710 
711 
s_GetRelocateChunk(const IRegistry & registry,const string & service,size_t default_value)712 size_t s_GetRelocateChunk(const IRegistry& registry, const string& service,
713         size_t default_value)
714 {
715     const string param_name = "relocate_chunk";
716     const string service_section = s_GetSection(registry, service, param_name);
717     return registry.GetInt(service_section, param_name, static_cast<int>(default_value));
718 }
719 
720 
721 const size_t kRelocateChunk = 1024 * 1024;
722 
723 
SContext(const SCombinedNetStorageConfig & config,TNetStorageFlags flags)724 SContext::SContext(const SCombinedNetStorageConfig& config, TNetStorageFlags flags)
725     : icache_client(s_GetICClient(config)),
726       filetrack_api(config.ft),
727       default_flags(flags),
728       app_domain(s_GetAppDomain(config.app_domain, icache_client)),
729       relocate_chunk(kRelocateChunk)
730 {
731     Init();
732 }
733 
734 
SContext(const string & service_name,const string & domain,CCompoundIDPool::TInstance id_pool,const IRegistry & registry)735 SContext::SContext(const string& service_name, const string& domain,
736         CCompoundIDPool::TInstance id_pool,
737         const IRegistry& registry)
738     : icache_client(s_GetICClient(registry, service_name)),
739       filetrack_api(s_GetFTConfig(registry, service_name)),
740       compound_id_pool(id_pool ? CCompoundIDPool(id_pool) : CCompoundIDPool()),
741       app_domain(s_GetAppDomain(domain, icache_client)),
742       relocate_chunk(s_GetRelocateChunk(registry, service_name, kRelocateChunk))
743 {
744     Init();
745 }
746 
747 
Init()748 void SContext::Init()
749 {
750     random.Randomize();
751 
752     const TNetStorageFlags backend_storage =
753         (icache_client ? fNST_NetCache  : 0) |
754         (filetrack_api ? fNST_FileTrack : 0);
755 
756     // If there were specific underlying storages requested
757     if (TNetStorageLocFlags(default_flags)) {
758         // Reduce storages to the ones that are available
759         default_flags &= (backend_storage | fNST_AnyAttr);
760     } else {
761         // Use all available underlying storages
762         default_flags |= backend_storage;
763     }
764 
765     if (TNetStorageLocFlags(default_flags)) {
766         if (app_domain.empty() && icache_client) {
767             app_domain = icache_client.GetCacheName();
768         }
769     }
770 }
771 
772 
773 }
774 
775 
776 SCombinedNetStorageConfig::EMode
GetMode(const string & value)777 SCombinedNetStorageConfig::GetMode(const string& value)
778 {
779     if (NStr::CompareNocase(value, "direct") == 0)
780         return eServerless;
781     else
782         return eDefault;
783 }
784 
785 
ParseArg(const string & name,const string & value)786 void SCombinedNetStorageConfig::ParseArg(const string& name,
787         const string& value)
788 {
789     if (name == "mode")
790         mode = GetMode(value);
791     else if (!ft.ParseArg(name, value))
792         SNetStorage::SConfig::ParseArg(name, value);
793 }
794 
795 
796 END_NCBI_SCOPE
797