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

Go to the SVN repository for this file.

1 /* $Id: nc_cmds.cpp 100724 2023-09-01 19:52:08Z lavr $
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  * Authors: Dmitry Kazimirov
27  *
28  * File Description: NetCache-specific commands of the grid_cli application.
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include "grid_cli.hpp"
35 
37 
39 {
41  GetRWConfig().Set("netcache_api", "enable_mirroring", "true");
42  }
43 }
44 
46  bool require_version, bool require_service)
47 {
49 
50  if (!icache_mode) {
51  if (!m_Opts.ncid.subkey.empty() || NStr::MatchesMask(m_Opts.ncid.key, "*,*,*")) {
52  NCBI_THROW(CArgException, eNoValue, "both '--" NETCACHE_OPTION "' and '--" CACHE_OPTION "' "
53  "options are required in icache mode.");
54  }
55 
57 
58  if (!IsOptionSet(eNetCache)) {
59  if (m_Opts.ncid.key.empty()) {
60  if (require_service) {
61  NCBI_THROW(CArgException, eNoValue, "'--" NETCACHE_OPTION "' "
62  "option is required when ID is not provided.");
63  }
64  } else {
65  // If NetCache service is not provided, use server from blob ID
67 
68  if (key.GetVersion() != 3) {
69  m_Opts.nc_service = key.GetHost() + ':' + to_string(key.GetPort());
70  }
71  }
72  }
73 
76 
77  if (!m_Opts.ncid.key.empty() && IsOptionExplicitlySet(eNetCache)) {
79 
80  if (key.GetVersion() != 3) {
81  if (auto address = SSocketAddress::Parse(m_Opts.nc_service)) {
82  m_NetCacheAPI.GetService().GetServerPool().StickToServer(std::move(address));
83  } else {
84  NCBI_THROW(CArgException, eInvalidArg,
85  "When blob ID is given, '--" NETCACHE_OPTION "' "
86  "must be a host:port server address.");
87  }
88 
89  }
90  }
91 
94  }
95 
96  } else {
97  m_Opts.ncid.Parse(icache_mode, require_version);
98 
102 
103  if (m_Opts.nc_service.empty()) {
104  NCBI_THROW(CArgException, eNoValue, "'--" NETCACHE_OPTION "' "
105  "option is required in icache mode.");
106  }
107 
108  if (!IsOptionSet(eCompatMode))
110  }
111 }
112 
115 {
116  SetUp_NetCache();
117 
119 
120  if (cmd_severity != eReadOnlyAdminCmd &&
122  NCBI_THROW(CArgException, eNoValue, "'--" NETCACHE_OPTION "' "
123  "must be explicitly specified.");
124  }
127 }
128 
130 {
131  CTime generation_time;
132 
133  generation_time.SetTimeT((time_t) key.GetCreationTime());
134 
135  if (key.GetVersion() != 3)
136  printf("server_address: %s:%hu\n",
137  g_NetService_TryResolveHost(key.GetHost()).c_str(), key.GetPort());
138  else
139  printf("server_address_crc32: 0x%08X\n", key.GetHostPortCRC32());
140 
141  printf("id: %u\nkey_generation_time: %s\nrandom: %u\n",
142  key.GetId(),
143  generation_time.AsString().c_str(),
144  (unsigned) key.GetRandomPart());
145 
146  string service(key.GetServiceName());
147 
148  if (!service.empty())
149  printf("service_name: %s\n", service.c_str());
150 }
151 
153  const string& value)
154 {
155  switch (++parts) {
156  case 1:
157  // First parameter is always key
158  key = value;
159  return true;
160  case 2:
161  // Second parameter could be subkey
162  // (when only two parameters provided) or version (when three).
163  // Until we get third parameter we consider this as subkey
164  subkey = value;
165  return true;
166  case 3:
167  // Okay, we have got third parameter, move second into version
168  ver = subkey;
169  subkey = value;
170  return true;
171  }
172 
173  return false;
174 }
175 
177  bool icache_mode, bool require_version)
178 {
179  if (!icache_mode) {
180  if (parts > 1) {
181  NCBI_THROW_FMT(CArgException, eInvalidArg,
182  "Too many positional parameters.");
183  }
184 
185  return;
186  }
187 
188  if (parts == 1) {
189  vector<string> key_parts;
190 
191  NStr::Split(key, ",", key_parts);
192  if (key_parts.size() != 3) {
193  NCBI_THROW_FMT(CArgException, eInvalidArg,
194  "Invalid ICache key specification \"" << key << "\" ("
195  "expected a comma-separated key,version,subkey triplet).");
196  }
197  key = key_parts.front();
198  ver = key_parts[1];
199  subkey = key_parts.back();
200  }
201 
202  if (!ver.empty()) {
203  version = NStr::StringToInt(ver);
204  } else if (require_version) {
205  NCBI_THROW(CArgException, eNoValue,
206  "blob version parameter is missing");
207  }
208 }
209 
211 {
212  printf("Server: %s\n", server.GetServerAddress().c_str());
213 }
214 
216 {
218 
219  try {
221 
222  if (m_APIClass == eNetCacheAPI) {
224 
227  } else {
228  CNetServer server_last_used;
229 
231  m_Opts.ncid.key,
235  nc_server_last_used = &server_last_used));
236 
237  PrintServerAddress(server_last_used);
238  }
239 
240  string line;
241 
242  if (output.ReadLine(line)) {
243  if (!NStr::StartsWith(line, "SIZE="))
244  printf("%s\n", line.c_str());
245  while (output.ReadLine(line))
246  printf("%s\n", line.c_str());
247  }
248  }
249  catch (CNetCacheException& e) {
251  throw;
252 
253  if (m_APIClass == eNetCacheAPI)
254  printf("Size: %lu\n", (unsigned long)
256  else {
257  CNetServer server_last_used;
258 
259  size_t blob_size = m_NetICacheClient.GetBlobSize(
260  m_Opts.ncid.key,
263  nc_server_last_used = &server_last_used);
264 
265  PrintServerAddress(server_last_used);
266 
267  printf("Size: %lu\n", (unsigned long) blob_size);
268  }
269  }
270 
271  return 0;
272 }
273 
275 {
276  int reader_select = IsOptionSet(ePassword, OPTION_N(1)) |
277  (m_Opts.offset != 0 || m_Opts.size != 0 ? OPTION_N(0) : 0);
278 
279  SetUp_NetCacheCmd(IsOptionSet(eCache), reader_select);
280 
281  unique_ptr<IReader> reader;
282 
283  if (m_APIClass == eNetCacheAPI) {
284  size_t blob_size = 0;
285  switch (reader_select) {
286  case 0: /* no special case */
287  reader.reset(m_NetCacheAPI.GetReader(
288  m_Opts.ncid.key,
289  &blob_size,
292  break;
293  case OPTION_N(0): /* use offset */
294  reader.reset(m_NetCacheAPI.GetPartReader(
295  m_Opts.ncid.key,
296  m_Opts.offset,
297  m_Opts.size,
298  &blob_size,
301  break;
302  case OPTION_N(1): /* use password */
303  reader.reset(m_NetCacheAPI.GetReader(
304  m_Opts.ncid.key,
305  &blob_size,
309  break;
310  case OPTION_N(1) | OPTION_N(0): /* use password and offset */
311  reader.reset(m_NetCacheAPI.GetPartReader(
312  m_Opts.ncid.key,
313  m_Opts.offset,
314  m_Opts.size,
315  &blob_size,
319  }
320  } else {
322  switch (reader_select) {
323  case 0: /* no special case */
324  reader.reset(m_Opts.ncid.HasVersion() ?
326  m_Opts.ncid.key,
329  NULL,
333  m_Opts.ncid.key,
336  &validity));
337  break;
338  case OPTION_N(0): /* use offset */
340  m_Opts.ncid.key,
343  m_Opts.offset,
344  m_Opts.size,
345  NULL,
348  break;
349  case OPTION_N(1): /* use password */
350  reader.reset(m_NetICacheClient.GetReadStream(
351  m_Opts.ncid.key,
354  NULL,
358  break;
359  case OPTION_N(1) | OPTION_N(0): /* use password and offset */
361  m_Opts.ncid.key,
364  m_Opts.offset,
365  m_Opts.size,
366  NULL,
370  }
371  if (!m_Opts.ncid.HasVersion())
372  NcbiCerr << "Blob version: " <<
374  "Blob validity: " << (validity == ICache::eCurrent ?
375  "current" : "expired") << NcbiEndl;
376  }
377  if (!reader.get()) {
378  NCBI_THROW(CNetCacheException, eBlobNotFound,
379  "Cannot find the requested blob");
380  }
381 
382  char buffer[IO_BUFFER_SIZE];
383  ERW_Result read_result;
384  size_t bytes_read;
385 
386  while ((read_result = reader->Read(buffer,
387  sizeof(buffer), &bytes_read)) == eRW_Success)
388  fwrite(buffer, 1, bytes_read, m_Opts.output_stream);
389 
390  if (read_result != eRW_Eof) {
391  ERR_POST("Error while sending data to the output stream");
392  return 1;
393  }
394 
395  return 0;
396 }
397 
399 {
401 
402  unique_ptr<IEmbeddedStreamWriter> writer;
403 
404  // Cannot use a reference here because m_Opts.ncid.key.empty() is
405  // used later to find out whether a blob was given in the
406  // command line.
407  string blob_key = m_Opts.ncid.key;
408 
409  CNetServer server_last_used;
410 
411  if (m_APIClass == eNetCacheAPI) {
412  switch (IsOptionSet(ePassword, 1) | IsOptionSet(eUseCompoundID, 2)) {
413  case 1:
414  writer.reset(m_NetCacheAPI.PutData(&blob_key,
417  break;
418  case 2:
419  writer.reset(m_NetCacheAPI.PutData(&blob_key,
421  nc_use_compound_id = true)));
422  break;
423  case 3:
424  writer.reset(m_NetCacheAPI.PutData(&blob_key,
427  nc_use_compound_id = true)));
428  break;
429  default:
430  writer.reset(m_NetCacheAPI.PutData(&blob_key,
431  nc_blob_ttl = m_Opts.ttl));
432  }
433  } else {
434  writer.reset(IsOptionSet(ePassword) ?
436  m_Opts.ncid.key,
441  nc_server_last_used = &server_last_used)) :
443  m_Opts.ncid.key,
447  nc_server_last_used = &server_last_used)));
448  }
449 
450  if (!writer.get()) {
451  NCBI_USER_THROW("Cannot create blob stream");
452  }
453 
454  if (m_APIClass != eNetCacheAPI &&
456  PrintServerAddress(server_last_used);
457 
458  size_t bytes_written;
459 
460  if (IsOptionSet(eInput)) {
461  if (writer->Write(m_Opts.input.data(), m_Opts.input.length(),
462  &bytes_written) != eRW_Success ||
463  bytes_written != m_Opts.input.length())
464  goto ErrorExit;
465  } else {
466  char buffer[IO_BUFFER_SIZE];
467 
468  do {
469  m_Opts.input_stream->read(buffer, sizeof(buffer));
470  if (m_Opts.input_stream->fail() && !m_Opts.input_stream->eof()) {
471  NCBI_USER_THROW("Error while reading from input stream");
472  }
473  size_t bytes_read = (size_t) m_Opts.input_stream->gcount();
474  if (writer->Write(buffer, bytes_read, &bytes_written) !=
475  eRW_Success || bytes_written != bytes_read)
476  goto ErrorExit;
477  } while (!m_Opts.input_stream->eof());
478  }
479 
480  writer->Close();
481 
482  if (m_APIClass == eNetCacheAPI && m_Opts.ncid.key.empty())
483  NcbiCout << blob_key << NcbiEndl;
484 
485  return 0;
486 
487 ErrorExit:
488  NCBI_USER_THROW("Error while writing to NetCache");
489 }
490 
492 {
494 
495  if (m_APIClass == eNetCacheAPI)
496  if (IsOptionSet(ePassword))
499  else
501  else {
502  if (IsOptionSet(ePassword))
506  else
509  }
510 
511  return 0;
512 }
513 
515 {
517 
519 
520  return 0;
521 }
CArgException –.
Definition: ncbiargs.hpp:120
Pool of recycled CCompoundID objects.
CCompoundIDPool m_CompoundIDPool
Definition: grid_cli.hpp:457
bool IsOptionSet(int option) const
Definition: grid_cli.hpp:421
struct CGridCommandLineInterfaceApp::SOptions m_Opts
CNetICacheClient m_NetICacheClient
Definition: grid_cli.hpp:448
CNetScheduleAPIExt m_NetScheduleAPI
Definition: grid_cli.hpp:449
void PrintServerAddress(CNetServer server)
Definition: nc_cmds.cpp:210
enum CGridCommandLineInterfaceApp::EAPIClass m_APIClass
bool IsOptionExplicitlySet(int option) const
Definition: grid_cli.hpp:436
void SetUp_NetCacheAdminCmd(EAdminCmdSeverity cmd_severity)
Definition: nc_cmds.cpp:113
CNetCacheAdmin m_NetCacheAdmin
Definition: grid_cli.hpp:447
static void PrintBlobMeta(const CNetCacheKey &key)
Definition: nc_cmds.cpp:129
Client API for NetCache server.
NetCache internal exception.
Client to NetCache server (implements ICache interface)
void StickToServer(SSocketAddress address)
string GetServerAddress() const
bool IsLoadBalanced() const
CNetServerPool GetServerPool()
CTime –.
Definition: ncbitime.hpp:296
EBlobVersionValidity
BLOB version existence and validity – from the point of view of the underlying cache implementation.
Definition: icache.hpp:274
@ eCurrent
The returned BLOB's version is considered valid.
Definition: icache.hpp:275
@ eValid
Synonym for eCurrent.
Definition: icache.hpp:277
@ fBestReliability
Usually, it's not a problem if something fails to get cached sometimes.
Definition: icache.hpp:85
char value[7]
Definition: config.c:431
Declarations of command line interface arguments and handlers.
#define CACHE_OPTION
Definition: grid_cli.hpp:71
#define OPTION_N(number)
Definition: grid_cli.hpp:286
#define IO_BUFFER_SIZE
Definition: grid_cli.hpp:145
@ eCache
Definition: grid_cli.hpp:172
@ eNetCache
Definition: grid_cli.hpp:171
@ ePassword
Definition: grid_cli.hpp:174
@ eCompatMode
Definition: grid_cli.hpp:246
@ eInput
Definition: grid_cli.hpp:163
@ eNoServerCheck
Definition: grid_cli.hpp:261
@ eEnableMirroring
Definition: grid_cli.hpp:178
@ eTryAllServers
Definition: grid_cli.hpp:179
@ eUseCompoundID
Definition: grid_cli.hpp:180
#define NETCACHE_OPTION
Definition: grid_cli.hpp:70
CNcbiRegistry & GetRWConfig(void)
Get the application's cached configuration parameters, accessible for read-write for an application's...
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
#define NCBI_USER_THROW(message)
Throw a quick-and-dirty runtime exception of type 'CException' with the given error message and error...
Definition: ncbiexpt.hpp:715
TErrCode GetErrCode(void) const
Get error code.
Definition: ncbiexpt.cpp:453
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
#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
#define nc_blob_password
Blob password.
#define nc_server_last_used
Pointer to a variable for saving the CNetServer that was last used.
#define nc_try_all_servers
Whether to run a request through all NetCache servers in the ICache service in an attempt to find the...
#define nc_server_check
For blob readers: whether to check if the primary server that stores the blob is still in service.
#define nc_caching_mode
Caching mode.
#define nc_use_compound_id
Whether to return NetCache keys in CompoundID format.
#define nc_blob_ttl
Blob life span in seconds.
CNetService GetService()
IReader * GetPartReader(const string &key, size_t offset, size_t part_size, size_t *blob_size=NULL, const CNamedParameterList *optional=NULL)
Get a pointer to the IReader interface to read a portion of the blob contents.
IReader * GetReadStream(const string &key, int version, const string &subkey, size_t *blob_size_ptr, const CNamedParameterList *optional=NULL)
Read a lengthy blob via the IReader interface.
void RemoveBlob(const string &key, int version, const string &subkey, const CNamedParameterList *optional=NULL)
CNetServerMultilineCmdOutput GetBlobInfo(const string &key, int version, const string &subkey, const CNamedParameterList *optional=NULL)
Return a CNetServerMultilineCmdOutput object for reading meta information about the specified blob.
size_t GetBlobSize(const string &blob_id, const CNamedParameterList *optional=NULL)
Returns the size of the BLOB identified by the "key" parameter.
void Remove(const string &blob_id, const CNamedParameterList *optional=NULL)
Remove BLOB by key.
IReader * GetReadStreamPart(const string &key, int version, const string &subkey, size_t offset, size_t part_size, size_t *blob_size_ptr, const CNamedParameterList *optional=NULL)
Read data from the specified blob.
CNetServerMultilineCmdOutput GetBlobInfo(const string &blob_id, const CNamedParameterList *optional=NULL)
Return a CNetServerMultilineCmdOutput object for reading meta information about the specified blob.
string PutData(const void *buf, size_t size, const CNamedParameterList *optional=NULL)
Put BLOB to server.
size_t GetBlobSize(const string &key, int version, const string &subkey, const CNamedParameterList *optional=NULL)
Returns the size of the BLOB identified by the "key", "version", and "subkey" parameters.
IEmbeddedStreamWriter * GetNetCacheWriter(const string &key, int version, const string &subkey, const CNamedParameterList *optional=NULL)
Create or update the specified blob.
void SetDefaultParameters(const CNamedParameterList *parameters)
Override defaults used by this object.
IReader * GetReader(const string &key, size_t *blob_size=NULL, const CNamedParameterList *optional=NULL)
Get a pointer to the IReader interface to read blob contents.
virtual void SetFlags(TFlags flags)
Pass flags to the underlying storage.
CNetService GetService()
void Purge(const string &cache_name)
Remove all blobs from an ICache database.
CNetCacheAdmin GetAdmin()
@ eServerError
Blob is not found.
bool Set(const string &section, const string &name, const string &value, TFlags flags=0, const string &comment=kEmptyStr)
Set the configuration parameter value.
Definition: ncbireg.cpp:826
ERW_Result
Result codes for I/O operations.
#define NcbiEndl
Definition: ncbistre.hpp:548
#define NcbiCout
Definition: ncbistre.hpp:543
#define NcbiCerr
Definition: ncbistre.hpp:544
@ eRW_Eof
End of data, should be considered permanent.
@ eRW_Success
Everything is okay, I/O completed.
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3457
static bool MatchesMask(CTempString str, CTempString mask, ECase use_case=eCase)
Match "str" against the "mask".
Definition: ncbistr.cpp:389
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5411
string AsString(const CTimeFormat &format=kEmptyStr, TSeconds out_tz=eCurrentTimeZone) const
Transform time to string.
Definition: ncbitime.cpp:1511
CTime & SetTimeT(const time_t t)
Set time using time_t time value.
Definition: ncbitime.hpp:2299
string g_NetService_TryResolveHost(const string &ip_or_hostname)
Definition: util.cpp:186
static int version
Definition: mdb_load.c:29
const struct ncbi::grid::netcache::search::fields::KEY key
const struct ncbi::grid::netcache::search::fields::SUBKEY subkey
USING_NCBI_SCOPE
Definition: nc_cmds.cpp:36
static pcre_uint8 * buffer
Definition: pcretest.c:1051
static SQLCHAR output[256]
Definition: print.c:5
void Parse(bool icache_mode, bool require_version)
Definition: nc_cmds.cpp:176
struct CGridCommandLineInterfaceApp::SOptions::SNCID ncid
Meaningful information encoded in the NetCache key.
static SSocketAddress Parse(const string &address, SHost::EName name=SHost::EName::eResolved)
Modified on Fri Dec 01 04:50:40 2023 by modify_doxy.py rev. 669887