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

Go to the SVN repository for this file.

1 /* $Id: util.cpp 86218 2019-04-18 16:59:46Z 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  * Authors: Dmitry Kazimirov
27  *
28  * File Description: Utility functions - implementation.
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include "util.hpp"
35 
36 #include <sstream>
37 #include <locale>
38 #include <corelib/rwstream.hpp>
39 #include <cgi/ncbicgi.hpp>
44 
45 #include <connect/ncbi_util.h>
46 
48 
50 {
51 public:
53  m_Cmd(cmd)
54  {
56  }
57 
58 protected:
59  virtual CJsonNode ExecOn(CNetServer server);
60 
61 private:
62  string m_Cmd;
63 };
64 
66 {
67  const string response(server.ExecWithRetry(m_Cmd, false).response);
68  if (response.empty()) return CJsonNode::eObject;
69  return CJsonNode::ParseJSON(response);
70 }
71 
73 {
74  const string stat_cmd(verbose ? "STAT ALL" : "STAT");
75 
76  CNetServerMultilineCmdOutput output(server.ExecWithRetry(stat_cmd, true));
77 
79  CJsonNode jobs_by_status(CJsonNode::NewObjectNode());;
80  stat_info.SetByKey("JobsByStatus", jobs_by_status);
81  CJsonNode section_entries;
82 
83  string line;
85 
86  while (output.ReadLine(line)) {
87  if (line.empty() || isspace(line[0]))
88  continue;
89 
90  if (line[0] == '[') {
91  size_t section_name_len = line.length();
92  while (--section_name_len > 0 &&
93  (line[section_name_len] == ':' ||
94  line[section_name_len] == ']' ||
95  isspace(line[section_name_len])))
96  ;
97  line.erase(0, 1);
98  line.resize(section_name_len);
99  stat_info.SetByKey(line,
100  section_entries = CJsonNode::NewArrayNode());
101  }
102  else if (section_entries) {
103  section_entries.AppendString(line);
104  }
105  else if (NStr::SplitInTwo(line, ":", key, value)) {
109  jobs_by_status.SetInteger(key, NStr::StringToInt8(value));
110  else {
111  if (key == "Executable path" &&
112  g_FixMisplacedPID(stat_info, value, "PID")) {
113  if (!stat_info.HasKey("Version"))
114  stat_info.SetString("Version", "Unknown");
115 
116  if (!stat_info.HasKey("Build date"))
117  stat_info.SetString("Build date", "Unknown");
118  }
119  stat_info.SetByKey(key, CJsonNode::GuessType(value));
120  }
121  }
122  }
123 
124  return stat_info;
125 }
126 
128 {
130  const string& queue_name) :
131  m_NetScheduleAdmin(ns_admin), m_QueueName(queue_name)
132  {
133  }
134 
135  virtual CJsonNode ExecOn(CNetServer server);
136 
138  string m_QueueName;
139 };
140 
142 {
144  m_NetScheduleAdmin.GetQueueInfo(server, m_QueueName, queue_info);
145 
146  CJsonNode queue_info_node(CJsonNode::NewObjectNode());
147 
148  ITERATE(CNetScheduleAdmin::TQueueInfo, qi, queue_info) {
149  queue_info_node.SetByKey(qi->first, CJsonNode::GuessType(qi->second));
150  }
151 
152  return queue_info_node;
153 }
154 
156 {
157  SQueueInfoToJson(const string& cmd, const string& section_prefix) :
158  m_Cmd(cmd), m_SectionPrefix(section_prefix)
159  {
161  }
162 
163  virtual CJsonNode ExecOn(CNetServer server);
164 
165  string m_Cmd;
167 };
168 
170 {
172 
173  CJsonNode queue_map(CJsonNode::NewObjectNode());
174  CJsonNode queue_params;
175 
176  string line;
177  CTempString param_name, param_value;
178 
179  while (output.ReadLine(line))
180  if (NStr::StartsWith(line, m_SectionPrefix) &&
181  line.length() > m_SectionPrefix.length())
182  queue_map.SetByKey(line.substr(m_SectionPrefix.length(),
183  line.length() - m_SectionPrefix.length() - 1),
184  queue_params = CJsonNode::NewObjectNode());
185  else if (queue_params && NStr::SplitInTwo(line, ": ",
186  param_name, param_value,
188  queue_params.SetByKey(param_name,
189  CJsonNode::GuessType(param_value));
190 
191  return queue_map;
192 }
193 
195  const string& queue_name)
196 {
197  if (queue_name.empty()) {
198  SQueueInfoToJson queue_info_proc("STAT QUEUES", "[queue ");
199 
200  return g_ExecToJson(queue_info_proc, ns_api.GetService(),
202  }
203 
204  SSingleQueueInfoToJson single_queue_proc(ns_api.GetAdmin(), queue_name);
205 
206  return g_ExecToJson(single_queue_proc, ns_api.GetService(),
208 }
209 
211 {
212  SQueueInfoToJson queue_info_proc("STAT QCLASSES", "[qclass ");
213 
214  return g_ExecToJson(queue_info_proc, ns_api.GetService(),
216 }
217 
219 {
220  CExecAndParseStructuredOutput exec_and_parse_structured_output("RECO");
221 
222  return g_ExecToJson(exec_and_parse_structured_output,
224 }
225 
227 {
228  m_JobInfo.SetString("server_host", g_NetService_TryResolveHost(key.host));
229  m_JobInfo.SetInteger("server_port", key.port);
230 
231  m_JobInfo.SetInteger("job_id", key.id);
232 
233  if (!key.queue.empty())
234  m_JobInfo.SetString("queue_name", g_UnquoteIfQuoted(key.queue));
235 }
236 
238 {
239  if (!m_JobEvents)
241 
243 }
244 
246  const string& attr_value)
247 {
248  m_CurrentEvent.SetByKey(attr_name, CJsonNode::GuessType(attr_value));
249 }
250 
252 {
253  m_CurrentEvent.SetNull(attr_name);
254 }
255 
257 {
258 protected:
259  static CJsonNode x_CreateNode(EType type, const string& data)
260  {
262 
263  switch (type) {
264  case eEmbedded:
265  node.SetString("storage", "embedded");
266  node.SetString("embedded_data", data);
267  return node;
268 
269  case eNetCache:
270  node.SetString("storage", "netcache");
271  node.SetString("netcache_key", data);
272  return node;
273 
274  default:
275  node.SetString("storage", "raw");
276  node.SetString("raw_data", data);
277  return node;
278  }
279  }
280 
281 public:
282  static bool AddNode(CJsonNode parent, const string& name, string data)
283  {
284  // Do not combine calls to x_GetDataType and x_CreateNode,
285  // as x_GetDataType modifies data
286  EType type = x_GetDataType(data);
287  parent.SetByKey(name, x_CreateNode(type, data));
288  return type != eRaw && type != eEmpty;
289  }
290 
291  static void AddNodes(CJsonNode parent, const string& name, const string& src)
292  {
293  if (AddNode(parent, name, src)) {
294  parent.SetString("raw_" + name, src);
295  }
296  }
297 };
298 
300 {
302 
303  CJsonNodeUpdater(const string& name, CJsonNode parent)
304  : node(parent.GetByKeyOrNull(name)),
305  m_Name(name),
306  m_Parent(parent),
307  m_NewNode(!node)
308  {
310  }
311 
312 
314  {
316  }
317 
318 private:
319  const string m_Name;
321  const bool m_NewNode;
322 };
323 
324 static const string s_JobType = "job_type";
325 
326 struct SRemoteApp : private CBlobStreamHelper, private SDataDetector
327 {
328 private:
329  static bool x_GetFileName(string& data);
330  static CJsonNode x_CreateArgsNode(const string& data, CJsonNode files);
331  static CJsonNode x_CreateDataNode(string data);
332 
333 public:
334  struct SRequest;
335 
336  static const string& Name() {
337  static const string name = "remote_app";
338  return name;
339  }
340 
341  static void Input(CJsonNode& node, SRequest& request);
342  static void Output(CJsonNode& node, CRStream& stream, const string&);
343 };
344 
345 bool SRemoteApp::x_GetFileName(string& data)
346 {
347  istringstream iss(data);
348  string name;
349 
350  if (x_GetTypeAndName(iss, name) == eLocalFile) {
351  data.swap(name);
352  return true;
353  }
354 
355  data.erase(0, iss.tellg());
356  return false;
357 }
358 
360 {
362  node.SetString("cmdline_args", data);
363  if (files) node.SetByKey("files", files);
364  return node;
365 }
366 
368 {
369  EType type = x_GetDataType(data);
370 
371  if (type == eEmbedded && x_GetFileName(data)) {
373  node.SetString("storage", "localfile");
374  node.SetString("filename", data);
375  return node;
376  }
377 
378  return x_CreateNode(type, data);
379 }
380 
382 {
385  {
386  if (!x_Deserialize(is, &m_Files)) {
387  throw ios_base::failure("x_Deserialize failed");
388  }
389  }
390 
392  {
393  if (m_Files.empty()) return CJsonNode();
394 
397  i != m_Files.end(); ++i) {
399  file.SetString("filename", i->first);
400 
401  if (i->second.empty()) {
402  file.SetString("storage", "localfile");
403  } else {
404  file.SetString("storage", "netcache");
405  file.SetString("netcache_key", i->second);
406  }
407 
408  array.Append(file);
409  }
410  return array;
411  }
412 
413 private:
415 };
416 
417 void SRemoteApp::Input(CJsonNode& node, SRequest& request)
418 {
419  node.SetInteger("run_timeout", request.GetAppRunTimeout());
420  node.SetBoolean("exclusive", request.IsExclusiveMode());
421  CJsonNode files = request.CreateFilesNode();
422  node.SetByKey("args", x_CreateArgsNode(request.GetCmdLine(), files));
423  node.SetByKey("stdin", x_CreateDataNode(request.GetInBlobIdOrData()));
424 }
425 
426 void SRemoteApp::Output(CJsonNode& node, CRStream& stream, const string&)
427 {
429  result.Receive(stream);
430 
431  node.SetByKey("stdout", x_CreateDataNode(result.GetOutBlobIdOrData()));
432  node.SetByKey("stderr", x_CreateDataNode(result.GetErrBlobIdOrData()));
433  node.SetInteger("exit_code", result.GetRetCode());
434 }
435 
437 {
438  struct SRequest;
439 
440  static const string& Name() {
441  static const string name = "remote_cgi";
442  return name;
443  }
444 
445  static void Input(CJsonNode& node, SRequest& request);
446  static void Output(CJsonNode& node, CRStream& stream, const string& data);
447 };
448 
450 {
453  {}
454 };
455 
456 void SRemoteCgi::Input(CJsonNode& node, SRequest& request)
457 {
458  node.SetString("method", request.GetRequestMethodName());
459 
460  const CNcbiEnvironment& env(request.GetEnvironment());
461  list<string> names;
462  env.Enumerate(names);
463  CJsonNodeUpdater env_updater("env", node);
464 
465  for (list<string>::iterator i = names.begin(); i != names.end(); ++i) {
466  env_updater.node.SetString(*i, env.Get(*i));
467  }
468 }
469 
470 void SRemoteCgi::Output(CJsonNode& node, CRStream& stream, const string& data)
471 {
472  string field;
473  getline(stream, field);
474  stream >> field;
475  int status = 200;
476  if (field == "Status:") stream >> status;
477 
478  node.SetInteger("status", status);
479  SDataDetector::AddNode(node, "stdout", data);
480 }
481 
483 {
484 private:
486  {
487  SStringStream(const string& data)
489  CRStream(this, 0, 0, CRWStreambuf::fLeakExceptions)
490  {
491  exceptions(IOS_BASE::badbit | IOS_BASE::failbit);
492  }
493  };
494 
495 public:
496  template <class TJobType>
497  static bool Input(const string& data, CJsonNode& node)
498  {
499  try {
500  SStringStream stream(data);
501  typename TJobType::SRequest request(stream);
502 
503  CJsonNodeUpdater updater(TJobType::Name(), node);
504  TJobType::Input(updater.node, request);
505 
506  node.SetString(s_JobType, TJobType::Name());
507  return true;
508  }
509  catch (...) {
510  return false;
511  }
512  }
513 
514  template <class TJobType>
515  static void Output(const string& data, CJsonNode& node)
516  {
517  CJsonNodeUpdater updater(TJobType::Name(), node);
518  const char* value = data.empty() ? "absent" : "gone";
519 
520  try {
521  SStringStream stream(data);
522  TJobType::Output(updater.node, stream, data);
523  value = "ready";
524  }
525  catch (...) {
526  }
527 
528  updater.node.SetString("output_data", value);
529  }
530 };
531 
532 void CJobInfoToJSON::ProcessInput(const string& data)
533 {
534  SDataDetector::AddNodes(m_JobInfo, "input", data);
535 
536  if (!SInputOutputProcessor::Input<SRemoteApp>(data, m_JobInfo) &&
537  !SInputOutputProcessor::Input<SRemoteCgi>(data, m_JobInfo))
538  m_JobInfo.SetString(s_JobType, "generic");
539 }
540 
541 void CJobInfoToJSON::ProcessOutput(const string& data)
542 {
543  SDataDetector::AddNodes(m_JobInfo, "output", data);
544  const string job_type(m_JobInfo.GetString(s_JobType));
545 
546  if (job_type == SRemoteApp::Name()) {
547  SInputOutputProcessor::Output<SRemoteApp>(data, m_JobInfo);
548  } else if (job_type == SRemoteCgi::Name()) {
549  SInputOutputProcessor::Output<SRemoteCgi>(data, m_JobInfo);
550  }
551 }
552 
554  const CTempString& field_value)
555 {
556  // There could be page hit ID values that look like a double
557  CJsonNode node(field_name != "ncbi_phid" ?
558  CJsonNode::GuessType(field_value) :
559  CJsonNode::NewStringNode(field_value)) ;
560  m_JobInfo.SetByKey(field_name, node);
561 }
562 
563 void CJobInfoToJSON::ProcessRawLine(const string& line)
564 {
565  if (!m_UnparsableLines)
566  m_JobInfo.SetByKey("unparsable_lines",
568 
570 }
571 
572 void g_ProcessJobInfo(CNetScheduleAPI ns_api, const string& job_key,
573  IJobInfoProcessor* processor, bool verbose,
575 {
576  processor->ProcessJobMeta(CNetScheduleKey(job_key, id_pool));
577 
578  if (verbose) {
580 
581  string line;
582 
583  while (output.ReadLine(line)) {
584  if (!line.empty() && line[0] != '[' && !NStr::StartsWith(line,
585  TEMP_STRING_CTOR("NCBI NetSchedule"))) {
586  CTempString field_name, field_value;
587 
588  if (!NStr::SplitInTwo(line, TEMP_STRING_CTOR(": "),
589  field_name, field_value,
591  processor->ProcessRawLine(line);
592  else if (field_name == TEMP_STRING_CTOR("input"))
593  processor->ProcessInput(NStr::ParseQuoted(field_value));
594  else if (field_name == TEMP_STRING_CTOR("output"))
595  processor->ProcessOutput(NStr::ParseQuoted(field_value));
596  else if (NStr::StartsWith(field_name,
597  TEMP_STRING_CTOR("event"))) {
598  processor->BeginJobEvent(field_name);
599 
600  try {
601  CAttrListParser attr_parser;
602  attr_parser.Reset(field_value);
604  CTempString attr_name;
605  string attr_value;
606  size_t attr_column;
607 
608  while ((next_attr_type = attr_parser.NextAttribute(
609  &attr_name, &attr_value, &attr_column)) !=
611  if (next_attr_type ==
613  processor->ProcessJobEventField(attr_name,
614  attr_value);
615  else // CAttrListParser::eStandAloneAttribute
616  processor->ProcessJobEventField(attr_name);
617  }
618  catch (CArgException&) {
619  // Ignore this exception type.
620  }
621  } else if (field_name != TEMP_STRING_CTOR("id") &&
622  field_name != TEMP_STRING_CTOR("key"))
623  processor->ProcessJobInfoField(field_name, field_value);
624  }
625  }
626  } else {
627  CNetScheduleJob job;
628  job.job_id = job_key;
629  CNetScheduleAPI::EJobStatus status(ns_api.GetJobDetails(job));
630 
631  processor->ProcessJobInfoField(TEMP_STRING_CTOR("status"),
633 
634  if (status == CNetScheduleAPI::eJobNotFound)
635  return;
636 
637  processor->ProcessInput(job.input);
638 
639  switch (status) {
640  default:
641  if (job.output.empty())
642  break;
643  /* FALL THROUGH */
644 
649  processor->ProcessOutput(job.output);
650  break;
651  }
652 
653  if (!job.error_msg.empty())
654  processor->ProcessJobInfoField(TEMP_STRING_CTOR("err_msg"),
655  job.error_msg);
656  }
657 }
658 
659 static void Indent(FILE* output_stream, int indent_depth, const char* indent)
660 {
661  while (--indent_depth >= 0)
662  fprintf(output_stream, "%s", indent);
663 }
664 
665 static void PrintJSONNode(FILE* output_stream, CJsonNode node,
666  const char* indent,
667  int struct_indent_depth = 0, const char* struct_prefix = "",
668  int scalar_indent_depth = 0, const char* scalar_prefix = "")
669 {
670  switch (node.GetNodeType()) {
671  case CJsonNode::eObject:
672  {
673  fputs(struct_prefix, output_stream);
674  Indent(output_stream, struct_indent_depth, indent);
675  putc('{', output_stream);
676  const char* prefix = "\n";
677  int indent_depth = struct_indent_depth + 1;
678  for (CJsonIterator it = node.Iterate(); it; ++it) {
679  fputs(prefix, output_stream);
680  Indent(output_stream, indent_depth, indent);
681  fprintf(output_stream, "\"%s\":",
682  NStr::PrintableString(it.GetKey()).c_str());
683  PrintJSONNode(output_stream, *it, indent,
684  indent_depth, "\n", 0, " ");
685  prefix = ",\n";
686  }
687  putc('\n', output_stream);
688  Indent(output_stream, struct_indent_depth, indent);
689  putc('}', output_stream);
690  }
691  break;
692  case CJsonNode::eArray:
693  {
694  fputs(struct_prefix, output_stream);
695  Indent(output_stream, struct_indent_depth, indent);
696  putc('[', output_stream);
697  const char* prefix = "\n";
698  int indent_depth = struct_indent_depth + 1;
699  for (CJsonIterator it = node.Iterate(); it; ++it) {
700  fputs(prefix, output_stream);
701  PrintJSONNode(output_stream, *it, indent,
702  indent_depth, "", indent_depth, "");
703  prefix = ",\n";
704  }
705  putc('\n', output_stream);
706  Indent(output_stream, struct_indent_depth, indent);
707  putc(']', output_stream);
708  }
709  break;
710  case CJsonNode::eString:
711  fputs(scalar_prefix, output_stream);
712  Indent(output_stream, scalar_indent_depth, indent);
713  fprintf(output_stream, "\"%s\"",
714  NStr::PrintableString(node.AsString()).c_str());
715  break;
716  case CJsonNode::eInteger:
717  fputs(scalar_prefix, output_stream);
718  Indent(output_stream, scalar_indent_depth, indent);
719  fprintf(output_stream, "%lld", (long long) node.AsInteger());
720  break;
721  case CJsonNode::eDouble:
722  fputs(scalar_prefix, output_stream);
723  Indent(output_stream, scalar_indent_depth, indent);
724  fprintf(output_stream, "%.10g", node.AsDouble());
725  break;
726  case CJsonNode::eBoolean:
727  fputs(scalar_prefix, output_stream);
728  Indent(output_stream, scalar_indent_depth, indent);
729  fputs(node.AsBoolean() ? "true" : "false", output_stream);
730  break;
731  default: // CJsonNode::eNull
732  fputs(scalar_prefix, output_stream);
733  Indent(output_stream, scalar_indent_depth, indent);
734  fputs("null", output_stream);
735  }
736 }
737 
738 void g_PrintJSON(FILE* output_stream, CJsonNode node, const char* indent)
739 {
740  PrintJSONNode(output_stream, node, indent);
741  putc('\n', output_stream);
742 }
743 
745 {
746  SExecAnyCmdToJson(const string& cmd, bool multiline) :
748  {
749  }
750 
751  virtual CJsonNode ExecOn(CNetServer server);
752 
753  string m_Cmd;
755 };
756 
758 {
759  if (!m_Multiline)
761  false).response);
762 
764 
766  string line;
767 
768  while (output.ReadLine(line))
769  lines.AppendString(line);
770 
771  return lines;
772 }
773 
775  const string& command, bool multiline)
776 {
777  SExecAnyCmdToJson exec_any_cmd_proc(command, multiline);
778 
779  return g_ExecToJson(exec_any_cmd_proc, service);
780 }
781 
783 {
784  SServerInfoToJson(bool server_version_key) :
785  m_ServerVersionKey(server_version_key)
786  {
787  }
788 
789  virtual CJsonNode ExecOn(CNetServer server);
790 
792 };
793 
795 {
797 }
798 
800  bool server_version_key)
801 {
802  SServerInfoToJson server_info_proc(server_version_key);
803 
804  return g_ExecToJson(server_info_proc, service,
806 }
807 
808 void g_SuspendNetSchedule(CNetScheduleAPI netschedule_api, bool pullback_mode)
809 {
810  string cmd(pullback_mode ? "QPAUSE pullback=1" : "QPAUSE");
811 
813 
814  netschedule_api.GetService().ExecOnAllServers(cmd);
815 }
816 
818 {
819  string cmd("QRESUME");
820 
822 
823  netschedule_api.GetService().ExecOnAllServers(cmd);
824 }
825 
827  bool pullback_mode, unsigned timeout)
828 {
829  string cmd("SUSPEND");
830  if (pullback_mode)
831  cmd += " pullback";
832  if (timeout > 0) {
833  cmd += " timeout=";
834  cmd += NStr::NumericToString(timeout);
835  }
836  worker_node.ExecWithRetry(cmd, false);
837 }
838 
840 {
841  worker_node.ExecWithRetry("RESUME", false);
842 }
843 
845 {
847  result.SetString("type", TOKEN_TYPE__NETCACHE_BLOB_KEY);
848  result.SetInteger("key_version", key.GetVersion());
849 
850  if (key.GetVersion() != 3) {
851  const string server_host(g_NetService_TryResolveHost(key.GetHost()));
852  result.SetString("server_host", server_host);
853  result.SetInteger("server_port", key.GetPort());
854  } else {
855  result.SetInteger("server_address_crc32", key.GetHostPortCRC32());
856  }
857 
858  result.SetInteger("id", key.GetId());
859 
860  CTime generation_time;
861  generation_time.SetTimeT(key.GetCreationTime());
862  result.SetString("key_generation_time", generation_time.AsString());
863  result.SetInteger("random", key.GetRandomPart());
864 
865  const string service(key.GetServiceName());
866 
867  if (!service.empty()) {
868  result.SetString("service_name", service);
869  } else {
870  result.SetNull("service_name");
871  }
872 
873  return result;
874 }
875 
876 CJsonNode g_WhatIs(const string& id, CCompoundIDPool id_pool)
877 {
878  try {
879  CNetStorageObjectLoc object_loc(id_pool, id);
881 
882  result.SetString("type", TOKEN_TYPE__NETSTORAGEOBJECT_LOC);
883  object_loc.ToJSON(result);
884  return result;
885  }
886  catch (CCompoundIDException&) {
887  }
888  catch (CNetStorageException&) {
889  }
890 
891  CNetCacheKey nc_key;
892 
893  if (CNetCacheKey::ParseBlobKey(id.c_str(), id.length(), &nc_key, id_pool)) {
894  return s_GetBlobMeta(nc_key);
895  }
896 
897  CNetScheduleKey ns_key;
898 
899  if (ns_key.ParseJobKey(id, id_pool)) {
900  CJobInfoToJSON job_info_to_json;
901 
902  // Ignoring version 0 as it means any string with a leading digit
903  if (ns_key.version) {
904  CJsonNode result(job_info_to_json.GetRootNode());
905 
906  result.SetString("type", TOKEN_TYPE__NETSCHEDULE_JOB_KEY);
907  result.SetInteger("key_version", ns_key.version);
908  job_info_to_json.ProcessJobMeta(ns_key);
909  return result;
910  }
911  }
912 
913  return CJsonNode();
914 }
915 
916 namespace NNetStorage
917 {
918 
919 void RemoveStdReplyFields(CJsonNode& server_reply)
920 {
921  server_reply.DeleteByKey("Type");
922  server_reply.DeleteByKey("Status");
923  server_reply.DeleteByKey("RE");
924  server_reply.DeleteByKey("Warnings");
925 }
926 
928  const string& command) :
929  m_NetStorageAdmin(netstorage_admin),
930  m_Command(command)
931 {
932 }
933 
935 {
938 
939  RemoveStdReplyFields(server_reply);
940  return server_reply;
941 }
942 
943 }
944 
CJsonNode g_ServerInfoToJson(CNetService service, bool server_version_key)
Definition: util.cpp:799
static void Indent(FILE *output_stream, int indent_depth, const char *indent)
Definition: util.cpp:659
CJsonNode g_ExecAnyCmdToJson(CNetService service, const string &command, bool multiline)
Definition: util.cpp:774
CJsonNode g_ReconfAndReturnJson(CNetScheduleAPI ns_api)
Definition: util.cpp:218
CJsonNode g_LegacyStatToJson(CNetServer server, bool verbose)
Definition: util.cpp:72
CJsonNode g_QueueClassInfoToJson(CNetScheduleAPI ns_api)
Definition: util.cpp:210
void g_ResumeNetSchedule(CNetScheduleAPI netschedule_api)
Definition: util.cpp:817
CJsonNode s_GetBlobMeta(const CNetCacheKey &key)
Definition: util.cpp:844
void g_ProcessJobInfo(CNetScheduleAPI ns_api, const string &job_key, IJobInfoProcessor *processor, bool verbose, CCompoundIDPool::TInstance id_pool)
Definition: util.cpp:572
static void PrintJSONNode(FILE *output_stream, CJsonNode node, const char *indent, int struct_indent_depth=0, const char *struct_prefix="", int scalar_indent_depth=0, const char *scalar_prefix="")
Definition: util.cpp:665
void g_SuspendNetSchedule(CNetScheduleAPI netschedule_api, bool pullback_mode)
Definition: util.cpp:808
static const string s_JobType
Definition: util.cpp:324
void g_ResumeWorkerNode(CNetServer worker_node)
Definition: util.cpp:839
void g_PrintJSON(FILE *output_stream, CJsonNode node, const char *indent)
Definition: util.cpp:738
CJsonNode g_QueueInfoToJson(CNetScheduleAPI ns_api, const string &queue_name)
Definition: util.cpp:194
CJsonNode g_WhatIs(const string &id, CCompoundIDPool id_pool)
Definition: util.cpp:876
void g_SuspendWorkerNode(CNetServer worker_node, bool pullback_mode, unsigned timeout)
Definition: util.cpp:826
CArgException –.
Definition: ncbiargs.hpp:120
ENextAttributeType NextAttribute(CTempString *attr_name, string *attr_value, size_t *attr_column)
void Reset(const char *position, const char *eol)
static int x_GetTypeAndName(CNcbiIstream &istream, string &name)
Definition: remote_app.cpp:98
CCgiRequest::
Definition: ncbicgi.hpp:685
Exception class for use by CCompoundIDPool, CCompoundID, and CCompoundIDField.
Definition: compound_id.hpp:91
Pool of recycled CCompoundID objects.
virtual CJsonNode ExecOn(CNetServer server)
Definition: util.cpp:65
CExecAndParseStructuredOutput(const string &cmd)
Definition: util.cpp:52
CJsonNode m_UnparsableLines
Definition: util.hpp:95
virtual void ProcessInput(const string &data)
Definition: util.cpp:532
virtual void ProcessJobEventField(const CTempString &attr_name, const string &attr_value)
Definition: util.cpp:245
CJsonNode m_JobEvents
Definition: util.hpp:93
CJsonNode m_CurrentEvent
Definition: util.hpp:94
CJsonNode GetRootNode() const
Definition: util.hpp:89
CJsonNode m_JobInfo
Definition: util.hpp:92
virtual void BeginJobEvent(const CTempString &event_header)
Definition: util.cpp:237
virtual void ProcessOutput(const string &data)
Definition: util.cpp:541
virtual void ProcessJobInfoField(const CTempString &field_name, const CTempString &field_value)
Definition: util.cpp:553
virtual void ProcessJobMeta(const CNetScheduleKey &key)
Definition: util.cpp:226
virtual void ProcessRawLine(const string &line)
Definition: util.cpp:563
Iterator for JSON arrays and objects.
JSON node abstraction.
Int8 AsInteger() const
Provided that this is a numeric node (that is, either an integer or a floating point node),...
static CJsonNode NewArrayNode()
Create a new JSON array node.
static CJsonNode GuessType(const CTempString &value)
Guess the type of a JSON scalar from the string representation of its value and initialize a new node...
bool HasKey(const string &key) const
Check if an object node has an element accessible by the specified key.
static CJsonNode ParseJSON(const string &json, TParseFlags flags=0)
void DeleteByKey(const string &key)
Delete an element referred to by the specified key from a JSON object.
SJsonIteratorImpl * Iterate(EIterationMode mode=eNatural) const
For a container node (that is, either an array or an object), begin iteration over its elements.
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 AppendString(const string &value)
For an array node, add a string node at the end of the array.
const string AsString() const
Provided that this is a string node, return the string value of this node.
string GetString(const string &key) const
For a JSON object node, return the string referred to by the specified key.
void SetBoolean(const string &key, bool value)
Set a JSON object element to the specified boolean value.
bool AsBoolean() const
Provided that this is a boolean node, return the boolean value of this node.
ENodeType GetNodeType() const
Return a ENodeType constant identifying the node type.
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 NewStringNode(const string &value)
Create a new JSON string node.
static CJsonNode NewObjectNode()
Create a new JSON object node.
void Append(CJsonNode::TInstance value)
For an array node, add a new element at the end of the array.
double AsDouble() const
Provided that this is a numeric node (that is, either a floating point or an integer node),...
CNcbiEnvironment –.
Definition: ncbienv.hpp:104
Client API for NCBI NetSchedule server.
void GetQueueInfo(CNetServer server, const string &queue_name, TQueueInfo &queue_info)
void DumpJob(CNcbiOstream &out, const string &job_key)
CNetServerInfo GetServerInfo()
Retrieve basic information about the server as attribute name-value pairs.
SExecResult ExecWithRetry(const string &cmd, bool multiline_output=false)
Execute remote command 'cmd', wait for the reply, check if it starts with 'OK:', and return the remai...
void ExecOnAllServers(const string &cmd)
CJsonNode MkNetStorageRequest(const string &request_type)
CJsonNode ExchangeJson(const CJsonNode &request, CNetServer::TInstance server_to_use=NULL, CNetServerConnection *conn=NULL)
Exception class for use by CNetStorage, CNetStorageByKey, and CNetStorageObject.
Definition: netstorage.hpp:67
void ToJSON(CJsonNode &root) const
Note about the "buf_size" parameter for streams in this API.
Definition: rwstream.hpp:122
Reader-writer-based stream buffer.
Definition: rwstreambuf.hpp:60
Remote Application Request (both client side and application executor side)
Definition: remote_app.hpp:96
bool IsExclusiveMode() const
Definition: remote_app.hpp:137
const string & GetInBlobIdOrData() const
Definition: remote_app.hpp:154
const string & GetCmdLine() const
Get the command line of the remote application.
Definition: remote_app.hpp:108
bool x_Deserialize(CNcbiIstream &is, TStoredFiles *files=NULL)
Definition: remote_app.cpp:225
unsigned int GetAppRunTimeout() const
Definition: remote_app.hpp:111
Remote Application Result (both client side and application executor side)
Definition: remote_app.hpp:209
String or Blob Storage Reader.
static EType x_GetDataType(string &data)
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTime –.
Definition: ncbitime.hpp:296
This class is for use by the grid_cli utility only.
virtual void ProcessJobMeta(const CNetScheduleKey &key)=0
virtual void ProcessRawLine(const string &line)=0
virtual void ProcessJobEventField(const CTempString &attr_name, const string &attr_value)=0
virtual void BeginJobEvent(const CTempString &event_header)=0
virtual void ProcessInput(const string &data)=0
virtual void ProcessOutput(const string &data)=0
virtual void ProcessJobInfoField(const CTempString &field_name, const CTempString &field_value)=0
const string m_Command
Definition: util.hpp:138
CExecToJson(CNetStorageAdmin::TInstance, const string &)
Definition: util.cpp:927
virtual CJsonNode ExecOn(CNetServer) override
Definition: util.cpp:934
CNetStorageAdmin m_NetStorageAdmin
Definition: util.hpp:137
container_type::const_iterator const_iterator
Definition: map.hpp:53
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
bool empty() const
Definition: map.hpp:149
char value[7]
Definition: config.c:431
string g_NetService_TryResolveHost(const string &ip_or_hostname)
Definition: util.cpp:186
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static const struct name_t names[]
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
const CNcbiEnvironment & GetEnvironment() const
Definition: ncbicgi.hpp:891
const string & GetRequestMethodName(void) const
Get request method name.
Definition: ncbicgi.cpp:1804
@ fDoNotParseContent
do not automatically parse the request's content body (from "istr")
Definition: ncbicgi.hpp:712
@ fIgnoreQueryString
do not parse $QUERY_STRING (or cmd.line if $REQUEST_METHOD not def)
Definition: ncbicgi.hpp:708
#define NULL
Definition: ncbistd.hpp:225
static bool ParseBlobKey(const char *key_str, size_t key_len, CNetCacheKey *key_obj, CCompoundIDPool::TInstance id_pool=NULL)
Parse blob key string into a CNetCacheKey structure.
EJobStatus
Job status codes.
string output
Job result data.
bool ParseJobKey(const string &key_str, CCompoundIDPool::TInstance id_pool=NULL)
EJobStatus GetJobDetails(CNetScheduleJob &job, time_t *job_exptime=NULL, ENetScheduleQueuePauseMode *pause_mode=NULL)
Get job details.
static string StatusToString(EJobStatus status)
Printable status type.
string input
Input data.
unsigned version
Key version.
CNetService GetService()
static EJobStatus StringToStatus(const CTempString &status_str)
Parse status string into enumerator value.
CNetScheduleAdmin GetAdmin()
string job_id
Output job key.
@ eDone
Job is ready (computed successfully)
@ eConfirmed
Final state - read confirmed.
@ eReading
Job has its output been reading.
@ eJobNotFound
No such job.
@ eReadFailed
Final state - read failed.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
static string PrintableString(const CTempString str, TPrintableMode mode=fNewLine_Quote|fNonAscii_Passthru)
Get a printable version of the specified string.
Definition: ncbistr.cpp:3949
static CTempString TruncateSpaces_Unsafe(const CTempString str, ETrunc where=eTrunc_Both)
Truncate spaces in a string.
Definition: ncbistr.cpp:3187
static Int8 StringToInt8(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to Int8.
Definition: ncbistr.cpp:793
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
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3550
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
static string ParseQuoted(const CTempString str, size_t *n_read=NULL)
Discard C-style backslash escapes and extract a quoted string.
Definition: ncbistr.cpp:4923
@ fSplit_Truncate
Definition: ncbistr.hpp:2501
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
@ eTrunc_Begin
Truncate leading spaces only.
Definition: ncbistr.hpp:2240
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
#define TEMP_STRING_CTOR(str)
Definition: util.hpp:79
FILE * file
int i
void RemoveStdReplyFields(CJsonNode &server_reply)
Definition: util.cpp:919
const struct ncbi::grid::netcache::search::fields::KEY key
int isspace(Uchar c)
Definition: ncbictype.hpp:69
string g_UnquoteIfQuoted(const CTempString &str)
bool g_FixMisplacedPID(CJsonNode &stat_info, CTempString &executable_path, const char *pid_key)
const char * command
CJsonNode g_ExecToJson(IExecToJson &exec_to_json, CNetService service, CNetService::EIterationMode iteration_mode=CNetService::eSortByLoad)
This function is for use by the grid_cli utility only.
void g_AppendClientIPSessionIDHitID(string &cmd)
static BOOL multiline
Definition: pcregrep.c:192
static const char * prefix[]
Definition: pcregrep.c:405
static SQLCHAR output[256]
Definition: print.c:5
true_type verbose
Definition: processing.cpp:902
@ eLocalFile
Definition: remote_app.hpp:51
Reader-writer based streams.
CSeq_id_Mapper TInstance
string indent(" ")
#define TOKEN_TYPE__NETCACHE_BLOB_KEY
Definition: util.hpp:118
#define TOKEN_TYPE__NETSTORAGEOBJECT_LOC
Definition: util.hpp:120
#define TOKEN_TYPE__NETSCHEDULE_JOB_KEY
Definition: util.hpp:119
const bool m_NewNode
Definition: util.cpp:321
CJsonNodeUpdater(const string &name, CJsonNode parent)
Definition: util.cpp:303
const string m_Name
Definition: util.cpp:319
CJsonNode node
Definition: util.cpp:301
CJsonNode m_Parent
Definition: util.cpp:320
Meaningful information encoded in the NetCache key.
Job description.
Meaningful information encoded in the NetSchedule key.
static bool AddNode(CJsonNode parent, const string &name, string data)
Definition: util.cpp:282
static CJsonNode x_CreateNode(EType type, const string &data)
Definition: util.cpp:259
static void AddNodes(CJsonNode parent, const string &name, const string &src)
Definition: util.cpp:291
virtual CJsonNode ExecOn(CNetServer server)
Definition: util.cpp:757
bool m_Multiline
Definition: util.cpp:754
string m_Cmd
Definition: util.cpp:753
SExecAnyCmdToJson(const string &cmd, bool multiline)
Definition: util.cpp:746
SStringStream(const string &data)
Definition: util.cpp:487
static bool Input(const string &data, CJsonNode &node)
Definition: util.cpp:497
static void Output(const string &data, CJsonNode &node)
Definition: util.cpp:515
SQueueInfoToJson(const string &cmd, const string &section_prefix)
Definition: util.cpp:157
string m_Cmd
Definition: util.cpp:165
string m_SectionPrefix
Definition: util.cpp:166
virtual CJsonNode ExecOn(CNetServer server)
Definition: util.cpp:169
SRequest(CNcbiIstream &is)
Definition: util.cpp:383
TStoredFiles m_Files
Definition: util.cpp:414
CJsonNode CreateFilesNode() const
Definition: util.cpp:391
static CJsonNode x_CreateArgsNode(const string &data, CJsonNode files)
Definition: util.cpp:359
static void Input(CJsonNode &node, SRequest &request)
Definition: util.cpp:417
static const string & Name()
Definition: util.cpp:336
static CJsonNode x_CreateDataNode(string data)
Definition: util.cpp:367
static bool x_GetFileName(string &data)
Definition: util.cpp:345
static void Output(CJsonNode &node, CRStream &stream, const string &)
Definition: util.cpp:426
SRequest(CRStream &stream)
Definition: util.cpp:451
static void Input(CJsonNode &node, SRequest &request)
Definition: util.cpp:456
static const string & Name()
Definition: util.cpp:440
static void Output(CJsonNode &node, CRStream &stream, const string &data)
Definition: util.cpp:470
virtual CJsonNode ExecOn(CNetServer server)
Definition: util.cpp:794
SServerInfoToJson(bool server_version_key)
Definition: util.cpp:784
bool m_ServerVersionKey
Definition: util.cpp:791
CNetScheduleAdmin m_NetScheduleAdmin
Definition: util.cpp:137
virtual CJsonNode ExecOn(CNetServer server)
Definition: util.cpp:141
SSingleQueueInfoToJson(const CNetScheduleAdmin &ns_admin, const string &queue_name)
Definition: util.cpp:129
Definition: type.c:6
static int failure
Definition: t0019.c:11
else result
Definition: token2.c:20
static HENV env
Definition: transaction2.c:38
Modified on Thu Nov 30 04:57:35 2023 by modify_doxy.py rev. 669887