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

Go to the SVN repository for this file.

1 /* $Id: pubseq_gateway_utils.cpp 101697 2024-01-26 18:43:53Z satskyse $
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: Sergey Satskiy
27  *
28  * File Description:
29  *
30  */
31 #include <ncbi_pch.hpp>
32 
33 #include <corelib/ncbistr.hpp>
35 
36 #include "pubseq_gateway_utils.hpp"
37 #include "psgs_request.hpp"
38 #include "psgs_reply.hpp"
39 
42 
43 
44 // see CXX-10728
45 // Need to replace the found accession with the seq_ids found accession
47 SBioseqResolution::AdjustAccession(shared_ptr<CPSGS_Request> request,
48  shared_ptr<CPSGS_Reply> reply)
49 {
52  m_AdjustmentTried = true;
53 
55  m_AdjustmentError = "BIOSEQ_INFO accession adjustment logic error. The "
56  "data are not ready for adjustments.";
59  }
60 
61  auto seq_id_type = m_BioseqInfo.GetSeqIdType();
62  if (m_BioseqInfo.GetVersion() > 0 && seq_id_type != CSeq_id::e_Gi) {
63  if (request->NeedTrace())
64  reply->SendTrace("No need to adjust accession",
65  request->GetStartTimestamp());
66 
69  }
70 
71  auto & seq_ids = m_BioseqInfo.GetSeqIds();
72  for (const auto & seq_id : seq_ids) {
73  if (get<0>(seq_id) == CSeq_id::e_Gi) {
74  string orig_accession = m_BioseqInfo.GetAccession();
75  auto orig_seq_id_type = m_BioseqInfo.GetSeqIdType();
76 
77  m_BioseqInfo.SetAccession(get<1>(seq_id));
79 
80  seq_ids.erase(seq_id);
81  if (orig_seq_id_type != CSeq_id::e_Gi)
82  seq_ids.insert(make_tuple(orig_seq_id_type, orig_accession));
83 
84  if (request->NeedTrace())
85  reply->SendTrace("Accession adjusted with Gi",
86  request->GetStartTimestamp());
87 
90  }
91  }
92 
93  if (seq_ids.empty()) {
94  m_AdjustmentError = "BIOSEQ_INFO data inconsistency. Accession " +
95  m_BioseqInfo.GetAccession() + " needs to be "
96  "adjusted but the seq_ids list is empty.";
99  }
100 
101  // Adjusted with any
102  string orig_accession = m_BioseqInfo.GetAccession();
103  auto orig_seq_id_type = m_BioseqInfo.GetSeqIdType();
104 
105  auto first_seq_id = seq_ids.begin();
106  m_BioseqInfo.SetAccession(get<1>(*first_seq_id));
107  m_BioseqInfo.SetSeqIdType(get<0>(*first_seq_id));
108 
109  seq_ids.erase(*first_seq_id);
110  if (orig_seq_id_type != CSeq_id::e_Gi)
111  seq_ids.insert(make_tuple(orig_seq_id_type, orig_accession));
112 
113  if (request->NeedTrace())
114  reply->SendTrace("Accession adjusted with type " +
115  to_string(m_BioseqInfo.GetSeqIdType()) +
116  " (first from the seq_ids list)",
117  request->GetStartTimestamp());
118 
121 }
122 
123 
124 
125 static string s_ProtocolPrefix = "\n\nPSG-Reply-Chunk: ";
126 
127 // Names
128 static string s_ItemId = "item_id=";
129 static string s_ItemType = "item_type=";
130 static string s_ChunkType = "chunk_type=";
131 static string s_Size = "size=";
132 static string s_BlobChunk = "blob_chunk=";
133 static string s_NChunks = "n_chunks=";
134 static string s_Status = "status=";
135 static string s_Code = "code=";
136 static string s_Severity = "severity=";
137 static string s_BlobId = "blob_id=";
138 static string s_Fmt = "fmt=";
139 static string s_NA = "na=";
140 static string s_Reason = "reason=";
141 static string s_TimeUntilResend = "time_until_resend=";
142 static string s_SentSecondsAgo = "sent_seconds_ago=";
143 static string s_NChunksOne = "n_chunks=1";
144 static string s_ProcessorId = "processor_id=";
145 static string s_Id2Chunk = "id2_chunk=";
146 static string s_Id2Info = "id2_info=";
147 static string s_LastModified = "last_modified=";
148 static string s_Progress = "progress=";
149 static string s_ExecTime = "exec_time=";
150 
151 // Fixed values
152 static string s_BioseqInfo = "bioseq_info";
153 static string s_BlobProp = "blob_prop";
154 static string s_Data = "data";
155 static string s_DataAndMeta = "data_and_meta";
156 static string s_MessageAndMeta = "message_and_meta";
157 static string s_Reply = "reply";
158 static string s_Blob = "blob";
159 static string s_Meta = "meta";
160 static string s_Message = "message";
161 static string s_Protobuf = "protobuf";
162 static string s_Json = "json";
163 static string s_BioseqNA = "bioseq_na";
164 static string s_NAStatus = "na_status";
165 static string s_AccVerHistory = "acc_ver_history";
166 static string s_IPGInfo = "ipg_info";
167 static string s_Excluded = "excluded";
168 static string s_InProgress = "inprogress";
169 static string s_Sent = "sent";
170 static string s_Processor = "processor";
171 static string s_PublicComment = "public_comment";
172 
173 // Combinations
174 static string s_AndSize = "&" + s_Size;
175 static string s_AndStatus = "&" + s_Status;
176 static string s_AndCode = "&" + s_Code;
177 static string s_AndSeverity = "&" + s_Severity;
178 static string s_AndNChunks = "&" + s_NChunks;
179 static string s_AndBlobId = "&" + s_BlobId;
180 static string s_AndBlobChunk = "&" + s_BlobChunk;
181 static string s_AndNChunksOne = "&" + s_NChunksOne;
182 static string s_AndReason = "&" + s_Reason;
184 static string s_AndSentSecondsAgo = "&" + s_SentSecondsAgo;
185 static string s_AndNA = "&" + s_NA;
187 static string s_AndBioseqInfoItem = "&" + s_BioseqInfoItem;
189 static string s_AndBlobPropItem = "&" + s_BlobPropItem;
191 static string s_AndBioseqNAItem = "&" + s_BioseqNAItem;
193 static string s_AndNAStatusItem = "&" + s_NAStatusItem;
197 static string s_AndIPGInfoItem = "&" + s_IPGInfoItem;
198 static string s_BlobItem = s_ItemType + s_Blob;
199 static string s_AndBlobItem = "&" + s_BlobItem;
200 static string s_ReplyItem = s_ItemType + s_Reply;
201 static string s_AndReplyItem = "&" + s_ReplyItem;
204 static string s_AndProcessorItem = "&" + s_ProcessorItem;
206 static string s_AndProcessorId = "&" + s_ProcessorId;
207 static string s_AndId2Chunk = "&" + s_Id2Chunk;
208 static string s_AndId2Info = "&" + s_Id2Info;
209 static string s_AndLastModified = "&" + s_LastModified;
210 static string s_AndProgress = "&" + s_Progress;
211 
212 static string s_DataChunk = s_ChunkType + s_Data;
214 static string s_AndDataChunk = "&" + s_DataChunk;
218 static string s_MetaChunk = s_ChunkType + s_Meta;
219 static string s_AndMetaChunk = "&" + s_MetaChunk;
221 static string s_AndMessageChunk = "&" + s_MessageChunk;
222 static string s_FmtJson = s_Fmt + s_Json;
223 static string s_AndFmtJson = "&" + s_FmtJson;
224 static string s_FmtProtobuf = s_Fmt + s_Protobuf;
225 static string s_AndFmtProtobuf = "&" + s_FmtProtobuf;
226 static string s_AndExecTime = "&" + s_ExecTime;
227 
229 static string s_ReplyCompletionFixedPart = s_ReplyBegin + "0&" +
230  s_ReplyItem + "&" +
231  s_MetaChunk + "&" + s_NChunks;
232 
233 
234 static string SeverityToLowerString(EDiagSev severity)
235 {
236  string severity_as_string = CNcbiDiag::SeverityName(severity);
237  NStr::ToLower(severity_as_string);
238  return severity_as_string;
239 }
240 
241 
242 static string SkipReasonToString(EPSGS_BlobSkipReason skip_reason)
243 {
244  switch (skip_reason) {
245  case ePSGS_BlobExcluded:
246  return s_Excluded;
248  return s_InProgress;
249  case ePSGS_BlobSent:
250  return s_Sent;
251  }
252  return "UnknownSkipReason";
253 }
254 
255 
258  s_AndSize;
259 string GetBioseqInfoHeader(size_t item_id,
260  const string & processor_id,
261  size_t bioseq_info_size,
263 {
264  // E.g. PSG-Reply-Chunk: item_id=1&processor_id=get+blob+proc&item_type=bioseq_info&chunk_type=data&size=450&fmt=protobuf
265  string reply(s_ReplyBegin);
266  char buf[64];
267  long len;
268 
269  len = PSGToString(item_id, buf);
270  reply.append(buf, len)
271  .append(s_AndProcessorId)
272  .append(NStr::URLEncode(processor_id))
274 
275  len = PSGToString(bioseq_info_size, buf);
276  reply.append(buf, len);
277  if (output_format == SPSGS_ResolveRequest::ePSGS_JsonFormat)
278  reply.append(s_AndFmtJson);
279  else
280  reply.append(s_AndFmtProtobuf);
281  reply.append(1, '\n');
282  return reply;
283 }
284 
285 
286 string GetBioseqMessageHeader(size_t item_id,
287  const string & processor_id,
288  size_t msg_size,
289  CRequestStatus::ECode status,
290  int code,
291  EDiagSev severity)
292 {
293  string reply(s_ReplyBegin);
294  char buf[64];
295  long len;
296 
297  len = PSGToString(item_id, buf);
298  reply.append(buf, len)
299  .append(s_AndProcessorId)
300  .append(NStr::URLEncode(processor_id))
301  .append(s_AndBioseqInfoItem)
302  .append(s_AndMessageChunk)
303  .append(s_AndSize);
304 
305  len = PSGToString(msg_size, buf);
306  reply.append(buf, len)
307  .append(s_AndStatus);
308 
309  len = PSGToString(static_cast<int>(status), buf);
310  reply.append(buf, len)
311  .append(s_AndCode);
312 
313  len = PSGToString(code, buf);
314  reply.append(buf, len)
315  .append(s_AndSeverity)
316  .append(SeverityToLowerString(severity))
317  .append(1, '\n');
318  return reply;
319 }
320 
321 
322 string GetBioseqCompletionHeader(size_t item_id,
323  const string & processor_id,
324  size_t chunk_count)
325 {
326  // E.g. PSG-Reply-Chunk: item_id=1&processor_id=get+blob+proc&item_type=bioseq_info&chunk_type=meta&n_chunks=1
327  string reply(s_ReplyBegin);
328  char buf[64];
329  long len;
330 
331  len = PSGToString(item_id, buf);
332  reply.append(buf, len)
333  .append(s_AndProcessorId)
334  .append(NStr::URLEncode(processor_id))
335  .append(s_AndBioseqInfoItem)
336  .append(s_AndMetaChunk)
337  .append(s_AndNChunks);
338 
339  len = PSGToString(chunk_count, buf);
340  reply.append(buf, len)
341  .append(1, '\n');
342  return reply;
343 }
344 
345 
346 string GetBlobPropHeader(size_t item_id,
347  const string & processor_id,
348  const string & blob_id,
349  size_t blob_prop_size,
350  CBlobRecord::TTimestamp last_modified)
351 {
352  string reply(s_ReplyBegin);
353  char buf[64];
354  long len;
355 
356  string last_modified_part;
357  if (last_modified != -1) {
358  len = PSGToString(last_modified, buf);
359  last_modified_part.append(s_AndLastModified)
360  .append(buf, len);
361  }
362 
363  len = PSGToString(item_id, buf);
364  reply.append(buf, len)
365  .append(s_AndProcessorId)
366  .append(NStr::URLEncode(processor_id))
367  .append(s_AndBlobPropItem)
368  .append(s_AndDataChunk)
369  .append(s_AndSize);
370 
371  len = PSGToString(blob_prop_size, buf);
372  reply.append(buf, len)
373  .append(s_AndBlobId)
374  .append(blob_id)
375  .append(last_modified_part)
376  .append(1, '\n');
377  return reply;
378 }
379 
380 string GetTSEBlobPropHeader(size_t item_id,
381  const string & processor_id,
382  int64_t id2_chunk,
383  const string & id2_info,
384  size_t blob_prop_size)
385 {
386  // E.g. PSG-Reply-Chunk: item_id=2&processor_id=get+blob+proc&item_type=blob_prop&chunk_type=data&size=550
387  char buf[64];
388  long len;
389  string reply(s_ReplyBegin);
390 
391  len = PSGToString(item_id, buf);
392  reply.append(buf, len)
393  .append(s_AndProcessorId)
394  .append(NStr::URLEncode(processor_id))
395  .append(s_AndBlobPropItem)
396  .append(s_AndDataChunk)
397  .append(s_AndSize);
398 
399  len = PSGToString(blob_prop_size, buf);
400  reply.append(buf, len)
401  .append(s_AndId2Chunk);
402 
403  len = PSGToString(id2_chunk, buf);
404  reply.append(buf, len)
405  .append(s_AndId2Info)
406  .append(id2_info)
407  .append(1, '\n');
408  return reply;
409 }
410 
411 
412 string GetBlobPropMessageHeader(size_t item_id,
413  const string & processor_id,
414  size_t msg_size,
415  CRequestStatus::ECode status,
416  int code,
417  EDiagSev severity)
418 {
419  char buf[64];
420  long len;
421  string reply(s_ReplyBegin);
422 
423  len = PSGToString(item_id, buf);
424  reply.append(buf, len)
425  .append(s_AndProcessorId)
426  .append(NStr::URLEncode(processor_id))
427  .append(s_AndBlobPropItem)
428  .append(s_AndMessageChunk)
429  .append(s_AndSize);
430 
431  len = PSGToString(msg_size, buf);
432  reply.append(buf, len)
433  .append(s_AndStatus);
434 
435  len = PSGToString(static_cast<int>(status), buf);
436  reply.append(buf, len)
437  .append(s_AndCode);
438 
439  len = PSGToString(code, buf);
440  reply.append(buf, len)
441  .append(s_AndSeverity)
442  .append(SeverityToLowerString(severity))
443  .append(1, '\n');
444  return reply;
445 }
446 
447 
448 string GetTSEBlobPropMessageHeader(size_t item_id,
449  const string & processor_id,
450  int64_t id2_chunk,
451  const string & id2_info,
452  size_t msg_size,
453  CRequestStatus::ECode status,
454  int code,
455  EDiagSev severity)
456 {
457  char buf[64];
458  long len;
459  string reply(s_ReplyBegin);
460 
461  len = PSGToString(item_id, buf);
462  reply.append(buf, len)
463  .append(s_AndProcessorId)
464  .append(NStr::URLEncode(processor_id))
465  .append(s_AndId2Chunk);
466 
467  len = PSGToString(id2_chunk, buf);
468  reply.append(buf, len)
469  .append(s_AndId2Info)
470  .append(id2_info)
471  .append(s_AndBlobPropItem)
472  .append(s_AndMessageChunk)
473  .append(s_AndSize);
474 
475  len = PSGToString(msg_size, buf);
476  reply.append(buf, len)
477  .append(s_AndStatus);
478 
479  len = PSGToString(static_cast<int>(status), buf);
480  reply.append(buf, len)
481  .append(s_AndCode);
482 
483  len = PSGToString(code, buf);
484  reply.append(buf, len)
485  .append(s_AndSeverity)
486  .append(SeverityToLowerString(severity))
487  .append(1, '\n');
488  return reply;
489 }
490 
491 string GetBlobPropCompletionHeader(size_t item_id,
492  const string & processor_id,
493  size_t chunk_count)
494 {
495  char buf[64];
496  long len;
497  string reply(s_ReplyBegin);
498 
499  len = PSGToString(item_id, buf);
500  reply.append(buf, len)
501  .append(s_AndProcessorId)
502  .append(NStr::URLEncode(processor_id))
503  .append(s_AndBlobPropItem)
504  .append(s_AndMetaChunk)
505  .append(s_AndNChunks);
506 
507  len = PSGToString(chunk_count, buf);
508  reply.append(buf, len)
509  .append(1, '\n');
510  return reply;
511 }
512 
513 
514 string GetTSEBlobPropCompletionHeader(size_t item_id,
515  const string & processor_id,
516  size_t chunk_count)
517 {
518  char buf[64];
519  long len;
520  string reply(s_ReplyBegin);
521 
522  len = PSGToString(item_id, buf);
523  reply.append(buf, len)
524  .append(s_AndProcessorId)
525  .append(NStr::URLEncode(processor_id))
526  .append(s_AndBlobPropItem)
527  .append(s_AndMetaChunk)
528  .append(s_AndNChunks);
529 
530  len = PSGToString(chunk_count, buf);
531  reply.append(buf, len)
532  .append(1, '\n');
533  return reply;
534 }
535 
536 
537 string GetBlobChunkHeader(size_t item_id,
538  const string & processor_id,
539  const string & blob_id,
540  size_t chunk_size,
541  size_t chunk_number,
542  CBlobRecord::TTimestamp last_modified)
543 {
544  // E.g. PSG-Reply-Chunk: item_id=3&processor_id=get+blob+proc&item_type=blob&chunk_type=data&size=2345&blob_id=333.444&blob_chunk=37
545  char buf[64];
546  long len;
547  string reply(s_ReplyBegin);
548 
549  string last_modified_part;
550  if (last_modified != -1) {
551  len = PSGToString(last_modified, buf);
552  last_modified_part.append(s_AndLastModified)
553  .append(buf, len);
554  }
555 
556  len = PSGToString(item_id, buf);
557  reply.append(buf, len)
558  .append(s_AndProcessorId)
559  .append(NStr::URLEncode(processor_id))
560  .append(s_AndBlobItem)
561  .append(s_AndDataChunk)
562  .append(s_AndSize);
563 
565  reply.append(buf, len)
566  .append(s_AndBlobId)
567  .append(blob_id)
568  .append(last_modified_part)
569  .append(s_AndBlobChunk);
570 
571  len = PSGToString(chunk_number, buf);
572  reply.append(buf, len)
573  .append(1, '\n');
574  return reply;
575 }
576 
577 
578 string GetTSEBlobChunkHeader(size_t item_id,
579  const string & processor_id,
580  size_t chunk_size,
581  size_t chunk_number,
582  int64_t id2_chunk,
583  const string & id2_info)
584 {
585  // E.g. PSG-Reply-Chunk:
586  // item_id=3&processor_id=get+blob+proc&item_type=blob&chunk_type=data&size=2345&id2_chunk=11&id2_info=33.44.55&blob_chunk=37
587  char buf[64];
588  long len;
589  string reply(s_ReplyBegin);
590 
591  len = PSGToString(item_id, buf);
592  reply.append(buf, len)
593  .append(s_AndProcessorId)
594  .append(NStr::URLEncode(processor_id))
595  .append(s_AndBlobItem)
596  .append(s_AndDataChunk)
597  .append(s_AndSize);
598 
600  reply.append(buf, len)
601  .append(s_AndBlobChunk);
602 
603  len = PSGToString(chunk_number, buf);
604  reply.append(buf, len)
605  .append(s_AndId2Chunk);
606 
607  len = PSGToString(id2_chunk, buf);
608  reply.append(buf, len)
609  .append(s_AndId2Info)
610  .append(id2_info)
611  .append(1, '\n');
612  return reply;
613 }
614 
615 
616 string GetBlobExcludeHeader(size_t item_id,
617  const string & processor_id,
618  const string & blob_id,
619  EPSGS_BlobSkipReason skip_reason,
620  CBlobRecord::TTimestamp last_modified)
621 {
622  // E.g. PSG-Reply-Chunk: item_id=5&processor_id=get+blob+proc&item_type=blob&chunk_type=meta&blob_id=555.666&n_chunks=1&reason={excluded,inprogress,sent}
623  char buf[64];
624  long len;
625  string reply(s_ReplyBegin);
626 
627  string last_modified_part;
628  if (last_modified != -1) {
629  len = PSGToString(last_modified, buf);
630  last_modified_part.append(s_AndLastModified)
631  .append(buf, len);
632  }
633 
634  len = PSGToString(item_id, buf);
635  reply.append(buf, len)
636  .append(s_AndProcessorId)
637  .append(NStr::URLEncode(processor_id))
638  .append(s_AndBlobItem)
639  .append(s_AndMetaChunk)
640  .append(s_AndBlobId)
641  .append(blob_id)
642  .append(last_modified_part)
643  .append(s_AndNChunksOne)
644  .append(s_AndReason)
645  .append(SkipReasonToString(skip_reason))
646  .append(1, '\n');
647  return reply;
648 }
649 
650 
651 // Used only for the case 'already sent'
652 string GetBlobExcludeHeader(size_t item_id,
653  const string & processor_id,
654  const string & blob_id,
655  unsigned long sent_mks_ago,
656  unsigned long until_resend_mks,
657  CBlobRecord::TTimestamp last_modified)
658 {
659  char buf[64];
660  long len;
661  string reply(s_ReplyBegin);
662 
663  string last_modified_part;
664  if (last_modified != -1) {
665  len = PSGToString(last_modified, buf);
666  last_modified_part.append(s_AndLastModified)
667  .append(buf, len);
668  }
669 
670  unsigned long ago_sec = sent_mks_ago / 1000000;
671  len = PSGToString(sent_mks_ago - ago_sec * 1000000, buf);
672  string ago_mks(buf, len);
673  while (ago_mks.size() < 6)
674  ago_mks = "0" + ago_mks;
675 
676  unsigned long until_sec = until_resend_mks / 1000000;
677  len = PSGToString(until_resend_mks - until_sec * 1000000, buf);
678  string until_mks(buf, len);
679  while (until_mks.size() < 6)
680  until_mks = "0" + until_mks;
681 
682  len = PSGToString(item_id, buf);
683  reply.append(buf, len)
684  .append(s_AndProcessorId)
685  .append(NStr::URLEncode(processor_id))
686  .append(s_AndBlobItem)
687  .append(s_AndMetaChunk)
688  .append(s_AndBlobId)
689  .append(blob_id)
690  .append(last_modified_part)
691  .append(s_AndNChunksOne)
692  .append(s_AndReason)
694  .append(s_AndSentSecondsAgo);
695 
696  len = PSGToString(ago_sec, buf);
697  reply.append(buf, len)
698  .append(1, '.')
699  .append(ago_mks)
700  .append(s_AndTimeUntilResend);
701 
702  len = PSGToString(until_sec, buf);
703  reply.append(buf, len)
704  .append(1, '.')
705  .append(until_mks)
706  .append(1, '\n');
707  return reply;
708 }
709 
710 
711 // NOTE: the blob id argument is temporary to satisfy the older clients
712 string GetTSEBlobExcludeHeader(size_t item_id,
713  const string & processor_id,
714  const string & blob_id,
715  EPSGS_BlobSkipReason skip_reason,
716  int64_t id2_chunk,
717  const string & id2_info)
718 {
719  // E.g. PSG-Reply-Chunk: item_id=5&processor_id=get+blob+proc&item_type=blob&chunk_type=meta&blob_id=555.666&n_chunks=1&reason={excluded,inprogress,sent}
720  char buf[64];
721  long len;
722  string reply(s_ReplyBegin);
723 
724  len = PSGToString(item_id, buf);
725  reply.append(buf, len)
726  .append(s_AndProcessorId)
727  .append(NStr::URLEncode(processor_id))
728  .append(s_AndBlobItem)
729  .append(s_AndMetaChunk)
730 
731  // NOTE: the blob id argument is temporary to satisfy the older clients
732  .append(s_AndBlobId)
733  .append(blob_id)
734 
735  .append(s_AndId2Chunk);
736 
737  len = PSGToString(id2_chunk, buf);
738  reply.append(buf, len)
739  .append(s_AndId2Info)
740  .append(id2_info)
741  .append(s_AndNChunksOne)
742  .append(s_AndReason)
743  .append(SkipReasonToString(skip_reason))
744  .append(1, '\n');
745  return reply;
746 }
747 
748 
749 // Used only for the case 'already sent'
750 // NOTE: the blob id argument is temporary to satisfy the older clients
751 string GetTSEBlobExcludeHeader(size_t item_id,
752  const string & processor_id,
753  const string & blob_id,
754  int64_t id2_chunk,
755  const string & id2_info,
756  unsigned long sent_mks_ago,
757  unsigned long until_resend_mks)
758 {
759  char buf[64];
760  long len;
761  string reply(s_ReplyBegin);
762 
763  unsigned long ago_sec = sent_mks_ago / 1000000;
764  len = PSGToString(sent_mks_ago - ago_sec * 1000000, buf);
765  string ago_mks(buf, len);
766  while (ago_mks.size() < 6)
767  ago_mks = "0" + ago_mks;
768 
769  unsigned long until_sec = until_resend_mks / 1000000;
770  len = PSGToString(until_resend_mks - until_sec * 1000000, buf);
771  string until_mks(buf, len);
772  while (until_mks.size() < 6)
773  until_mks = "0" + until_mks;
774 
775  len = PSGToString(item_id, buf);
776  reply.append(buf, len)
777  .append(s_AndProcessorId)
778  .append(NStr::URLEncode(processor_id))
779  .append(s_AndBlobItem)
780  .append(s_AndMetaChunk)
781 
782  // NOTE: the blob id argument is temporary to satisfy the older clients
783  .append(s_AndBlobId)
784  .append(blob_id)
785 
786  .append(s_AndId2Chunk);
787 
788  len = PSGToString(id2_chunk, buf);
789  reply.append(buf, len)
790  .append(s_AndId2Info)
791  .append(id2_info)
792  .append(s_AndNChunksOne)
793  .append(s_AndReason)
795  .append(s_AndSentSecondsAgo);
796 
797  len = PSGToString(ago_sec, buf);
798  reply.append(buf, len)
799  .append(1, '.')
800  .append(ago_mks)
801  .append(s_AndTimeUntilResend);
802  len = PSGToString(until_sec, buf);
803  reply.append(buf, len)
804  .append(1, '.')
805  .append(until_mks)
806  .append(1, '\n');
807  return reply;
808 }
809 
810 
811 string GetBlobCompletionHeader(size_t item_id,
812  const string & processor_id,
813  size_t chunk_count)
814 {
815  // E.g. PSG-Reply-Chunk: item_id=4&processor_id=get+blob+proc&item_type=blob&chunk_type=meta&n_chunks=100
816  char buf[64];
817  long len;
818  string reply(s_ReplyBegin);
819 
820  len = PSGToString(item_id, buf);
821  reply.append(buf, len)
822  .append(s_AndProcessorId)
823  .append(NStr::URLEncode(processor_id))
824  .append(s_AndBlobItem)
825  .append(s_AndMetaChunk)
826  .append(s_AndNChunks);
827 
828  len = PSGToString(chunk_count, buf);
829  reply.append(buf, len)
830  .append(1, '\n');
831  return reply;
832 }
833 
834 
835 string GetTSEBlobCompletionHeader(size_t item_id,
836  const string & processor_id,
837  size_t chunk_count)
838 {
839  // E.g. PSG-Reply-Chunk:
840  // item_id=4&processor_id=get+blob+proc&item_type=blob&chunk_type=meta&n_chunks=100
841  char buf[64];
842  long len;
843  string reply(s_ReplyBegin);
844 
845  len = PSGToString(item_id, buf);
846  reply.append(buf, len)
847  .append(s_AndProcessorId)
848  .append(NStr::URLEncode(processor_id))
849  .append(s_AndBlobItem)
850  .append(s_AndMetaChunk)
851  .append(s_AndNChunks);
852 
853  len = PSGToString(chunk_count, buf);
854  reply.append(buf, len)
855  .append(1, '\n');
856  return reply;
857 }
858 
859 
860 string GetBlobMessageHeader(size_t item_id,
861  const string & processor_id,
862  const string & blob_id,
863  size_t msg_size,
864  CRequestStatus::ECode status,
865  int code,
866  EDiagSev severity,
867  CBlobRecord::TTimestamp last_modified)
868 {
869  // E.g. PSG-Reply-Chunk: item_id=3&processor_id=get+blob+proc&item_type=blob&chunk_type=message&size=22&blob_id=333.444&status=404&code=5&severity=critical
870  char buf[64];
871  long len;
872  string reply(s_ReplyBegin);
873 
874  string last_modified_part;
875  if (last_modified != -1) {
876  len = PSGToString(last_modified, buf);
877  last_modified_part.append(s_AndLastModified)
878  .append(buf, len);
879  }
880 
881  len = PSGToString(item_id, buf);
882  reply.append(buf, len)
883  .append(s_AndProcessorId)
884  .append(NStr::URLEncode(processor_id))
885  .append(s_AndBlobItem)
886  .append(s_AndMessageChunk)
887  .append(s_AndSize);
888 
889  len = PSGToString(msg_size, buf);
890  reply.append(buf, len)
891  .append(s_AndBlobId)
892  .append(blob_id)
893  .append(last_modified_part)
894  .append(s_AndStatus);
895 
896  len = PSGToString(static_cast<int>(status), buf);
897  reply.append(buf, len)
898  .append(s_AndCode);
899 
900  len = PSGToString(code, buf);
901  reply.append(buf, len)
902  .append(s_AndSeverity)
903  .append(SeverityToLowerString(severity))
904  .append(1, '\n');
905  return reply;
906 }
907 
908 
909 string GetTSEBlobMessageHeader(size_t item_id,
910  const string & processor_id,
911  int64_t id2_chunk,
912  const string & id2_info,
913  size_t msg_size,
914  CRequestStatus::ECode status,
915  int code,
916  EDiagSev severity)
917 {
918  char buf[64];
919  long len;
920  string reply(s_ReplyBegin);
921 
922  len = PSGToString(item_id, buf);
923  reply.append(buf, len)
924  .append(s_AndProcessorId)
925  .append(NStr::URLEncode(processor_id))
926  .append(s_AndBlobItem)
927  .append(s_AndMessageChunk)
928  .append(s_AndSize);
929 
930  len = PSGToString(msg_size, buf);
931  reply.append(buf, len)
932  .append(s_AndId2Chunk);
933 
934  len = PSGToString(id2_chunk, buf);
935  reply.append(buf, len)
936  .append(s_AndId2Info)
937  .append(id2_info)
938  .append(s_AndStatus);
939 
940  len = PSGToString(static_cast<int>(status), buf);
941  reply.append(buf, len)
942  .append(s_AndCode);
943 
944  len = PSGToString(code, buf);
945  reply.append(buf, len)
946  .append(s_AndSeverity)
947  .append(SeverityToLowerString(severity))
948  .append(1, '\n');
949  return reply;
950 }
951 
952 
953 string GetReplyCompletionHeader(size_t chunk_count,
954  CRequestStatus::ECode status,
955  const psg_time_point_t & create_timestamp)
956 {
957  // E.g. PSG-Reply-Chunk: item_id=0&item_type=reply&chunk_type=meta&n_chunks=153&status=200&exec_time=231
958  char buf[64];
959  long len;
960  string reply(s_ReplyCompletionFixedPart);
961  auto now = psg_clock_t::now();
962  uint64_t mks = chrono::duration_cast<chrono::microseconds>
963  (now - create_timestamp).count();
964 
965  len = PSGToString(chunk_count, buf);
966  reply.append(buf, len);
967 
968  len = PSGToString(status, buf);
969  reply.append(s_AndStatus)
970  .append(buf, len)
971  .append(s_AndExecTime);
972 
973  len = PSGToString(mks, buf);
974  reply.append(buf, len)
975  .append(1, '\n');
976  return reply;
977 }
978 
979 
980 string GetReplyMessageHeader(size_t msg_size,
981  CRequestStatus::ECode status,
982  int code,
983  EDiagSev severity)
984 {
985  // E.g. PSG-Reply-Chunk: item_id=0&item_type=reply&chunk_type=message&size=22&status=404&code=5&severity=critical
986  char buf[64];
987  long len;
988  string reply(s_ReplyBegin);
989 
990  reply.append(1, '0')
991  .append(s_AndReplyItem)
992  .append(s_AndMessageChunk)
993  .append(s_AndSize);
994 
995  len = PSGToString(msg_size, buf);
996  reply.append(buf, len)
997  .append(s_AndStatus);
998 
999  len = PSGToString(static_cast<int>(status), buf);
1000  reply.append(buf, len)
1001  .append(s_AndCode);
1002 
1003  len = PSGToString(code, buf);
1004  reply.append(buf, len)
1005  .append(s_AndSeverity)
1006  .append(SeverityToLowerString(severity))
1007  .append(1, '\n');
1008  return reply;
1009 }
1010 
1011 
1013  const string & processor_id,
1014  const string & progress_status)
1015 {
1016  // E.g. PSG-Reply-Chunk: item_id=...&processor_id=...&item_type=processor&chunk_type=meta&n_chunks=1&progress=...
1017  char buf[64];
1018  long len;
1019  string reply(s_ReplyBegin);
1020 
1021  len = PSGToString(item_id, buf);
1022  reply.append(buf, len)
1023  .append(s_AndProcessorId)
1024  .append(NStr::URLEncode(processor_id))
1025  .append(s_AndProcessorItem)
1026  .append(s_AndMetaChunk)
1027  .append(s_AndNChunks)
1028  .append(1, '1')
1029  .append(s_AndProgress)
1030  .append(progress_status)
1031  .append(1, '\n');
1032  return reply;
1033 }
1034 
1035 
1036 string GetNamedAnnotationHeader(size_t item_id,
1037  const string & processor_id,
1038  const string & annot_name,
1039  size_t annotation_size)
1040 {
1041  // E.g. PSG-Reply-Chunk: item_id=1&processor_id=get+blob+proc&item_type=bioseq_na&chunk_type=data&size=150&na=NA000111.1
1042  char buf[64];
1043  long len;
1044  string reply(s_ReplyBegin);
1045 
1046  len = PSGToString(item_id, buf);
1047  reply.append(buf, len)
1048  .append(s_AndProcessorId)
1049  .append(NStr::URLEncode(processor_id))
1050  .append(s_AndBioseqNAItem)
1051  .append(s_AndDataChunk)
1052  .append(s_AndSize);
1053 
1054  len = PSGToString(annotation_size, buf);
1055  reply.append(buf, len)
1056  .append(s_AndNA)
1057  .append(annot_name)
1058  .append(1, '\n');
1059  return reply;
1060 }
1061 
1062 
1063 string GetNamedAnnotationMessageHeader(size_t item_id,
1064  const string & processor_id,
1065  size_t msg_size,
1066  CRequestStatus::ECode status,
1067  int code,
1068  EDiagSev severity)
1069 {
1070  // E.g. PSG-Reply-Chunk: item_id=5&processor_id=get+blob+proc&item_type=reply&chunk_type=message&size=22&status=404&code=5&severity=critical
1071 
1072  char buf[64];
1073  long len;
1074  string reply(s_ReplyBegin);
1075 
1076  len = PSGToString(item_id, buf);
1077  reply.append(buf, len)
1078  .append(s_AndProcessorId)
1079  .append(NStr::URLEncode(processor_id))
1080  .append(s_AndBioseqNAItem)
1081  .append(s_AndMessageChunk)
1082  .append(s_AndSize);
1083 
1084  len = PSGToString(msg_size, buf);
1085  reply.append(buf, len)
1086  .append(s_AndStatus);
1087 
1088  len = PSGToString(static_cast<long>(status), buf);
1089  reply.append(buf, len)
1090  .append(s_AndCode);
1091 
1092  len = PSGToString(code, buf);
1093  reply.append(buf, len)
1094  .append(s_AndSeverity)
1095  .append(SeverityToLowerString(severity))
1096  .append(1, '\n');
1097  return reply;
1098 }
1099 
1100 
1102  const string & processor_id,
1103  size_t chunk_count)
1104 {
1105  char buf[64];
1106  long len;
1107  string reply(s_ReplyBegin);
1108 
1109  len = PSGToString(item_id, buf);
1110  reply.append(buf, len)
1111  .append(s_AndProcessorId)
1112  .append(NStr::URLEncode(processor_id))
1113  .append(s_AndBioseqNAItem)
1114  .append(s_AndMetaChunk)
1115  .append(s_AndNChunks);
1116 
1117  len = PSGToString(chunk_count, buf);
1118  reply.append(buf, len)
1119  .append(1, '\n');
1120  return reply;
1121 }
1122 
1123 
1125  const string & processor_id,
1126  size_t chunk_count)
1127 {
1128  char buf[64];
1129  long len;
1130  string reply(s_ReplyBegin);
1131 
1132  len = PSGToString(item_id, buf);
1133  reply.append(buf, len)
1134  .append(s_AndProcessorId)
1135  .append(NStr::URLEncode(processor_id))
1136  .append(s_AndBioseqNAItem)
1137  .append(s_AndMetaChunk)
1138  .append(s_AndNChunks);
1139 
1140  len = PSGToString(chunk_count, buf);
1141  reply.append(buf, len)
1142  .append(1, '\n');
1143  return reply;
1144 }
1145 
1146 
1148  size_t per_annot_result_size)
1149 {
1150  char buf[64];
1151  long len;
1152  string reply(s_ReplyBegin);
1153 
1154  len = PSGToString(item_id, buf);
1155  reply.append(buf, len);
1156 
1157  len = PSGToString(per_annot_result_size, buf);
1158  reply.append(s_AndNAStatusItem)
1159  .append(s_AndDataChunk)
1160  .append(s_AndSize)
1161  .append(buf, len)
1162  .append(1, '\n');
1163  return reply;
1164 }
1165 
1166 
1167 string GetPerNAResultsCompletionHeader(size_t item_id,
1168  size_t chunk_count)
1169 {
1170  char buf[64];
1171  long len;
1172  string reply(s_ReplyBegin);
1173 
1174  len = PSGToString(item_id, buf);
1175  reply.append(buf, len)
1176  .append(s_AndNAStatusItem)
1177  .append(s_AndMetaChunk)
1178  .append(s_AndNChunks);
1179 
1180  len = PSGToString(chunk_count, buf);
1181  reply.append(buf, len)
1182  .append(1, '\n');
1183  return reply;
1184 }
1185 
1186 
1187 string GetAccVerHistoryHeader(size_t item_id,
1188  const string & processor_id,
1189  size_t msg_size)
1190 {
1191  // E.g. PSG-Reply-Chunk: item_id=1&processor_id=cass-acc-blob-hist&item_type=acc_ver_history&chunk_type=data&size=150
1192  char buf[64];
1193  long len;
1194  string reply(s_ReplyBegin);
1195 
1196  len = PSGToString(item_id, buf);
1197  reply.append(buf, len)
1198  .append(s_AndProcessorId)
1199  .append(NStr::URLEncode(processor_id))
1200  .append(s_AndAccVerHistoryItem)
1201  .append(s_AndDataChunk)
1202  .append(s_AndSize);
1203 
1204  len = PSGToString(msg_size, buf);
1205  reply.append(buf, len)
1206  .append(1, '\n');
1207  return reply;
1208 }
1209 
1210 
1211 string GetIPGResolveHeader(size_t item_id,
1212  const string & processor_id,
1213  size_t msg_size)
1214 {
1215  char buf[64];
1216  long len;
1217  string reply(s_ReplyBegin);
1218 
1219  len = PSGToString(item_id, buf);
1220  reply.append(buf, len)
1221  .append(s_AndProcessorId)
1222  .append(NStr::URLEncode(processor_id))
1223  .append(s_AndIPGInfoItem)
1224  .append(s_AndDataAndMetaChunk)
1225  .append(s_AndSize);
1226 
1227  len = PSGToString(msg_size, buf);
1228  reply.append(buf, len)
1229  .append(s_AndNChunks)
1230  .append(1, '1')
1231  .append(1, '\n');
1232  return reply;
1233 }
1234 
1235 string GetIPGMessageHeader(size_t item_id,
1236  const string & processor_id,
1237  CRequestStatus::ECode status,
1238  int code,
1239  EDiagSev severity,
1240  size_t msg_size)
1241 {
1242  char buf[64];
1243  long len;
1244  string reply(s_ReplyBegin);
1245 
1246  len = PSGToString(item_id, buf);
1247  reply.append(buf, len)
1248  .append(s_AndProcessorId)
1249  .append(NStr::URLEncode(processor_id))
1250  .append(s_AndIPGInfoItem)
1251  .append(s_AndMessageAndMetaChunk)
1252  .append(s_AndSize);
1253 
1254  len = PSGToString(msg_size, buf);
1255  reply.append(buf, len)
1256  .append(s_AndStatus);
1257 
1258  len = PSGToString(static_cast<int>(status), buf);
1259  reply.append(buf, len)
1260  .append(s_AndCode);
1261 
1262  len = PSGToString(code, buf);
1263  reply.append(buf, len)
1264  .append(s_AndSeverity)
1265  .append(SeverityToLowerString(severity))
1266  .append(s_AndNChunks)
1267  .append(1, '1')
1268  .append(1, '\n');
1269  return reply;
1270 }
1271 
1272 
1273 string GetAccVerHistCompletionHeader(size_t item_id,
1274  const string & processor_id,
1275  size_t chunk_count)
1276 {
1277  char buf[64];
1278  long len;
1279  string reply(s_ReplyBegin);
1280 
1281  len = PSGToString(item_id, buf);
1282  reply.append(buf, len)
1283  .append(s_AndProcessorId)
1284  .append(NStr::URLEncode(processor_id))
1285  .append(s_AndAccVerHistoryItem)
1286  .append(s_AndMetaChunk)
1287  .append(s_AndNChunks);
1288 
1289  len = PSGToString(chunk_count, buf);
1290  reply.append(buf, len)
1291  .append(1, '\n');
1292  return reply;
1293 }
1294 
1295 
1296 string GetProcessorMessageHeader(size_t item_id,
1297  const string & processor_id,
1298  size_t msg_size,
1299  CRequestStatus::ECode status,
1300  int code,
1301  EDiagSev severity)
1302 {
1303  // item_id=2&processor_id=Cassandra-get&item_type=processor&
1304  // chunk_type=message&size=94&status=401&code=340&
1305  // severity=warning&progress=inprogress
1306  // <message text>
1307 
1308  char buf[64];
1309  long len;
1310  string reply(s_ReplyBegin);
1311 
1312  len = PSGToString(item_id, buf);
1313  reply.append(buf, len)
1314  .append(s_AndProcessorId)
1315  .append(NStr::URLEncode(processor_id))
1316  .append(s_AndProcessorItem)
1317  .append(s_AndMessageChunk)
1318  .append(s_AndSize);
1319 
1320  len = PSGToString(msg_size, buf);
1321  reply.append(buf, len)
1322  .append(s_AndStatus);
1323 
1324  len = PSGToString(static_cast<int>(status), buf);
1325  reply.append(buf, len)
1326  .append(s_AndCode);
1327 
1328  len = PSGToString(code, buf);
1329  reply.append(buf, len)
1330  .append(s_AndSeverity)
1331  .append(SeverityToLowerString(severity))
1332  .append(s_AndProgress)
1333  .append(s_InProgress)
1334  .append(1, '\n');
1335  return reply;
1336 }
1337 
1338 
1340  const string & processor_id,
1341  size_t chunk_count)
1342 {
1343  // item_id=2&processor_id=Cassandra-get&item_type=processor&chunk_type=meta&n_chunks=2
1344 
1345  char buf[64];
1346  long len;
1347  string reply(s_ReplyBegin);
1348 
1349  len = PSGToString(item_id, buf);
1350  reply.append(buf, len)
1351  .append(s_AndProcessorId)
1352  .append(NStr::URLEncode(processor_id))
1353  .append(s_AndProcessorItem)
1354  .append(s_AndMetaChunk)
1355  .append(s_AndNChunks);
1356 
1357  len = PSGToString(chunk_count, buf);
1358  reply.append(buf, len)
1359  .append(1, '\n');
1360  return reply;
1361 }
1362 
1363 
1364 
1365 string GetPublicCommentHeader(size_t item_id,
1366  const string & processor_id,
1367  const string & blob_id,
1368  CBlobRecord::TTimestamp last_modified,
1369  size_t msg_size)
1370 {
1371  char buf[64];
1372  long len;
1373  string reply(s_ReplyBegin);
1374 
1375  len = PSGToString(item_id, buf);
1376  reply.append(buf, len)
1377  .append(s_AndProcessorId)
1378  .append(NStr::URLEncode(processor_id))
1379  .append(s_AndPublicCommentItem)
1380  .append(s_AndDataChunk)
1381  .append(s_AndBlobId)
1382  .append(blob_id)
1383  .append(s_AndLastModified);
1384 
1385  len = PSGToString(last_modified, buf);
1386  reply.append(buf, len)
1387  .append(s_AndSize);
1388 
1389  len = PSGToString(msg_size, buf);
1390  reply.append(buf, len)
1391  .append(1, '\n');
1392  return reply;
1393 }
1394 
1395 
1396 string GetPublicCommentHeader(size_t item_id,
1397  const string & processor_id,
1398  int64_t id2_chunk,
1399  const string & id2_info,
1400  size_t msg_size)
1401 {
1402  char buf[64];
1403  long len;
1404  string reply(s_ReplyBegin);
1405 
1406  len = PSGToString(item_id, buf);
1407  reply.append(buf, len)
1408  .append(s_AndProcessorId)
1409  .append(NStr::URLEncode(processor_id))
1410  .append(s_AndPublicCommentItem)
1411  .append(s_AndDataChunk)
1412  .append(s_AndId2Chunk);
1413 
1414  len = PSGToString(id2_chunk, buf);
1415  reply.append(buf, len)
1416  .append(s_AndId2Info)
1417  .append(id2_info)
1418  .append(s_AndSize);
1419 
1420  len = PSGToString(msg_size, buf);
1421  reply.append(buf, len)
1422  .append(1, '\n');
1423  return reply;
1424 }
1425 
1426 
1427 string GetPublicCommentCompletionHeader(size_t item_id,
1428  const string & processor_id,
1429  size_t chunk_count)
1430 {
1431  char buf[64];
1432  long len;
1433  string reply(s_ReplyBegin);
1434 
1435  len = PSGToString(item_id, buf);
1436  reply.append(buf, len)
1437  .append(s_AndProcessorId)
1438  .append(NStr::URLEncode(processor_id))
1439  .append(s_AndPublicCommentItem)
1440  .append(s_AndMetaChunk)
1441  .append(s_AndNChunks);
1442 
1443  len = PSGToString(chunk_count, buf);
1444  reply.append(buf, len)
1445  .append(1, '\n');
1446  return reply;
1447 }
1448 
1449 
1450 
1451 extern bool g_Log;
1452 
1453 
1454 // If the thread had no context set => the context need to be reset.
1455 // The client IP address is set only for non default context.
1457  m_NeedReset(!CDiagContext::GetRequestContext().IsSetClientIP())
1458 {}
1459 
1461 {
1462  if (g_Log && m_NeedReset) {
1464  }
1465 }
1466 
1467 
1469 {
1470  std::time_t t = chrono::system_clock::to_time_t(t_point);
1471  chrono::milliseconds t_ms = chrono::duration_cast<chrono::milliseconds>
1472  (t_point.time_since_epoch());
1473 
1474  struct tm local_time;
1475  localtime_r(&t, &local_time);
1476 
1477  char buffer[64];
1478  size_t char_count = strftime(buffer, 64,
1479  "%Y-%m-%d %H:%M:%S",
1480  &local_time);
1481  sprintf(&buffer[char_count], ".%03ld", t_ms.count() % 1000);
1482  return buffer;
1483 }
1484 
1485 
1486 unsigned long GetTimespanToNowMks(const psg_time_point_t & t_point)
1487 {
1488  return chrono::duration_cast<chrono::microseconds>(psg_clock_t::now() - t_point).count();
1489 }
1490 
1491 
1492 unsigned long GetTimespanToNowMs(const psg_time_point_t & t_point)
1493 {
1494  return chrono::duration_cast<chrono::milliseconds>(psg_clock_t::now() - t_point).count();
1495 }
1496 
1497 
1498 // The standard C++ to_string() seems to use a variation sprintf().
1499 // It works slow and visible in the profiler.
1500 // The version below appears faster and more suitable for the PSG purposes
1501 long PSGToString(long signed_value, char * buf)
1502 {
1503  char * pos = buf;
1504  unsigned long value;
1505  long value_length;
1506  char * first_digit;
1507  char temp;
1508 
1509  if (signed_value < 0) {
1510  *pos++ = '-';
1511  value = static_cast<unsigned long>(-signed_value);
1512  } else {
1513  value = static_cast<unsigned long>(signed_value);
1514  }
1515 
1516  first_digit = pos;
1517 
1518  // Convert in reverse order
1519  do {
1520  *pos++ = '0' + value % 10;
1521  value /= 10;
1522  } while (value);
1523 
1524  value_length = pos - buf;
1525  *pos-- = 0;
1526 
1527  // Restore the order
1528  do {
1529  temp = *pos;
1530  *pos-- = *first_digit;
1531  *first_digit++ = temp;
1532  } while (first_digit < pos);
1533 
1534  return value_length;
1535 }
1536 
1537 
1538 // It is used to sanitize string values which are received from a user and are
1539 // going to be sent out. This to prevent vulnerabilities like XSS when an input
1540 // value is intentionally malformed as a fragment of a script or so.
1541 string SanitizeInputValue(const string & input_val)
1542 {
1543  return NStr::HtmlEncode(input_val);
1544 }
1545 
1546 
1547 static map<EPSGS_StartupDataState, string> s_CassStartupDataStateMsg =
1548  { {ePSGS_NoCassConnection, "Cassandra DB connection is not established"},
1549  {ePSGS_NoValidCassMapping, "Cassandra DB mapping configuration is invalid"},
1550  {ePSGS_NoCassCache, "LMDB cache is not initialized"},
1551  {ePSGS_StartupDataOK, "Cassandra DB mapping data are OK"} };
1553 {
1555 }
1556 
1557 
1559  in_port_t client_port)
1560 {
1562 
1563  // NOTE: the context is created regardless if the logging is switched on or
1564  // off. This request context is created in case of serious errors which
1565  // should go to applog unconditionally
1566  context.Reset(new CRequestContext());
1567  context->SetRequestID();
1568  if (!client_ip.empty())
1569  context->SetClientIP(client_ip);
1572  if (client_port > 0)
1573  extra.Print("peer_socket_port", client_port);
1574  return context;
1575 }
1576 
1577 
1579  int status, size_t bytes_sent)
1580 {
1581  if (context.NotNull()) {
1583  context->SetReadOnly(false);
1584  context->SetRequestStatus(status);
1585  context->SetBytesWr(bytes_sent);
1587  context.Reset();
1589  }
1590 }
1591 
1592 
1593 CSpinlockGuard::CSpinlockGuard(atomic<bool> * spinlock) :
1594  m_Spinlock(spinlock)
1595 {
1596  while (m_Spinlock->exchange(true)) {}
1597 }
1598 
1599 
1601 {
1602  *m_Spinlock = false;
1603 }
1604 
TSeqIdType GetSeqIdType() const
Definition: record.hpp:208
TVersion GetVersion() const
Definition: record.hpp:203
TSeqIds & GetSeqIds()
Definition: record.hpp:248
CBioseqInfoRecord & SetSeqIdType(TSeqIdType value)
Definition: record.hpp:106
TAccession const & GetAccession() const
Definition: record.hpp:198
CBioseqInfoRecord & SetAccession(const TAccession &value)
Definition: record.hpp:94
int64_t TTimestamp
Definition: blob_record.hpp:56
Temporary object for holding extra message arguments.
Definition: ncbidiag.hpp:1828
atomic< bool > * m_Spinlock
CSpinlockGuard(atomic< bool > *spinlock)
static const int chunk_size
The NCBI C++ standard methods for dealing with std::string.
Uint8 uint64_t
Int8 int64_t
#define NULL
Definition: ncbistd.hpp:225
void PrintRequestStop(void)
Print request stop message (for request-driven applications)
Definition: ncbidiag.cpp:2778
CDiagContext_Extra & Print(const string &name, const string &value)
The method does not print the argument, but adds it to the string.
Definition: ncbidiag.cpp:2622
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
static void SetRequestContext(CRequestContext *ctx)
Shortcut to CDiagContextThreadData::GetThreadData().SetRequestContext()
Definition: ncbidiag.cpp:1907
void PrintRequestStart(const string &message)
Print request start message (for request-driven applications)
Definition: ncbidiag.cpp:2762
static const char * SeverityName(EDiagSev sev)
Get a common symbolic name for the severity levels.
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
static string HtmlEncode(const CTempString str, THtmlEncode flags=fHtmlEnc_EncodeAll)
Encode a string for HTML.
Definition: ncbistr.cpp:4122
static string URLEncode(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
URL-encode string.
Definition: ncbistr.cpp:6062
static string & ToLower(string &str)
Convert string to lower case – string& version.
Definition: ncbistr.cpp:405
@ e_Gi
GenInfo Integrated Database.
Definition: Seq_id_.hpp:106
char * buf
int len
chrono::system_clock::time_point time_point
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
EIPRangeType t
Definition: ncbi_localip.c:101
static pcre_uint8 * buffer
Definition: pcretest.c:1051
EPSGS_BlobSkipReason
@ ePSGS_BlobExcluded
@ ePSGS_BlobSent
@ ePSGS_BlobInProgress
EPSGS_StartupDataState
@ ePSGS_NoCassConnection
@ ePSGS_NoCassCache
@ ePSGS_NoValidCassMapping
@ ePSGS_StartupDataOK
@ ePSGS_BioseqDB
@ ePSGS_BioseqCache
psg_clock_t::time_point psg_time_point_t
EPSGS_AccessionAdjustmentResult
@ ePSGS_AdjustedWithGi
@ ePSGS_AdjustedWithAny
@ ePSGS_NotRequired
@ ePSGS_LogicError
@ ePSGS_SeqIdsEmpty
static string s_Severity
static string s_AndSize
static string s_Processor
USING_SCOPE(objects)
static string s_Fmt
static string s_AndCode
static string s_MetaChunk
static string s_AndId2Info
static string s_InProgress
string GetPublicCommentCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
string GetReplyMessageHeader(size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
static string s_AndDataAndMetaChunk
static string s_AccVerHistory
static string s_AndProcessorId
static string s_AndIPGInfoItem
string GetIPGMessageHeader(size_t item_id, const string &processor_id, CRequestStatus::ECode status, int code, EDiagSev severity, size_t msg_size)
static string s_AndBlobPropItem
static string s_AndFmtJson
static string s_MessageChunk
unsigned long GetTimespanToNowMs(const psg_time_point_t &t_point)
static string s_BlobItem
string GetPerNamedAnnotationResultsHeader(size_t item_id, size_t per_annot_result_size)
static map< EPSGS_StartupDataState, string > s_CassStartupDataStateMsg
static string s_Reply
string SanitizeInputValue(const string &input_val)
static string s_AndMessageChunk
static string s_Meta
string GetTSEBlobChunkHeader(size_t item_id, const string &processor_id, size_t chunk_size, size_t chunk_number, int64_t id2_chunk, const string &id2_info)
static string s_Size
string GetAccVerHistoryHeader(size_t item_id, const string &processor_id, size_t msg_size)
static string s_Reason
string GetBlobMessageHeader(size_t item_id, const string &processor_id, const string &blob_id, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity, CBlobRecord::TTimestamp last_modified)
static string s_DataAndMetaChunk
static string s_AndSentSecondsAgo
static string s_AndReason
static string s_FmtProtobuf
string GetBioseqMessageHeader(size_t item_id, const string &processor_id, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
static string s_Excluded
long PSGToString(long signed_value, char *buf)
static string s_AndReplyItem
static string s_Data
static string s_Protobuf
static string s_Status
static string s_ReplyCompletionFixedPart
string GetBlobPropHeader(size_t item_id, const string &processor_id, const string &blob_id, size_t blob_prop_size, CBlobRecord::TTimestamp last_modified)
static string s_ExecTime
static string s_AndProcessorItem
bool g_Log
static string s_AndMetaChunk
static string s_ReplyBegin
static string s_AndNAStatusItem
static string s_AndDataChunk
static string s_BlobId
static string s_BlobChunk
static string s_BlobPropItem
static string s_NAStatusItem
static string s_IPGInfo
static string s_AndLastModified
string GetNamedAnnotationMessageHeader(size_t item_id, const string &processor_id, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
string GetReplyCompletionHeader(size_t chunk_count, CRequestStatus::ECode status, const psg_time_point_t &create_timestamp)
string GetBlobPropMessageHeader(size_t item_id, const string &processor_id, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
static string s_DataChunk
static string s_ItemId
static string SkipReasonToString(EPSGS_BlobSkipReason skip_reason)
string GetBioseqInfoHeader(size_t item_id, const string &processor_id, size_t bioseq_info_size, SPSGS_ResolveRequest::EPSGS_OutputFormat output_format)
static string s_IPGInfoItem
static string s_MessageAndMetaChunk
static string s_AndBlobId
static string s_Id2Info
static string s_BioseqInfo
static string s_ProcessorItem
string FormatPreciseTime(const chrono::system_clock::time_point &t_point)
string GetPerNAResultsCompletionHeader(size_t item_id, size_t chunk_count)
string GetTSEBlobPropMessageHeader(size_t item_id, const string &processor_id, int64_t id2_chunk, const string &id2_info, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
static string s_Json
static string s_Progress
string GetNamedAnnotationCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
static string s_ReplyItem
string GetTSEBlobPropCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
string GetBlobCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
static string s_AndBioseqNAItem
static string s_LastModified
unsigned long GetTimespanToNowMks(const psg_time_point_t &t_point)
static string s_AndFmtProtobuf
static string s_AndMessageAndMetaChunk
string GetNamedAnnotationHeader(size_t item_id, const string &processor_id, const string &annot_name, size_t annotation_size)
static string s_AndBioseqInfoItemAndDataChunkAndSize
string GetPublicCommentHeader(size_t item_id, const string &processor_id, const string &blob_id, CBlobRecord::TTimestamp last_modified, size_t msg_size)
static string s_AccVerHistoryItem
static string s_AndNChunksOne
static string s_BioseqInfoItem
static string s_ProcessorId
static string s_FmtJson
static string s_Sent
static string s_AndBlobChunk
static string SeverityToLowerString(EDiagSev severity)
string GetProcessorMessageCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
static string s_BioseqNA
string GetBlobChunkHeader(size_t item_id, const string &processor_id, const string &blob_id, size_t chunk_size, size_t chunk_number, CBlobRecord::TTimestamp last_modified)
static string s_AndProgress
static string s_AndBlobItem
static string s_ProtocolPrefix
static string s_DataAndMeta
static string s_Id2Chunk
string GetIPGResolveHeader(size_t item_id, const string &processor_id, size_t msg_size)
static string s_SentSecondsAgo
string GetTSEBlobExcludeHeader(size_t item_id, const string &processor_id, const string &blob_id, EPSGS_BlobSkipReason skip_reason, int64_t id2_chunk, const string &id2_info)
string GetBioseqCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
string GetAccVerHistCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
static string s_AndTimeUntilResend
static string s_Message
static string s_AndNA
static string s_AndPublicCommentItem
static string s_Code
string GetCassStartupDataStateMessage(EPSGS_StartupDataState state)
static string s_BioseqNAItem
string GetNamedAnnotationMessageCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
static string s_TimeUntilResend
static string s_MessageAndMeta
string GetProcessorMessageHeader(size_t item_id, const string &processor_id, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
string GetTSEBlobCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
string GetBlobPropCompletionHeader(size_t item_id, const string &processor_id, size_t chunk_count)
static string s_NAStatus
CRef< CRequestContext > CreateErrorRequestContext(const string &client_ip, in_port_t client_port)
void DismissErrorRequestContext(CRef< CRequestContext > context, int status, size_t bytes_sent)
static string s_AndId2Chunk
static string s_ChunkType
static string s_NChunks
static string s_Blob
static string s_AndNChunks
static string s_NA
static string s_AndExecTime
static string s_AndBioseqInfoItem
string GetBlobExcludeHeader(size_t item_id, const string &processor_id, const string &blob_id, EPSGS_BlobSkipReason skip_reason, CBlobRecord::TTimestamp last_modified)
static string s_AndStatus
string GetTSEBlobMessageHeader(size_t item_id, const string &processor_id, int64_t id2_chunk, const string &id2_info, size_t msg_size, CRequestStatus::ECode status, int code, EDiagSev severity)
static string s_AndSeverity
static string s_ItemType
static string s_PublicComment
static string s_PublicCommentItem
static string s_AndAccVerHistoryItem
static string s_NChunksOne
static string s_BlobProp
string GetTSEBlobPropHeader(size_t item_id, const string &processor_id, int64_t id2_chunk, const string &id2_info, size_t blob_prop_size)
string GetProcessorProgressMessageHeader(size_t item_id, const string &processor_id, const string &progress_status)
EPSGS_AccessionAdjustmentResult AdjustAccession(shared_ptr< CPSGS_Request > request, shared_ptr< CPSGS_Reply > reply)
EPSGS_ResolutionResult m_ResolutionResult
EPSGS_AccessionAdjustmentResult m_AccessionAdjustmentResult
CBioseqInfoRecord m_BioseqInfo
Definition: inftrees.h:24
static CS_CONTEXT * context
Definition: will_convert.c:21
Modified on Wed Apr 17 13:09:00 2024 by modify_doxy.py rev. 669887