NCBI C++ ToolKit
netstorageobjectloc.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: netstorageobjectloc.cpp 102908 2024-08-05 17:21:55Z ivanov $
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: Dmitry Kazimirov
27  *
28  * File Description:
29  * Implementation of the unified network blob storage API.
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 
37 
38 #include <connect/ncbi_socket.h>
39 
40 #include <corelib/ncbi_base64.h>
41 #include <corelib/ncbiargs.hpp>
42 #include <util/compile_time.hpp> // for MAKE_CONST_MAP
43 
44 #include <time.h>
45 #include <string.h>
46 
47 
48 #define NCBI_USE_ERRCODE_X NetStorage_Common
49 
50 #define FILETRACK_STORAGE_CODE "FT"
51 #define NETCACHE_STORAGE_CODE "NC"
52 
53 #define STORAGE_INFO_CUE 0
54 
56 
59  const string& app_domain,
60  Uint8 random_number,
61  EFileTrackSite ft_site) :
62  m_CompoundIDPool(cid_pool),
63  m_LocatorFlags(x_StorageFlagsToLocatorFlags(flags, ft_site)),
64  m_AppDomain(app_domain),
65  m_Timestamp(time(NULL)),
66  m_Random(random_number),
67  m_ShortUniqueKey(MakeShortUniqueKey()),
68  m_UniqueKey(MakeUniqueKey()),
69  m_Dirty(true)
70 {
71 
72 }
73 
76  const string& app_domain,
77  const string& unique_key,
78  EFileTrackSite ft_site) :
79  m_CompoundIDPool(cid_pool),
80  m_LocatorFlags(x_StorageFlagsToLocatorFlags(flags, ft_site) | fLF_HasUserKey),
81  m_AppDomain(app_domain),
82  m_ShortUniqueKey(unique_key),
83  m_UniqueKey(MakeUniqueKey()),
84  m_Dirty(true)
85 {
86 }
87 
88 #define INVALID_LOC_ERROR_MSG "Invalid NetStorage object locator"
89 
90 #define THROW_INVALID_LOC_ERROR(cid, msg) \
91  NCBI_THROW_FMT(CNetStorageException, eInvalidArg, \
92  msg " '" << cid.ToString() << '\'')
93 
94 #define VERIFY_FIELD_EXISTS(field) \
95  if (!(field)) { \
96  THROW_INVALID_LOC_ERROR(cid, INVALID_LOC_ERROR_MSG); \
97  }
98 
100 {
101  if (location.length() == 2) {
102  if (location.data()[0] == FILETRACK_STORAGE_CODE[0] &&
103  location.data()[1] == FILETRACK_STORAGE_CODE[1])
104  return eNFL_FileTrack;
105  if (location.data()[0] == NETCACHE_STORAGE_CODE[0] &&
106  location.data()[1] == NETCACHE_STORAGE_CODE[1])
107  return eNFL_NetCache;
108  }
109  return eNFL_Unknown;
110 }
111 
113  const string& object_loc) :
114  m_CompoundIDPool(cid_pool),
115  m_Dirty(false),
116  m_Locator(object_loc)
117 {
118  auto cid = m_CompoundIDPool.FromString(object_loc);
119  Parse(cid, false);
120 }
121 
122 void CNetStorageObjectLoc::SetServiceName(const string& service_name)
123 {
124  if (service_name.empty() ||
125  strchr(service_name.c_str(), ':') != NULL)
127  else {
128  m_ServiceName = service_name;
130  }
131  m_Dirty = true;
132 }
133 
135 {
137  loc.Parse(cid, true);
138  return loc.m_ServiceName;
139 }
140 
141 void CNetStorageObjectLoc::Parse(CCompoundID cid, bool service_name_only)
142 {
143  // Check the ID class.
144  switch (cid.GetClass()) {
147  "Unsupported NetStorage object locator version");
149  break;
150  default:
152  }
153 
154  // Get locator flags.
155  CCompoundIDField field = cid.GetFirst(eCIT_Flags);
156  VERIFY_FIELD_EXISTS(field);
158 
159  // Restore NetStorage service name.
161  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
162  m_ServiceName = field.GetServiceName();
163  }
164 
165  if (service_name_only) return;
166 
167  // Restore object ID.
169  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
170  m_ObjectID = field.GetID();
171  }
172 
173  // Get the domain name.
174  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
175  m_AppDomain = field.GetString();
176 
177  m_SubKey.clear();
178  m_Version = 0;
179 
180  // Restore object identification.
182  // Get the unique object key.
183  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
184  m_ShortUniqueKey = field.GetString();
185 
187  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
188  m_SubKey = field.GetString();
189 
191  // null is stored as 0 (0 is not stored as it's the default)
192  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
193  auto version = static_cast<int>(field.GetInteger());
195  }
196  }
197  } else {
198  // Get object creation timestamp.
199  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
200  m_Timestamp = field.GetTimestamp();
201  // Get the random ID.
202  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
203  m_Random = (Uint8) field.GetRandom() << (sizeof(Uint4) * 8);
204  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
205  m_Random |= field.GetRandom();
207  }
208 
210 
211  // Not used, though has to be read to be backward-compatible
213  field = field.GetNextNeighbor();
214  }
215 
216  // Find storage info (optional).
217  for (field = cid.GetFirst(eCIT_Cue); field; field = field.GetNextHomogeneous()) {
218  if (field.GetCue() == STORAGE_INFO_CUE) {
219  // Restore object location.
220  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
223 
224  // Restore storage-specific info.
225  if (m_Location == eNFL_NetCache) {
226  // Not used, though has to be read to be backward-compatible
227  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
228 
229  // Get the service name.
230  VERIFY_FIELD_EXISTS(field = field.GetNextNeighbor());
232  }
233 
234  break;
235  }
236  }
237 }
238 
239 void CNetStorageObjectLoc::SetLocation(const string& nc_service_name)
240 {
241  // If NetCache
242  if (!nc_service_name.empty()) {
243  if (m_Location == eNFL_NetCache) return;
244 
247  } else {
248  if (m_Location == eNFL_FileTrack) return;
249 
252  }
253 
254  m_Dirty = true;
255  m_NCServiceName = nc_service_name;
256 }
257 
259 {
263 }
264 
266 {
268  result += '-';
270 
272  result += '-';
274  }
275 
276  return result;
277 }
278 
280 {
281  // Allocate a new CompoundID object.
283 
284  // Save locator flags.
285  // If its location is not set yet, add "Movable", so the locator can be used
288 
289  // Save NetStorage service name.
292 
293  // Save object ID.
295  cid.AppendID(m_ObjectID);
296 
297  // Save the domain name.
299 
300  // Save object identification
302  // Save the unique object key.
304 
306  cid.AppendString(m_SubKey);
307 
309  // null is stored as 0 (0 is not stored as it's the default)
311  }
312  }
313  } else {
314  // Save object creation timestamp.
316  // Save the random ID.
317  cid.AppendRandom((Uint4)(m_Random >> (sizeof(Uint4) * 8)));
318  cid.AppendRandom((Uint4) m_Random);
319  }
320 
321  // Not used, though has to be written to be backward-compatible
323  cid.AppendInteger(0);
324 
325  // Save storage info (optional).
326  if (m_Location != eNFL_Unknown) {
328 
329  // Save object location.
331 
332  switch (m_Location) {
333  case eNFL_NetCache:
334  // Not used, though has to be written to be backward-compatible
335  cid.AppendFlags(0);
336  // Save the service name.
338  break;
339  default:
340  break;
341  }
342  }
343 
344  // Now pack it all up.
345  m_Locator = cid.ToString();
346 
347  m_Dirty = false;
348 }
349 
351 {
353 
355  flags |= fNST_Movable;
360 
361  return flags;
362 }
363 
365 {
366  const auto new_locator_flags = (m_LocatorFlags & eLF_FieldFlags) | x_StorageFlagsToLocatorFlags(flags);
367 
368  if (new_locator_flags != m_LocatorFlags) {
369  m_Dirty = true;
370  m_LocatorFlags = new_locator_flags;
371  }
372 }
373 
376  TNetStorageAttrFlags storage_flags,
377  EFileTrackSite ft_site)
378 {
379  TLocatorFlags locator_flags = 0;
380 
381  if (storage_flags & fNST_Movable)
382  locator_flags |= fLF_Movable;
383  if (storage_flags & fNST_Cacheable)
384  locator_flags |= fLF_Cacheable;
385  if (storage_flags & fNST_NoMetaData)
386  locator_flags |= fLF_NoMetaData;
387 
388  if (ft_site == eFileTrack_DevSite)
389  locator_flags |= fLF_DevEnv;
390  else if (ft_site == eFileTrack_QASite)
391  locator_flags |= fLF_QAEnv;
392 
393  return locator_flags;
394 }
395 
397 {
399  ToJSON(root);
400  return root;
401 }
402 
404 {
405  root.SetInteger("Version", 1 +
407 
408  root.SetString("Environment",
409  m_LocatorFlags & fLF_DevEnv ? "dev/test" :
410  m_LocatorFlags & fLF_QAEnv ? "QA" : "production");
411 
413  root.SetString("ServiceName", m_ServiceName);
414 
416  root.SetString("Cache", m_AppDomain);
417  root.SetString("ObjectKey", m_ShortUniqueKey);
418  root.SetString("ObjectSubKey", m_SubKey);
419 
420  if (m_Version.IsNull()) {
421  root.SetNull("ObjectVersion");
422  } else {
423  root.SetInteger("ObjectVersion", m_Version);
424  }
425  } else {
426  root.SetString("ObjectKey", m_UniqueKey);
427  }
428 
429  CJsonNode storage_flags(CJsonNode::NewObjectNode());
430 
431  storage_flags.SetBoolean("Movable",
432  (m_LocatorFlags & fLF_Movable) != 0);
433  storage_flags.SetBoolean("Cacheable",
434  (m_LocatorFlags & fLF_Cacheable) != 0);
435  storage_flags.SetBoolean("NoMetaData",
436  (m_LocatorFlags & fLF_NoMetaData) != 0);
437 
438  root.SetByKey("StorageFlags", storage_flags);
439 
440  if (!m_LocationCode.empty())
441  root.SetString("DefaultLocation", m_LocationCode);
442 
443  CJsonNode storage_info(CJsonNode::NewObjectNode());
444 
445  switch (m_Location) {
446  case eNFL_NetCache:
447  storage_info.SetString("ServiceName", m_NCServiceName);
448  root.SetByKey("NetCache", storage_info);
449  break;
450  default:
451  break;
452  }
453 }
454 
456 {
458  {
459  { "production", eFileTrack_ProdSite },
460  { "prod", eFileTrack_ProdSite },
461  { "submit", eFileTrack_ProdSite },
462  { "development", eFileTrack_DevSite },
463  { "dev", eFileTrack_DevSite },
464  { "dsubmit", eFileTrack_DevSite },
465  { "qa", eFileTrack_QASite },
466  { "qsubmit", eFileTrack_QASite },
467  })
468  auto i = p.find(ft_site_name);
469  if (i == p.end()) {
470  NCBI_THROW_FMT(CArgException, eInvalidArg, "unrecognized FileTrack site '" << ft_site_name << '\'');
471  }
472  return i->second;
473 }
474 
475 string CNetStorageObjectLoc::Create(const string& service_name, const string& cache_name,
476  const string& key, const string& subkey, const TVersion& version)
477 {
478  CCompoundIDPool id_pool;
480  CNetStorageObjectLoc loc(id_pool, fNST_NoMetaData, cache_name, key, ft_site);
481  loc.SetLocation(service_name);
482  loc.m_SubKey = subkey;
483  loc.m_Version = version;
485  return loc.GetLocator();
486 }
487 
CArgException –.
Definition: ncbiargs.hpp:120
Compound ID field – an element of the compound ID that has a type and a value.
string GetString() const
Return the string value that this field contains.
CCompoundIDField GetNextHomogeneous()
Return the next field of the same type.
CCompoundIDField GetNextNeighbor()
Return the next immediately adjacent field.
Uint4 GetRandom() const
Return the random number value that this field contains.
Uint8 GetCue() const
Return the application-specific numeric tag value that this field contains.
string GetServiceName() const
Return the LBSM service name that this field contains.
Int8 GetTimestamp() const
Return the UNIX timestamp that this field contains.
Int8 GetInteger() const
Return the integer value that this field contains.
string GetDatabaseName() const
Return the database name that this field contains.
Uint8 GetID() const
Return the ID value that this field contains.
Uint8 GetFlags() const
Return the combination of binary flags stored in this field.
Pool of recycled CCompoundID objects.
CCompoundID NewID(ECompoundIDClass new_id_class)
Create and return a new CCompoundID objects.
CCompoundID FromString(const string &cid)
Unpack the base64-encoded ID and return a CCompoundID object for field extraction.
Base64-encoded ID string that contains extractable typed fields.
void AppendDatabaseName(const string &db_name)
Append an eCIT_DatabaseName field at the end of this compound ID.
void AppendRandom(Uint4 random_number)
Append an eCIT_Random field at the end of this compound ID.
void AppendCue(Uint8 tag)
Append an eCIT_Cue field at the end of this compound ID.
void AppendString(const string &string_value)
Append an eCIT_String field at the end of this compound ID.
CCompoundIDField GetFirst(ECompoundIDFieldType field_type)
Return the first field of the specified type or NULL if this compound ID contains no fields of such t...
string ToString()
Pack the ID and return its string representation.
void AppendTimestamp(Int8 timestamp)
Append an eCIT_Timestamp field at the end of this compound ID.
void AppendID(Uint8 id)
Append an eCIT_ID field at the end of this compound ID.
void AppendFlags(Uint8 flags)
Append an eCIT_Flags field at the end of this compound ID.
ECompoundIDClass GetClass() const
One of the registered ID classes.
void AppendServiceName(const string &service_name)
Append an eCIT_ServiceName field at the end of this compound ID.
void AppendInteger(Int8 number)
Append an eCIT_Integer field at the end of this compound ID.
JSON node abstraction.
void SetString(const string &key, const string &value)
Set a JSON object element to the specified string value.
void SetNull(const string &key)
Set a JSON object element to the specified null value.
void SetBoolean(const string &key, bool value)
Set a JSON object element to the specified boolean value.
void SetInteger(const string &key, Int8 value)
Set a JSON object element to the specified integer value.
void SetByKey(const string &key, CJsonNode::TInstance value)
For a JSON object node, insert a new element or update an existing element.
static CJsonNode NewObjectNode()
Create a new JSON object node.
void SetStorageAttrFlags(TNetStorageAttrFlags flags)
void Parse(CCompoundID cid, bool service_name_only)
static string Create(const string &service_name, const string &cache_name, const string &key, const string &subkey, const TVersion &version=null)
static TLocatorFlags x_StorageFlagsToLocatorFlags(TNetStorageAttrFlags storage_flags, EFileTrackSite ft_site=eFileTrack_ProdSite)
TNetStorageAttrFlags GetStorageAttrFlags() const
void SetLocatorFlags(TLocatorFlags flags)
string GetLocator() const
CCompoundIDPool m_CompoundIDPool
ENetStorageObjectLocation m_Location
TLocatorFlags m_LocatorFlags
string MakeShortUniqueKey() const
void SetLocation(const string &nc_service_name)
CNullable< int > TVersion
string MakeUniqueKey() const
void ClearLocatorFlags(TLocatorFlags flags)
string GetServiceName() const
static EFileTrackSite ParseFileTrackSite(const string &ft_site_name)
void SetServiceName(const string &service_name)
EFileTrackSite GetFileTrackSite() const
#define MAKE_CONST_MAP(name, type1, type2,...)
@ eCIT_Cue
Definition: compound_id.hpp:78
@ eCIT_Flags
Definition: compound_id.hpp:76
@ eCIC_NetStorageObjectLocV1
Old version of NetStorageObjectLoc.
Definition: compound_id.hpp:54
@ eCIC_NetStorageObjectLoc
Definition: compound_id.hpp:55
static uch flags
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static const char location[]
Definition: config.c:97
bool IsNull(void) const
Check if the object is unassigned.
Definition: ncbimisc.hpp:686
const TValue & GetValue(void) const
Get a const reference to the current value.
Definition: ncbimisc.hpp:703
#define NULL
Definition: ncbistd.hpp:225
static const string & GetHostRole(void)
Get host role (DEV/QA/TRY/PROD) from /etc/ncbi/role.
Definition: ncbidiag.cpp:3091
#define NCBI_THROW_FMT(exception_class, err_code, message)
The same as NCBI_THROW but with message processed as output to ostream.
Definition: ncbiexpt.hpp:719
ENetStorageObjectLocation
Enumeration that indicates the current location of the object.
Definition: netstorage.hpp:86
@ fNST_NoMetaData
Do not use NetStorage relational database to track ownership & changes.
Definition: netstorage.hpp:140
@ fNST_Cacheable
Has no effect at the moment.
Definition: netstorage.hpp:139
@ fNST_Movable
Allow the object to move between storages.
Definition: netstorage.hpp:138
@ eNFL_FileTrack
Definition: netstorage.hpp:90
@ eNFL_NetCache
Definition: netstorage.hpp:89
@ eNFL_Unknown
Definition: netstorage.hpp:87
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
Definition of all error codes used in connect services library (xconnserv.lib and others).
int i
std::false_type tagStrNocase
const string version
version string
Definition: variables.hpp:66
const struct ncbi::grid::netcache::search::fields::KEY key
const struct ncbi::grid::netcache::search::fields::SUBKEY subkey
Defines command line argument related classes.
#define FILETRACK_STORAGE_CODE
#define VERIFY_FIELD_EXISTS(field)
#define NETCACHE_STORAGE_CODE
#define STORAGE_INFO_CUE
ENetStorageObjectLocation s_LocationCodeToLocation(const string &location)
#define THROW_INVALID_LOC_ERROR(cid, msg)
#define INVALID_LOC_ERROR_MSG
else result
Definition: token2.c:20
Modified on Fri Sep 20 14:58:21 2024 by modify_doxy.py rev. 669887