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 101212 2023-11-16 16:09:11Z 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.AddFlag("include-hup", "Include HUP data");
185  arg_desc.AddFlag("https", "Enable HTTPS");
186  s_AddLatencyOptions(arg_desc);
187  arg_desc.AddFlag("verbose", "Verbose output");
188 }
189 
190 void s_InitDataOnly(CArgDescriptions& arg_desc, bool blob_only = true)
191 {
192  const auto name = blob_only ? "blob-only" : "annot-only";
193  const auto comment = blob_only ? "Output blob data only" : "Output annot info only";
194  arg_desc.AddFlag(name, comment);
195  arg_desc.AddOptionalKey("output-fmt", "FORMAT", "Format for blob data to return in (instead of raw data)", CArgDescriptions::eString);
196  arg_desc.SetConstraint("output-fmt", new CArgAllow_Strings{"asn", "asnb", "xml", "json"});
197  arg_desc.SetDependency("output-fmt", CArgDescriptions::eRequires, name);
198 }
199 
200 template <class TRequest>
202 {
203  arg_desc.AddOptionalKey("exclude-blob", "BLOB_ID", "Exclude blob by its ID", CArgDescriptions::eString, CArgDescriptions::fAllowMultiple);
204  arg_desc.AddPositional("ID", "ID part of Bio ID", CArgDescriptions::eString);
205  arg_desc.AddOptionalKey("type", "TYPE", "Type part of bio ID", CArgDescriptions::eString);
206  arg_desc.AddOptionalKey("acc-substitution", "ACC_SUB", "ACC substitution", CArgDescriptions::eString);
207  arg_desc.AddFlag("no-bio-id-resolution", "Do not try to resolve provided bio ID(s) before use");
208  s_InitDataOnly(arg_desc);
209  s_InitDataFlags(arg_desc);
210 }
211 
212 template <>
213 void CPsgClientApp::s_InitRequest<CPSG_Request_Resolve>(CArgDescriptions& arg_desc)
214 {
215  arg_desc.AddOptionalPositional("ID", "Bio ID", CArgDescriptions::eString);
216  arg_desc.AddDefaultKey("input-file", "FILENAME", "File containing bio IDs to resolve (one per line)", CArgDescriptions::eInputFile, "-");
217  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "ID");
218  arg_desc.AddAlias("id-file", "input-file");
219  arg_desc.AddFlag("server-mode", "Output one response per line");
220  arg_desc.SetDependency("server-mode", CArgDescriptions::eExcludes, "ID");
221  arg_desc.AddOptionalKey("type", "TYPE", "Type of bio ID(s)", CArgDescriptions::eString);
222  arg_desc.AddOptionalKey("acc-substitution", "ACC_SUB", "ACC substitution", CArgDescriptions::eString);
223  arg_desc.AddFlag("no-bio-id-resolution", "Do not try to resolve provided bio ID(s) before use");
224  arg_desc.AddDefaultKey("rate", "RATE", "Maximum number of requests to submit per second", CArgDescriptions::eInteger, "0");
225  arg_desc.AddDefaultKey("worker-threads", "THREADS_CONF", "Numbers of worker threads of each type", CArgDescriptions::eInteger, "7", CArgDescriptions::fHidden);
226 
227  for (const auto& f : SRequestBuilder::GetInfoFlags()) {
228  arg_desc.AddFlag(f.name, f.desc);
229  }
230 }
231 
232 template <>
233 void CPsgClientApp::s_InitRequest<CPSG_Request_Blob>(CArgDescriptions& arg_desc)
234 {
235  arg_desc.AddPositional("ID", "Blob ID", CArgDescriptions::eString);
236  arg_desc.AddOptionalKey("last-modified", "LAST_MODIFIED", "LastModified", CArgDescriptions::eInt8);
237  s_InitDataOnly(arg_desc);
238  s_InitDataFlags(arg_desc);
239 }
240 
241 template <>
242 void CPsgClientApp::s_InitRequest<CPSG_Request_NamedAnnotInfo>(CArgDescriptions& arg_desc)
243 {
244  arg_desc.AddKey("na", "NAMED_ANNOT", "Named annotation", CArgDescriptions::eString, CArgDescriptions::fAllowMultiple);
245  arg_desc.AddExtra(1, kMax_UInt, "Bio ID(s)", CArgDescriptions::eString);
246  arg_desc.AddOptionalKey("type", "TYPE", "Type of the first bio ID", CArgDescriptions::eString);
247  arg_desc.AddOptionalKey("acc-substitution", "ACC_SUB", "ACC substitution", CArgDescriptions::eString);
248  arg_desc.AddFlag("no-bio-id-resolution", "Do not try to resolve provided bio ID(s) before use");
249  arg_desc.AddOptionalKey("snp-scale-limit", "LIMIT", "SNP scale limit", CArgDescriptions::eString);
250  arg_desc.SetConstraint("snp-scale-limit", new CArgAllow_Strings{"unit", "contig", "supercontig", "chromosome"});
251  s_InitDataOnly(arg_desc, false);
252  s_InitDataFlags(arg_desc);
253 }
254 
255 template <>
256 void CPsgClientApp::s_InitRequest<CPSG_Request_Chunk>(CArgDescriptions& arg_desc)
257 {
258  arg_desc.AddPositional("ID2_CHUNK", "ID2 chunk number", CArgDescriptions::eInteger);
259  arg_desc.AddPositional("ID2_INFO", "ID2 info", CArgDescriptions::eString);
260  s_InitDataOnly(arg_desc);
261 }
262 
263 template <>
264 void CPsgClientApp::s_InitRequest<CPSG_Request_IpgResolve>(CArgDescriptions& arg_desc)
265 {
266  arg_desc.AddOptionalKey("protein", "PROTEIN", "Protein", CArgDescriptions::eString);
267  arg_desc.AddOptionalKey("ipg", "IPG", "IPG", CArgDescriptions::eInt8);
268  arg_desc.AddOptionalKey("nucleotide", "NUCLEOTIDE", "Nucleotide", CArgDescriptions::eString);
269  arg_desc.AddDefaultKey("input-file", "FILENAME", "File containing proteins to resolve (one 'protein[,nucleotide]' per line)", CArgDescriptions::eInputFile, "-");
270  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "protein");
271  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "ipg");
272  arg_desc.SetDependency("input-file", CArgDescriptions::eExcludes, "nucleotide");
273  arg_desc.AddFlag("server-mode", "Output one response per line");
274  arg_desc.AddDefaultKey("rate", "RATE", "Maximum number of requests to submit per second", CArgDescriptions::eInteger, "0");
275  arg_desc.AddDefaultKey("worker-threads", "THREADS_CONF", "Numbers of worker threads of each type", CArgDescriptions::eInteger, "7", CArgDescriptions::fHidden);
276 }
277 
278 template<>
279 void CPsgClientApp::s_InitRequest<SInteractive>(CArgDescriptions& arg_desc)
280 {
281  arg_desc.AddDefaultKey("input-file", "FILENAME", "File containing JSON-RPC requests (one per line)", CArgDescriptions::eInputFile, "-");
282  arg_desc.AddOptionalKey("data-limit", "SIZE", "Show a data preview for any data larger the limit (if set)", CArgDescriptions::eDataSize);
283  arg_desc.AddDefaultKey("preview-size", "SIZE", "How much of data to show as the preview", CArgDescriptions::eDataSize, "16");
284  arg_desc.AddFlag("server-mode", "Output one JSON-RPC response per line and always output reply statuses");
285  arg_desc.AddFlag("echo", "Echo all incoming requests");
286  arg_desc.AddFlag("one-server", "Use only one server from the service", CArgDescriptions::eFlagHasValueIfSet, CArgDescriptions::fHidden);
287  arg_desc.AddFlag("testing", "Testing mode adjustments", CArgDescriptions::eFlagHasValueIfSet, CArgDescriptions::fHidden);
288  arg_desc.AddDefaultKey("rate", "RATE", "Maximum number of requests to submit per second", CArgDescriptions::eInteger, "0");
289  arg_desc.AddDefaultKey("worker-threads", "THREADS_CONF", "Numbers of worker threads of each type", CArgDescriptions::eInteger, "7", CArgDescriptions::fHidden);
290  arg_desc.SetDependency("preview-size", CArgDescriptions::eRequires, "data-limit");
291 }
292 
293 template <>
294 void CPsgClientApp::s_InitRequest<SPerformance>(CArgDescriptions& arg_desc)
295 {
296  arg_desc.AddDefaultKey("user-threads", "THREADS_NUM", "Number of user threads", CArgDescriptions::eInteger, "1");
297  arg_desc.AddDefaultKey("delay", "SECONDS", "Delay between consecutive requests (in seconds)", CArgDescriptions::eDouble, "0.0");
298  arg_desc.AddFlag("local-queue", "Whether user threads to use separate queues");
299  arg_desc.AddFlag("report-immediately", "Whether to report metrics immediately (or at the end)");
300  arg_desc.AddDefaultKey("output-file", "FILENAME", "Output file to contain raw performance metrics", CArgDescriptions::eOutputFile, "-");
301 }
302 
303 template <>
304 void CPsgClientApp::s_InitRequest<SJsonCheck>(CArgDescriptions& arg_desc)
305 {
306  arg_desc.AddOptionalKey("schema-file", "FILENAME", "JSON-RPC schema file (built-in by default)", CArgDescriptions::eInputFile);
307  arg_desc.AddDefaultKey("input-file", "FILENAME", "JSON-RPC requests file (one per line)", CArgDescriptions::eInputFile, "-");
308 }
309 
310 void s_SetPsgDefaults(const CArgs& args, bool parallel)
311 {
313 
314  if (args["io-threads"].HasValue()) {
315  auto io_threads = args["io-threads"].AsInteger();
316  TPSG_NumIo::SetDefault(io_threads);
317  }
318 
319  if (args["requests-per-io"].HasValue()) {
320  auto requests_per_io = args["requests-per-io"].AsInteger();
321  TPSG_RequestsPerIo::SetDefault(requests_per_io);
322  } else if (parallel) {
324  }
325 
326  if (args["max-streams"].HasValue()) {
327  auto max_streams = args["max-streams"].AsInteger();
328  TPSG_MaxConcurrentStreams::SetDefault(max_streams);
329  }
330 
331  if (args["use-cache"].HasValue()) {
332  auto use_cache = args["use-cache"].AsString();
333  TPSG_UseCache::SetDefault(use_cache);
334  }
335 
336  if (args["timeout"].HasValue()) {
337  auto timeout = args["timeout"].AsInteger();
338  TPSG_RequestTimeout::SetDefault(timeout);
339  }
340 
341  if (args["https"].HasValue()) {
342  TPSG_Https::SetDefault(true);
343  }
344 
345  if (args["debug-printout"].HasValue()) {
346  auto debug_printout = args["debug-printout"].AsString();
347  TPSG_DebugPrintout::SetDefault(debug_printout);
348  }
349 }
350 
351 namespace NParamsBuilder
352 {
353 
354 template <class TParams>
355 struct SBase : TParams
356 {
357  template <class... TInitArgs>
358  SBase(const CArgs& args, TInitArgs&&... init_args) :
359  TParams{
360  args["service"].HasValue() ? args["service"].AsString() : string(),
361  args["include-hup"].HasValue() ? CPSG_Request::fIncludeHUP : CPSG_Request::eDefaultFlags,
362  args["user-args"].HasValue() ? args["user-args"].AsString() : SPSG_UserArgs(),
363  std::forward<TInitArgs>(init_args)...
364  }
365  {
366  TParams::verbose = args["verbose"].HasValue();
367  }
368 };
369 
370 struct SOneRequest : SBase<SOneRequestParams>
371 {
372  SOneRequest(const CArgs& args) :
373  SBase{
374  args,
375  GetLatency(args),
376  args["debug-printout"].HasValue(),
377  GetDataOnlyEnabled(args),
378  false,
380  }
381  {
382  }
383 
385  {
386  if (args["first-latency"].HasValue()) return CLogLatencies::eFirst;
387  if (args["last-latency"].HasValue()) return CLogLatencies::eLast;
388  if (args["all-latency"].HasValue()) return CLogLatencies::eAll;
389  return CLogLatencies::eOff;
390  }
391 
392  static bool GetDataOnlyEnabled(const CArgs& args)
393  {
394  return (args.Exist("blob-only") && args["blob-only"].HasValue()) ||
395  (args.Exist("annot-only") && args["annot-only"].HasValue());
396  }
397 
399  {
400  if (args.Exist("output-fmt") && args["output-fmt"].HasValue()) {
401  const auto& format = args["output-fmt"].AsString();
402 
403  if (format == "asn") return eSerial_AsnText;
404  if (format == "asnb") return eSerial_AsnBinary;
405  if (format == "xml") return eSerial_Xml;
406  if (format == "json") return eSerial_Json;
407  }
408 
409  return eSerial_None;
410  }
411 
412 };
413 
414 template <class TParams>
416 {
417  template <class... TInitArgs>
418  SParallelProcessing(const CArgs& args, TInitArgs&&... init_args) :
419  SBase<TParams>{
420  args,
421  args["rate"].AsInteger(),
422  max(1, min(10, args["worker-threads"].AsInteger())),
423  args["input-file"].AsString() == "-",
424  args["server-mode"].AsBoolean(),
425  std::forward<TInitArgs>(init_args)...
426  },
427  SIoRedirector(cin, args["input-file"].AsInputFile())
428  {
429  }
430 };
431 
432 struct SBatchResolve : SParallelProcessing<SBatchResolveParams>
433 {
434  SBatchResolve(const CArgs& args) :
436  args,
438  }
439  {
440  }
441 };
442 
444 
445 struct SInteractive : SParallelProcessing<SInteractiveParams>
446 {
447  SInteractive(const CArgs& args) :
449  args,
450  GetDataLimit(args["data-limit"]),
451  static_cast<size_t>(args["preview-size"].AsInt8()),
452  args["echo"].HasValue(),
453  args["one-server"].HasValue(),
454  args["testing"].HasValue()
455  }
456  {
457  }
458 
459  static size_t GetDataLimit(const CArgValue& value)
460  {
461  return value.HasValue() ? static_cast<size_t>(value.AsInt8()) : numeric_limits<size_t>::max();
462  }
463 };
464 
465 struct SPerformance : SBase<SPerformanceParams>, SIoRedirector
466 {
467  SPerformance(const CArgs& args) :
469  args,
470  static_cast<size_t>(args["user-threads"].AsInteger()),
471  args["delay"].AsDouble(),
472  args["local-queue"].AsBoolean(),
473  args["report-immediately"].AsBoolean(),
474  },
475  SIoRedirector(cout, args["output-file"].AsOutputFile())
476  {
477  }
478 };
479 
480 }
481 
482 template <>
484 {
485  const CArgs& input;
486 
487  SReader(const CArgs& i) : input(i) {}
488 
489  TSpecified GetSpecified() const;
490  auto GetBioIdType() const { return input["type"].HasValue() ? SRequestBuilder::GetBioIdType(input["type"].AsString()) : CPSG_BioId::TType(); }
491  CPSG_BioId GetBioId() const { return { input["ID"].AsString(), GetBioIdType() }; }
492  CPSG_BioIds GetBioIds() const;
493  CPSG_BlobId GetBlobId() const;
494  CPSG_ChunkId GetChunkId() const;
495  vector<string> GetNamedAnnots() const { return input["na"].GetStringList(); }
496  auto GetAccSubstitution() const { return input["acc-substitution"].HasValue() ? SRequestBuilder::GetAccSubstitution(input["acc-substitution"].AsString()) : EPSG_AccSubstitution::Default; }
499  void ForEachTSE(TExclude exclude) const;
500  auto GetProtein() const { return input["protein"].HasValue() ? input["protein"].AsString() : string(); }
501  auto GetIpg() const { return input["ipg"].HasValue() ? input["ipg"].AsInt8() : 0; }
502  auto GetNucleotide() const { return input["nucleotide"].HasValue() ? CPSG_Request_IpgResolve::TNucleotide(input["nucleotide"].AsString()) : null; }
503  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; }
504  void SetRequestFlags(shared_ptr<CPSG_Request> request) const;
505  SPSG_UserArgs GetUserArgs() const { return input["user-args"].HasValue() ? input["user-args"].AsString() : SPSG_UserArgs(); }
506 };
507 
509 {
510  return [&](const string& name) {
511  return input[name].HasValue();
512  };
513 }
514 
516 {
517  const size_t n = input.GetNExtra();
518 
519  CPSG_BioIds rv;
520 
521  for (size_t i = 1; i <= n; ++i) {
522  if (i == 1) {
523  rv.emplace_back(input[i].AsString(), GetBioIdType());
524  } else {
525  rv.emplace_back(input[i].AsString());
526  }
527  }
528 
529  return rv;
530 }
531 
533 {
534  const auto& id = input["ID"].AsString();
535  const auto& last_modified = input["last-modified"];
536  return last_modified.HasValue() ? CPSG_BlobId(id, last_modified.AsInt8()) : id;
537 }
538 
540 {
541  return { input["ID2_CHUNK"].AsInteger(), input["ID2_INFO"].AsString() };
542 }
543 
545 {
546  if (!input["exclude-blob"].HasValue()) return;
547 
548  auto blob_ids = input["exclude-blob"].GetStringList();
549 
550  for (const auto& blob_id : blob_ids) {
551  exclude(blob_id);
552  }
553 }
554 
555 void SRequestBuilder::SReader<CArgs>::SetRequestFlags(shared_ptr<CPSG_Request> request) const
556 {
557  if (input["include-hup"].HasValue()) {
558  request->SetFlags(CPSG_Request::fIncludeHUP);
559  }
560 }
561 
562 template <class TRequest>
564 {
565  auto request = SRequestBuilder::Build<TRequest>(args);
567 }
568 
569 template<>
570 int CPsgClientApp::RunRequest<CPSG_Request_Resolve>(const CArgs& args)
571 {
572  const auto single_request = args["ID"].HasValue();
573 
574  if (single_request) {
575  auto request = SRequestBuilder::Build<CPSG_Request_Resolve>(args);
577  } else {
579  }
580 }
581 
582 template<>
583 int CPsgClientApp::RunRequest<CPSG_Request_IpgResolve>(const CArgs& args)
584 {
585  const auto single_request = args["protein"].HasValue() || args["ipg"].HasValue() || args["nucleotide"].HasValue();
586 
587  if (single_request) {
588  auto request = SRequestBuilder::Build<CPSG_Request_IpgResolve>(args);
590  } else {
592  }
593 }
594 
595 template<>
596 int CPsgClientApp::RunRequest<SInteractive>(const CArgs& args)
597 {
598  NParamsBuilder::SInteractive params_builder(args);
599 
600  if (params_builder.testing) {
601  GetRWConfig().SetValue("log", "issued_subhit_limit", 0);
602  }
603 
604  return CProcessing::ParallelProcessing(params_builder);
605 }
606 
607 template <>
608 int CPsgClientApp::RunRequest<SPerformance>(const CArgs& args)
609 {
612 }
613 
614 template <>
615 int CPsgClientApp::RunRequest<SJsonCheck>(const CArgs& args)
616 {
617  const auto& schema = args["schema-file"];
618  SIoRedirector ior(cin, args["input-file"].AsInputFile());
619  return CProcessing::JsonCheck(schema.HasValue() ? &schema.AsInputFile() : nullptr);
620 }
621 
622 template <class TRequest>
624 {
625  return { std::move(name), std::move(desc), s_InitRequest<TRequest>, s_RunRequest<TRequest>, flags };
626 }
627 
628 int main(int argc, const char* argv[])
629 {
630  return CPsgClientApp().AppMain(argc, argv);
631 }
static const NStr::TNumToStringFlags kFlags
#define false
Definition: bool.h:36
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:174
CSeq_id::E_Choice TType
Definition: psg_client.hpp:177
Blob unique ID.
Definition: psg_client.hpp:225
Chunk unique ID.
Definition: psg_client.hpp:264
CNullable< string > TNucleotide
Definition: psg_client.hpp:599
Request to the PSG server (see "CPSG_Request_*" below)
Definition: psg_client.hpp:99
static int JsonCheck(istream *schema_is)
static int OneRequest(const SOneRequestParams &params, shared_ptr< CPSG_Request > request)
Definition: processing.cpp:822
static int ParallelProcessing(const TParams &params, istream &is=cin)
Definition: processing.hpp:341
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
char value[7]
Definition: config.c:431
#define option
static uch flags
static const struct name_t names[]
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments.
Definition: ncbiapp.cpp:285
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:799
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: ncbiapp.cpp:1175
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
#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
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:902
@ Default
Substitute always (default)
vector< CPSG_BioId > CPSG_BioIds
Definition: psg_client.hpp:205
EPSG_BioIdResolution
Whether to try to resolve provided seq-ids before use.
Definition: psg_client.hpp:298
@ 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
static const char * schema
Definition: stats.c:20
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:238
SIoRedirector(ios &what, ios &to)
static void SetImplicitDefault(const T &value)
Definition: misc.hpp:228
Arbitrary request URL arguments.
Definition: psg_client.hpp:78
vector< string > GetNamedAnnots() const
EPSG_BioIdResolution GetBioIdResolution() const
static CPSG_BioId::TType GetBioIdType(const string &type)
function< void(string)> TExclude
Definition: processing.hpp:396
static EPSG_AccSubstitution GetAccSubstitution(const string &acc_substitution)
Definition: processing.hpp:623
static SResolveParams GetResolveParams(const TInput &input)
Definition: processing.hpp:487
static const initializer_list< SInfoFlag > & GetInfoFlags()
static const initializer_list< SDataFlag > & GetDataFlags()
function< bool(const string &)> TSpecified
Definition: processing.hpp:395
#define _ASSERT
Modified on Wed Nov 29 02:19:34 2023 by modify_doxy.py rev. 669887