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

Go to the SVN repository for this file.

1 /* $Id: psg_client_app.cpp 101384 2023-12-07 15:43:23Z 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 <unordered_map>
33 
34 #include <corelib/ncbiapp.hpp>
36 
37 #include "processing.hpp"
38 #include "performance.hpp"
39 
40 #include <common/test_assert.h> /* This header must go last */
41 
43 
44 class CPsgClientApp;
45 
46 struct SCommand
47 {
48  using TInit = function<void(CArgDescriptions&)>;
49  using TRun = function<int(CPsgClientApp*, const CArgs&)>;
50  enum EFlags { eDefault, fHidden = 1 << 0, fParallel = 1 << 1 };
51 
52  const string name;
53  const string desc;
57 
58  SCommand(string n, string d, TInit i, TRun r, EFlags f) : name(n), desc(d), init(i), run(r), flags(f) {}
59 };
60 
62 {
63 public:
64  CPsgClientApp();
65  virtual void Init();
66  virtual int Run();
67 
68 private:
69  template <class TRequest>
70  static SCommand s_GetCommand(string name, string desc, SCommand::EFlags flags = SCommand::eDefault);
71 
72  template <class TRequest>
73  static void s_InitRequest(CArgDescriptions& arg_desc);
74 
75  template <class TRequest>
76  static int s_RunRequest(CPsgClientApp* that, const CArgs& args) { _ASSERT(that); return that->RunRequest<TRequest>(args); }
77 
78  template <class TRequest>
79  int RunRequest(const CArgs& args);
80 
81  vector<SCommand> m_Commands;
82 };
83 
84 struct SInteractive {};
85 struct SPerformance {};
86 struct SJsonCheck {};
87 
88 void s_InitPsgOptions(CArgDescriptions& arg_desc);
89 void s_SetPsgDefaults(const CArgs& args, bool parallel);
90 
92  m_Commands({
93  s_GetCommand<CPSG_Request_Biodata> ("biodata", "Request biodata info and data by bio ID"),
94  s_GetCommand<CPSG_Request_Blob> ("blob", "Request blob by blob ID"),
95  s_GetCommand<CPSG_Request_Resolve> ("resolve", "Request biodata info by bio ID", SCommand::fParallel),
96  s_GetCommand<CPSG_Request_NamedAnnotInfo>("named_annot", "Request named annotations info by bio ID(s)"),
97  s_GetCommand<CPSG_Request_Chunk> ("chunk", "Request blob data chunk by chunk ID"),
98  s_GetCommand<CPSG_Request_IpgResolve> ("ipg_resolve", "Request IPG info"),
99  s_GetCommand<SInteractive> ("interactive", "Interactive JSON-RPC mode", SCommand::fParallel),
100  s_GetCommand<SPerformance> ("performance", "Performance testing", SCommand::fHidden),
101  s_GetCommand<SJsonCheck> ("json_check", "JSON document validate", SCommand::fHidden),
102  })
103 {
104 }
105 
107 {
109  unique_ptr<CCommandArgDescriptions> cmd_desc(new CCommandArgDescriptions(true, nullptr, kFlags));
110 
111  cmd_desc->SetUsageContext(GetArguments().GetProgramBasename(), "PSG client");
112 
113  for (const auto& command : m_Commands) {
114  unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions());
115  arg_desc->SetUsageContext("", command.desc);
116  s_InitPsgOptions(*arg_desc);
117  command.init(*arg_desc);
118  const auto hidden = command.flags & SCommand::fHidden;
120  cmd_desc->AddCommand(command.name, arg_desc.release(), kEmptyStr, flags);
121  }
122 
123  SetupArgDescriptions(cmd_desc.release());
124 }
125 
127 {
128  const auto& args = GetArgs();
129  auto name = args.GetCommand();
130 
131  for (const auto& command : m_Commands) {
132  if (command.name == name) {
133  const bool parallel = command.flags & SCommand::fParallel;
134  s_SetPsgDefaults(args, parallel);
135  return command.run(this, args);
136  }
137  }
138 
139  NCBI_THROW(CArgException, eNoArg, "Command is required");
140  return -1;
141 }
142 
144 {
145  const auto& data_flags = SRequestBuilder::GetDataFlags();
146 
147  for (auto i = data_flags.begin(); i != data_flags.end(); ++i) {
148  arg_desc.AddFlag(i->name, i->desc);
149 
150  for (auto j = i + 1; j != data_flags.end(); ++j) {
151  if (i->name != j->name) arg_desc.SetDependency(i->name, CArgDescriptions::eExcludes, j->name);
152  }
153  }
154 }
155 
157 {
158  auto names = { "First", "Last", "All" };
159  auto option = [](string name) { return NStr::ToLower(name) + "-latency"; };
160 
161  for (string name : names) {
162  arg_desc.AddFlag(option(name), name + " latency output", CArgDescriptions::eFlagHasValueIfSet, CArgDescriptions::fHidden);
163 
164  for (string excluded : names) {
165  if (name != excluded) {
166  arg_desc.SetDependency(option(name), CArgDescriptions::eExcludes, option(excluded));
167  }
168  }
169  }
170 
171  arg_desc.AddAlias("latency", "last-latency");
172 }
173 
175 {
176  arg_desc.AddOptionalKey("service", "SERVICE", "PSG service name or host:port pair", CArgDescriptions::eString);
177  arg_desc.AddOptionalKey("io-threads", "THREADS_NUM", "Number of I/O threads", CArgDescriptions::eInteger, CArgDescriptions::fHidden);
178  arg_desc.AddOptionalKey("requests-per-io", "REQUESTS_NUM", "Number of requests to submit consecutively per I/O thread", CArgDescriptions::eInteger, CArgDescriptions::fHidden);
179  arg_desc.AddOptionalKey("max-streams", "REQUESTS_NUM", "Maximum number of concurrent streams per I/O thread", CArgDescriptions::eInteger, CArgDescriptions::fHidden);
180  arg_desc.AddOptionalKey("use-cache", "USE_CACHE", "Whether to use LMDB cache (no|yes|default)", CArgDescriptions::eString);
181  arg_desc.AddOptionalKey("timeout", "SECONDS", "Set request timeout (in seconds)", CArgDescriptions::eInteger);
182  arg_desc.AddOptionalKey("debug-printout", "WHAT", "Debug printout of PSG protocol (some|all).", CArgDescriptions::eString, CArgDescriptions::fHidden);
183  arg_desc.AddOptionalKey("user-args", "USER_ARGS", "Arbitrary request URL arguments (queue-wide)", CArgDescriptions::eString);
184  arg_desc.AddDefaultKey("min-severity", "SEVERITY", "Minimum severity level of messages to output", CArgDescriptions::eString, "Warning");
185  arg_desc.AddFlag("include-hup", "Include HUP data");
186  arg_desc.AddFlag("https", "Enable HTTPS");
187  s_AddLatencyOptions(arg_desc);
188  arg_desc.AddFlag("verbose", "Verbose output");
189 }
190 
191 void s_InitDataOnly(CArgDescriptions& arg_desc, bool blob_only = true)
192 {
193  const auto name = blob_only ? "blob-only" : "annot-only";
194  const auto comment = blob_only ? "Output blob data only" : "Output annot info only";
195  arg_desc.AddFlag(name, comment);
196  arg_desc.AddOptionalKey("output-fmt", "FORMAT", "Format for blob data to return in (instead of raw data)", CArgDescriptions::eString);
197  arg_desc.SetConstraint("output-fmt", new CArgAllow_Strings{"asn", "asnb", "xml", "json"});
198  arg_desc.SetDependency("output-fmt", CArgDescriptions::eRequires, name);
199 }
200 
201 template <class TRequest>
203 {
204  arg_desc.AddOptionalKey("exclude-blob", "BLOB_ID", "Exclude blob by its ID", CArgDescriptions::eString, CArgDescriptions::fAllowMultiple);
205  arg_desc.AddPositional("ID", "ID part of Bio ID", CArgDescriptions::eString);
206  arg_desc.AddOptionalKey("type", "TYPE", "Type part of bio ID", CArgDescriptions::eString);
207  arg_desc.AddOptionalKey("acc-substitution", "ACC_SUB", "ACC substitution", CArgDescriptions::eString);
208  arg_desc.AddFlag("no-bio-id-resolution", "Do not try to resolve provided bio ID(s) before use");
209  s_InitDataOnly(arg_desc);
210  s_InitDataFlags(arg_desc);
211 }
212 
213 template <>
214 void CPsgClientApp::s_InitRequest<CPSG_Request_Resolve>(CArgDescriptions& arg_desc)
215 {
216  arg_desc.AddOptionalPositional("ID", "Bio ID", CArgDescriptions::eString);
217  arg_desc.AddDefaultKey("input-file", "FILENAME", "File containing bio IDs to resolve (one per line)", CArgDescriptions::eInputFile, "-");
218  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "ID");
219  arg_desc.AddAlias("id-file", "input-file");
220  arg_desc.AddFlag("server-mode", "Output one response per line");
221  arg_desc.SetDependency("server-mode", CArgDescriptions::eExcludes, "ID");
222  arg_desc.AddOptionalKey("type", "TYPE", "Type of bio ID(s)", CArgDescriptions::eString);
223  arg_desc.AddOptionalKey("acc-substitution", "ACC_SUB", "ACC substitution", CArgDescriptions::eString);
224  arg_desc.AddFlag("no-bio-id-resolution", "Do not try to resolve provided bio ID(s) before use");
225  arg_desc.AddDefaultKey("rate", "RATE", "Maximum number of requests to submit per second", CArgDescriptions::eInteger, "0");
226  arg_desc.AddDefaultKey("worker-threads", "THREADS_CONF", "Numbers of worker threads of each type", CArgDescriptions::eInteger, "7", CArgDescriptions::fHidden);
227 
228  for (const auto& f : SRequestBuilder::GetInfoFlags()) {
229  arg_desc.AddFlag(f.name, f.desc);
230  }
231 }
232 
233 template <>
234 void CPsgClientApp::s_InitRequest<CPSG_Request_Blob>(CArgDescriptions& arg_desc)
235 {
236  arg_desc.AddPositional("ID", "Blob ID", CArgDescriptions::eString);
237  arg_desc.AddOptionalKey("last-modified", "LAST_MODIFIED", "LastModified", CArgDescriptions::eInt8);
238  s_InitDataOnly(arg_desc);
239  s_InitDataFlags(arg_desc);
240 }
241 
242 template <>
243 void CPsgClientApp::s_InitRequest<CPSG_Request_NamedAnnotInfo>(CArgDescriptions& arg_desc)
244 {
245  arg_desc.AddKey("na", "NAMED_ANNOT", "Named annotation", CArgDescriptions::eString, CArgDescriptions::fAllowMultiple);
246  arg_desc.AddExtra(1, kMax_UInt, "Bio ID(s)", CArgDescriptions::eString);
247  arg_desc.AddOptionalKey("type", "TYPE", "Type of the first bio ID", CArgDescriptions::eString);
248  arg_desc.AddOptionalKey("acc-substitution", "ACC_SUB", "ACC substitution", CArgDescriptions::eString);
249  arg_desc.AddFlag("no-bio-id-resolution", "Do not try to resolve provided bio ID(s) before use");
250  arg_desc.AddOptionalKey("snp-scale-limit", "LIMIT", "SNP scale limit", CArgDescriptions::eString);
251  arg_desc.SetConstraint("snp-scale-limit", new CArgAllow_Strings{"unit", "contig", "supercontig", "chromosome"});
252  s_InitDataOnly(arg_desc, false);
253  s_InitDataFlags(arg_desc);
254 }
255 
256 template <>
257 void CPsgClientApp::s_InitRequest<CPSG_Request_Chunk>(CArgDescriptions& arg_desc)
258 {
259  arg_desc.AddPositional("ID2_CHUNK", "ID2 chunk number", CArgDescriptions::eInteger);
260  arg_desc.AddPositional("ID2_INFO", "ID2 info", CArgDescriptions::eString);
261  s_InitDataOnly(arg_desc);
262 }
263 
264 template <>
265 void CPsgClientApp::s_InitRequest<CPSG_Request_IpgResolve>(CArgDescriptions& arg_desc)
266 {
267  arg_desc.AddOptionalKey("protein", "PROTEIN", "Protein", CArgDescriptions::eString);
268  arg_desc.AddOptionalKey("ipg", "IPG", "IPG", CArgDescriptions::eInt8);
269  arg_desc.AddOptionalKey("nucleotide", "NUCLEOTIDE", "Nucleotide", CArgDescriptions::eString);
270  arg_desc.AddDefaultKey("input-file", "FILENAME", "File containing proteins to resolve (one 'protein[,nucleotide]' per line)", CArgDescriptions::eInputFile, "-");
271  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "protein");
272  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "ipg");
273  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "nucleotide");
274  arg_desc.AddFlag("server-mode", "Output one response per line");
275  arg_desc.AddDefaultKey("rate", "RATE", "Maximum number of requests to submit per second", CArgDescriptions::eInteger, "0");
276  arg_desc.AddDefaultKey("worker-threads", "THREADS_CONF", "Numbers of worker threads of each type", CArgDescriptions::eInteger, "7", CArgDescriptions::fHidden);
277 }
278 
279 template<>
280 void CPsgClientApp::s_InitRequest<SInteractive>(CArgDescriptions& arg_desc)
281 {
282  arg_desc.AddDefaultKey("input-file", "FILENAME", "File containing JSON-RPC requests (one per line)", CArgDescriptions::eInputFile, "-");
283  arg_desc.AddOptionalKey("data-limit", "SIZE", "Show a data preview for any data larger the limit (if set)", CArgDescriptions::eDataSize);
284  arg_desc.AddDefaultKey("preview-size", "SIZE", "How much of data to show as the preview", CArgDescriptions::eDataSize, "16");
285  arg_desc.AddFlag("server-mode", "Output one JSON-RPC response per line and always output reply statuses");
286  arg_desc.AddFlag("echo", "Echo all incoming requests");
287  arg_desc.AddFlag("one-server", "Use only one server from the service", CArgDescriptions::eFlagHasValueIfSet, CArgDescriptions::fHidden);
288  arg_desc.AddFlag("testing", "Testing mode adjustments", CArgDescriptions::eFlagHasValueIfSet, CArgDescriptions::fHidden);
289  arg_desc.AddDefaultKey("rate", "RATE", "Maximum number of requests to submit per second", CArgDescriptions::eInteger, "0");
290  arg_desc.AddDefaultKey("worker-threads", "THREADS_CONF", "Numbers of worker threads of each type", CArgDescriptions::eInteger, "7", CArgDescriptions::fHidden);
291  arg_desc.SetDependency("preview-size", CArgDescriptions::eRequires, "data-limit");
292 }
293 
294 template <>
295 void CPsgClientApp::s_InitRequest<SPerformance>(CArgDescriptions& arg_desc)
296 {
297  arg_desc.AddDefaultKey("user-threads", "THREADS_NUM", "Number of user threads", CArgDescriptions::eInteger, "1");
298  arg_desc.AddDefaultKey("delay", "SECONDS", "Delay between consecutive requests (in seconds)", CArgDescriptions::eDouble, "0.0");
299  arg_desc.AddFlag("local-queue", "Whether user threads to use separate queues");
300  arg_desc.AddFlag("report-immediately", "Whether to report metrics immediately (or at the end)");
301  arg_desc.AddDefaultKey("output-file", "FILENAME", "Output file to contain raw performance metrics", CArgDescriptions::eOutputFile, "-");
302 }
303 
304 template <>
305 void CPsgClientApp::s_InitRequest<SJsonCheck>(CArgDescriptions& arg_desc)
306 {
307  arg_desc.AddOptionalKey("schema-file", "FILENAME", "JSON-RPC schema file (built-in by default)", CArgDescriptions::eInputFile);
308  arg_desc.AddDefaultKey("input-file", "FILENAME", "JSON-RPC requests file (one per line)", CArgDescriptions::eInputFile, "-");
309 }
310 
311 void s_SetPsgDefaults(const CArgs& args, bool parallel)
312 {
314 
315  if (args["io-threads"].HasValue()) {
316  auto io_threads = args["io-threads"].AsInteger();
317  TPSG_NumIo::SetDefault(io_threads);
318  }
319 
320  if (args["requests-per-io"].HasValue()) {
321  auto requests_per_io = args["requests-per-io"].AsInteger();
322  TPSG_RequestsPerIo::SetDefault(requests_per_io);
323  } else if (parallel) {
325  }
326 
327  if (args["max-streams"].HasValue()) {
328  auto max_streams = args["max-streams"].AsInteger();
329  TPSG_MaxConcurrentStreams::SetDefault(max_streams);
330  }
331 
332  if (args["use-cache"].HasValue()) {
333  auto use_cache = args["use-cache"].AsString();
334  TPSG_UseCache::SetDefault(use_cache);
335  }
336 
337  if (args["timeout"].HasValue()) {
338  auto timeout = args["timeout"].AsInteger();
339  TPSG_RequestTimeout::SetDefault(timeout);
340  }
341 
342  if (args["https"].HasValue()) {
343  TPSG_Https::SetDefault(true);
344  }
345 
346  if (args["debug-printout"].HasValue()) {
347  auto debug_printout = args["debug-printout"].AsString();
348  TPSG_DebugPrintout::SetDefault(debug_printout);
349  }
350 }
351 
352 namespace NParamsBuilder
353 {
354 
355 template <class TParams>
356 struct SBase : TParams
357 {
358  template <class... TInitArgs>
359  SBase(const CArgs& args, TInitArgs&&... init_args) :
360  TParams{
361  args["service"].HasValue() ? args["service"].AsString() : string(),
362  args["include-hup"].HasValue() ? CPSG_Request::fIncludeHUP : CPSG_Request::eDefaultFlags,
363  args["user-args"].HasValue() ? args["user-args"].AsString() : SPSG_UserArgs(),
364  std::forward<TInitArgs>(init_args)...
365  }
366  {
367  if (!CNcbiDiag::StrToSeverityLevel(args["min-severity"].AsString().c_str(), TParams::min_severity)) {
368  TParams::min_severity = eDiag_Warning;
369  }
370 
371  TParams::verbose = args["verbose"].HasValue();
372  }
373 };
374 
375 struct SOneRequest : SBase<SOneRequestParams>
376 {
377  SOneRequest(const CArgs& args) :
378  SBase{
379  args,
380  GetLatency(args),
381  args["debug-printout"].HasValue(),
382  GetDataOnlyEnabled(args),
383  false,
385  }
386  {
387  }
388 
390  {
391  if (args["first-latency"].HasValue()) return CLogLatencies::eFirst;
392  if (args["last-latency"].HasValue()) return CLogLatencies::eLast;
393  if (args["all-latency"].HasValue()) return CLogLatencies::eAll;
394  return CLogLatencies::eOff;
395  }
396 
397  static bool GetDataOnlyEnabled(const CArgs& args)
398  {
399  return (args.Exist("blob-only") && args["blob-only"].HasValue()) ||
400  (args.Exist("annot-only") && args["annot-only"].HasValue());
401  }
402 
404  {
405  if (args.Exist("output-fmt") && args["output-fmt"].HasValue()) {
406  const auto& format = args["output-fmt"].AsString();
407 
408  if (format == "asn") return eSerial_AsnText;
409  if (format == "asnb") return eSerial_AsnBinary;
410  if (format == "xml") return eSerial_Xml;
411  if (format == "json") return eSerial_Json;
412  }
413 
414  return eSerial_None;
415  }
416 
417 };
418 
419 template <class TParams>
421 {
422  template <class... TInitArgs>
423  SParallelProcessing(const CArgs& args, TInitArgs&&... init_args) :
424  SBase<TParams>{
425  args,
426  args["rate"].AsInteger(),
427  max(1, min(10, args["worker-threads"].AsInteger())),
428  args["input-file"].AsString() == "-",
429  args["server-mode"].AsBoolean(),
430  std::forward<TInitArgs>(init_args)...
431  },
432  SIoRedirector(cin, args["input-file"].AsInputFile())
433  {
434  }
435 };
436 
437 struct SBatchResolve : SParallelProcessing<SBatchResolveParams>
438 {
439  SBatchResolve(const CArgs& args) :
441  args,
443  }
444  {
445  }
446 };
447 
449 
450 struct SInteractive : SParallelProcessing<SInteractiveParams>
451 {
452  SInteractive(const CArgs& args) :
454  args,
455  GetDataLimit(args["data-limit"]),
456  static_cast<size_t>(args["preview-size"].AsInt8()),
457  args["echo"].HasValue(),
458  args["one-server"].HasValue(),
459  args["testing"].HasValue()
460  }
461  {
462  }
463 
464  static size_t GetDataLimit(const CArgValue& value)
465  {
466  return value.HasValue() ? static_cast<size_t>(value.AsInt8()) : numeric_limits<size_t>::max();
467  }
468 };
469 
470 struct SPerformance : SBase<SPerformanceParams>, SIoRedirector
471 {
472  SPerformance(const CArgs& args) :
474  args,
475  static_cast<size_t>(args["user-threads"].AsInteger()),
476  args["delay"].AsDouble(),
477  args["local-queue"].AsBoolean(),
478  args["report-immediately"].AsBoolean(),
479  },
480  SIoRedirector(cout, args["output-file"].AsOutputFile())
481  {
482  }
483 };
484 
485 }
486 
487 template <>
489 {
490  const CArgs& input;
491 
492  SReader(const CArgs& i) : input(i) {}
493 
494  TSpecified GetSpecified() const;
495  auto GetBioIdType() const { return input["type"].HasValue() ? SRequestBuilder::GetBioIdType(input["type"].AsString()) : CPSG_BioId::TType(); }
496  CPSG_BioId GetBioId() const { return { input["ID"].AsString(), GetBioIdType() }; }
497  CPSG_BioIds GetBioIds() const;
498  CPSG_BlobId GetBlobId() const;
499  CPSG_ChunkId GetChunkId() const;
500  vector<string> GetNamedAnnots() const { return input["na"].GetStringList(); }
501  auto GetAccSubstitution() const { return input["acc-substitution"].HasValue() ? SRequestBuilder::GetAccSubstitution(input["acc-substitution"].AsString()) : EPSG_AccSubstitution::Default; }
504  void ForEachTSE(TExclude exclude) const;
505  auto GetProtein() const { return input["protein"].HasValue() ? input["protein"].AsString() : string(); }
506  auto GetIpg() const { return input["ipg"].HasValue() ? input["ipg"].AsInt8() : 0; }
507  auto GetNucleotide() const { return input["nucleotide"].HasValue() ? CPSG_Request_IpgResolve::TNucleotide(input["nucleotide"].AsString()) : null; }
508  auto GetSNPScaleLimit() const { return input["snp-scale-limit"].HasValue() ? objects::CSeq_id::GetSNPScaleLimit_Value(input["snp-scale-limit"].AsString()) : CPSG_Request_NamedAnnotInfo::ESNPScaleLimit::eSNPScaleLimit_Default; }
509  void SetRequestFlags(shared_ptr<CPSG_Request> request) const;
510  SPSG_UserArgs GetUserArgs() const { return input["user-args"].HasValue() ? input["user-args"].AsString() : SPSG_UserArgs(); }
511 };
512 
514 {
515  return [&](const string& name) {
516  return input[name].HasValue();
517  };
518 }
519 
521 {
522  const size_t n = input.GetNExtra();
523 
524  CPSG_BioIds rv;
525 
526  for (size_t i = 1; i <= n; ++i) {
527  if (i == 1) {
528  rv.emplace_back(input[i].AsString(), GetBioIdType());
529  } else {
530  rv.emplace_back(input[i].AsString());
531  }
532  }
533 
534  return rv;
535 }
536 
538 {
539  const auto& id = input["ID"].AsString();
540  const auto& last_modified = input["last-modified"];
541  return last_modified.HasValue() ? CPSG_BlobId(id, last_modified.AsInt8()) : id;
542 }
543 
545 {
546  return { input["ID2_CHUNK"].AsInteger(), input["ID2_INFO"].AsString() };
547 }
548 
550 {
551  if (!input["exclude-blob"].HasValue()) return;
552 
553  auto blob_ids = input["exclude-blob"].GetStringList();
554 
555  for (const auto& blob_id : blob_ids) {
556  exclude(blob_id);
557  }
558 }
559 
560 void SRequestBuilder::SReader<CArgs>::SetRequestFlags(shared_ptr<CPSG_Request> request) const
561 {
562  if (input["include-hup"].HasValue()) {
563  request->SetFlags(CPSG_Request::fIncludeHUP);
564  }
565 }
566 
567 template <class TRequest>
569 {
570  auto request = SRequestBuilder::Build<TRequest>(args);
572 }
573 
574 template<>
575 int CPsgClientApp::RunRequest<CPSG_Request_Resolve>(const CArgs& args)
576 {
577  const auto single_request = args["ID"].HasValue();
578 
579  if (single_request) {
580  auto request = SRequestBuilder::Build<CPSG_Request_Resolve>(args);
582  } else {
584  }
585 }
586 
587 template<>
588 int CPsgClientApp::RunRequest<CPSG_Request_IpgResolve>(const CArgs& args)
589 {
590  const auto single_request = args["protein"].HasValue() || args["ipg"].HasValue() || args["nucleotide"].HasValue();
591 
592  if (single_request) {
593  auto request = SRequestBuilder::Build<CPSG_Request_IpgResolve>(args);
595  } else {
597  }
598 }
599 
600 template<>
601 int CPsgClientApp::RunRequest<SInteractive>(const CArgs& args)
602 {
603  NParamsBuilder::SInteractive params_builder(args);
604 
605  if (params_builder.testing) {
606  GetRWConfig().SetValue("log", "issued_subhit_limit", 0);
607  }
608 
609  return CProcessing::ParallelProcessing(params_builder);
610 }
611 
612 template <>
613 int CPsgClientApp::RunRequest<SPerformance>(const CArgs& args)
614 {
617 }
618 
619 template <>
620 int CPsgClientApp::RunRequest<SJsonCheck>(const CArgs& args)
621 {
622  const auto& schema = args["schema-file"];
623  SIoRedirector ior(cin, args["input-file"].AsInputFile());
624  return CProcessing::JsonCheck(schema.HasValue() ? &schema.AsInputFile() : nullptr);
625 }
626 
627 template <class TRequest>
629 {
630  return { std::move(name), std::move(desc), s_InitRequest<TRequest>, s_RunRequest<TRequest>, flags };
631 }
632 
633 int main(int argc, const char* argv[])
634 {
635  return CPsgClientApp().AppMain(argc, argv);
636 }
static const NStr::TNumToStringFlags kFlags
CArgAllow_Strings –.
Definition: ncbiargs.hpp:1641
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CArgException –.
Definition: ncbiargs.hpp:120
CArgValue –.
Definition: ncbiargs.hpp:184
CArgs –.
Definition: ncbiargs.hpp:379
CCommandArgDescriptions –.
Definition: ncbiargs.hpp:1381
Bio-id (such as accession)
Definition: psg_client.hpp:175
CSeq_id::E_Choice TType
Definition: psg_client.hpp:178
Blob unique ID.
Definition: psg_client.hpp:226
Chunk unique ID.
Definition: psg_client.hpp:265
CNullable< string > TNucleotide
Definition: psg_client.hpp:600
Request to the PSG server (see "CPSG_Request_*" below)
Definition: psg_client.hpp:100
static int JsonCheck(istream *schema_is)
static int OneRequest(const SOneRequestParams &params, shared_ptr< CPSG_Request > request)
Definition: processing.cpp:810
static int ParallelProcessing(const TParams &params, istream &is=cin)
Definition: processing.hpp:349
static int Performance(const SPerformanceParams &params)
static SCommand s_GetCommand(string name, string desc, SCommand::EFlags flags=SCommand::eDefault)
int RunRequest(const CArgs &args)
static void s_InitRequest(CArgDescriptions &arg_desc)
virtual int Run()
Run the application.
static int s_RunRequest(CPsgClientApp *that, const CArgs &args)
virtual void Init()
Initialize the application.
vector< SCommand > m_Commands
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
static uch flags
static const struct name_t names[]
#define false
Definition: bool.h:36
static const char * schema
Definition: stats.c:20
#define option
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments.
Definition: ncbiapp.cpp:305
int AppMain(int argc, const char *const *argv, const char *const *envp=0, EAppDiagStream diag=eDS_Default, const char *conf=NcbiEmptyCStr, const string &name=NcbiEmptyString)
Main function (entry point) for the NCBI application.
Definition: ncbiapp.cpp:819
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: ncbiapp.cpp:1195
const CNcbiArguments & GetArguments(void) const
Get the application's cached unprocessed command-line arguments.
void AddFlag(const string &name, const string &comment, CBoolEnum< EFlagValue > set_value=eFlagHasValueIfSet, TFlags flags=0)
Add description for flag argument.
Definition: ncbiargs.cpp:2459
void AddExtra(unsigned n_mandatory, unsigned n_optional, const string &comment, EType type, TFlags flags=0)
Add description for the extra, unnamed positional arguments.
Definition: ncbiargs.cpp:2528
void SetConstraint(const string &name, const CArgAllow *constraint, EConstraintNegate negate=eConstraint)
Set additional user defined constraint on argument value.
Definition: ncbiargs.cpp:2591
void SetDependency(const string &arg1, EDependency dep, const string &arg2)
Define a dependency.
Definition: ncbiargs.cpp:2618
bool Exist(const string &name) const
Check existence of argument description.
Definition: ncbiargs.cpp:1813
void AddKey(const string &name, const string &synopsis, const string &comment, EType type, TFlags flags=0)
Add description for mandatory key.
Definition: ncbiargs.cpp:2412
void AddAlias(const string &alias, const string &arg_name)
Add argument alias.
Definition: ncbiargs.cpp:2557
void AddPositional(const string &name, const string &comment, EType type, TFlags flags=0)
Add description for mandatory positional argument.
Definition: ncbiargs.cpp:2471
void AddOptionalKey(const string &name, const string &synopsis, const string &comment, EType type, TFlags flags=0)
Add description for optional key without default value.
Definition: ncbiargs.cpp:2427
void AddOptionalPositional(const string &name, const string &comment, EType type, TFlags flags=0)
Add description for optional positional argument without default value.
Definition: ncbiargs.cpp:2497
void AddDefaultKey(const string &name, const string &synopsis, const string &comment, EType type, const string &default_value, TFlags flags=0, const string &env_var=kEmptyStr, const char *display_value=nullptr)
Add description for optional key with default value.
Definition: ncbiargs.cpp:2442
@ fAllowMultiple
Repeated key arguments are legal (use with AddKey)
Definition: ncbiargs.hpp:635
@ fHidden
Hide it in Usage.
Definition: ncbiargs.hpp:662
@ eHidden
Hide command in Usage.
Definition: ncbiargs.hpp:1411
@ eRequires
One argument requires another.
Definition: ncbiargs.hpp:956
@ eExcludes
One argument excludes another.
Definition: ncbiargs.hpp:957
@ eNoSortCommands
On PrintUsage, keep commands unsorted.
Definition: ncbiargs.hpp:1387
@ eCommandOptional
Command is not necessary.
Definition: ncbiargs.hpp:1386
@ eInt8
Convertible into an integer number (Int8 only)
Definition: ncbiargs.hpp:591
@ eInputFile
Name of file (must exist and be readable)
Definition: ncbiargs.hpp:595
@ eDouble
Convertible into a floating point number (double)
Definition: ncbiargs.hpp:594
@ eDataSize
Integer number with possible "software" qualifiers (KB, KiB, et al)
Definition: ncbiargs.hpp:599
@ eString
An arbitrary string.
Definition: ncbiargs.hpp:589
@ eOutputFile
Name of file (must be writable)
Definition: ncbiargs.hpp:596
@ eInteger
Convertible into an integer number (int or Int8)
Definition: ncbiargs.hpp:592
string
Definition: cgiapp.hpp:687
static bool StrToSeverityLevel(const char *str_sev, EDiagSev &sev)
Get severity from string.
Definition: ncbidiag.cpp:7904
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
#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
ESerialDataFormat
Data file format.
Definition: serialdef.hpp:71
@ eSerial_AsnText
ASN.1 text.
Definition: serialdef.hpp:73
@ eSerial_Xml
XML.
Definition: serialdef.hpp:75
@ eSerial_Json
JSON.
Definition: serialdef.hpp:76
@ eSerial_None
Definition: serialdef.hpp:72
@ eSerial_AsnBinary
ASN.1 binary.
Definition: serialdef.hpp:74
#define kMax_UInt
Definition: ncbi_limits.h:185
#define kEmptyStr
Definition: ncbistr.hpp:123
static string & ToLower(string &str)
Convert string to lower case – string& version.
Definition: ncbistr.cpp:405
@ eDefault
Default timeout (to be interpreted by the client code)
Definition: ncbitime.hpp:1698
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
static int input()
int i
yy_size_t n
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
const char * command
T max(T x_, T y_)
T min(T x_, T y_)
static Format format
Definition: njn_ioutil.cpp:53
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
true_type verbose
Definition: processing.cpp:890
@ Default
Substitute always (default)
vector< CPSG_BioId > CPSG_BioIds
Definition: psg_client.hpp:206
EPSG_BioIdResolution
Whether to try to resolve provided seq-ids before use.
Definition: psg_client.hpp:299
@ Resolve
Try to resolve provided seq-ids.
@ NoResolve
Use provided seq-ids as is.
void s_AddLatencyOptions(CArgDescriptions &arg_desc)
void s_InitPsgOptions(CArgDescriptions &arg_desc)
void s_InitDataOnly(CArgDescriptions &arg_desc, bool blob_only=true)
void s_InitDataFlags(CArgDescriptions &arg_desc)
void s_SetPsgDefaults(const CArgs &args, bool parallel)
int main(int argc, const char *argv[])
USING_NCBI_SCOPE
SBase(const CArgs &args, TInitArgs &&... init_args)
SBatchResolve(const CArgs &args)
SInteractive(const CArgs &args)
static size_t GetDataLimit(const CArgValue &value)
CLogLatencies::EWhich GetLatency(const CArgs &args)
static ESerialDataFormat GetDataOnlyOutputFormat(const CArgs &args)
SOneRequest(const CArgs &args)
static bool GetDataOnlyEnabled(const CArgs &args)
SParallelProcessing(const CArgs &args, TInitArgs &&... init_args)
SPerformance(const CArgs &args)
const string name
const string desc
SCommand(string n, string d, TInit i, TRun r, EFlags f)
function< void(CArgDescriptions &)> TInit
function< int(CPsgClientApp *, const CArgs &)> TRun
EFlags flags
const bool testing
Definition: processing.hpp:246
SIoRedirector(ios &what, ios &to)
static void SetImplicitDefault(const T &value)
Definition: misc.hpp:228
Arbitrary request URL arguments.
Definition: psg_client.hpp:79
vector< string > GetNamedAnnots() const
EPSG_BioIdResolution GetBioIdResolution() const
static CPSG_BioId::TType GetBioIdType(const string &type)
function< void(string)> TExclude
Definition: processing.hpp:404
static EPSG_AccSubstitution GetAccSubstitution(const string &acc_substitution)
Definition: processing.hpp:631
static SResolveParams GetResolveParams(const TInput &input)
Definition: processing.hpp:495
static const initializer_list< SInfoFlag > & GetInfoFlags()
static const initializer_list< SDataFlag > & GetDataFlags()
function< bool(const string &)> TSpecified
Definition: processing.hpp:403
#define _ASSERT
Modified on Mon Apr 22 04:02:54 2024 by modify_doxy.py rev. 669887