1 #ifndef PSGS_REPLY__HPP
2 #define PSGS_REPLY__HPP
3 
4 /*  $Id: psgs_reply.hpp 629837 2021-04-22 12:47:49Z ivanov $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Sergey Satskiy
30  *
31  * File Description:
32  *
33  */
34 
35 #include <corelib/request_status.hpp>
36 #include <h2o.h>
37 
38 #include "pubseq_gateway_types.hpp"
39 #include "psgs_request.hpp"
40 
41 
42 class CPendingOperation;
43 class CCassBlobFetch;
44 template<typename P> class CHttpReply;
45 namespace idblob { class CCassDataCallbackReceiver; }
46 
47 // Keeps track of the protocol replies
48 class CPSGS_Reply
49 {
50 public:
CPSGS_Reply(unique_ptr<CHttpReply<CPendingOperation>> low_level_reply)51     CPSGS_Reply(unique_ptr<CHttpReply<CPendingOperation>>  low_level_reply) :
52         m_Reply(low_level_reply.release()),
53         m_ReplyOwned(true),
54         m_NextItemIdLock(false),
55         m_NextItemId(0),
56         m_TotalSentReplyChunks(0),
57         m_ChunksLock(false)
58     {
59         SetContentType(ePSGS_PSGMime);
60     }
61 
62     // This constructor is to reuse the infrastructure (PSG chunks, counting
63     // them etc) in the low level error reports
CPSGS_Reply(CHttpReply<CPendingOperation> * low_level_reply)64     CPSGS_Reply(CHttpReply<CPendingOperation> *  low_level_reply) :
65         m_Reply(low_level_reply),
66         m_ReplyOwned(false),
67         m_NextItemIdLock(false),
68         m_NextItemId(0),
69         m_TotalSentReplyChunks(0),
70         m_ChunksLock(false)
71     {
72         SetContentType(ePSGS_PSGMime);
73     }
74 
75     ~CPSGS_Reply();
76 
77 public:
78     void Flush(void);
79     void Flush(bool  is_last);
80     void Clear(void);
81     shared_ptr<idblob::CCassDataCallbackReceiver> GetDataReadyCB(void);
82     bool IsFinished(void) const;
83     bool IsOutputReady(void) const;
84     void SetContentType(EPSGS_ReplyMimeType  mime_type);
85 
GetHttpReply(void)86     CHttpReply<CPendingOperation> *  GetHttpReply(void)
87     {
88         return m_Reply;
89     }
90 
GetItemId(void)91     size_t  GetItemId(void)
92     {
93         while (m_NextItemIdLock.exchange(true)) {}
94         auto    ret = ++m_NextItemId;
95         m_NextItemIdLock = false;
96         return ret;
97     }
98 
99 public:
100     // PSG protocol facilities
101     void PrepareBioseqMessage(size_t  item_id,
102                               const string &  processor_id,
103                               const string &  msg,
104                               CRequestStatus::ECode  status,
105                               int  err_code, EDiagSev  severity);
106     void PrepareBioseqData(size_t  item_id,
107                            const string &  processor_id,
108                            const string &  content,
109                            SPSGS_ResolveRequest::EPSGS_OutputFormat  output_format);
110     void PrepareBioseqCompletion(size_t  item_id,
111                                  const string &  processor_id,
112                                  size_t  chunk_count);
113     void PrepareBlobPropMessage(size_t  item_id,
114                                 const string &  processor_id,
115                                 const string &  msg,
116                                 CRequestStatus::ECode  status,
117                                 int  err_code,
118                                 EDiagSev  severity);
119     void PrepareBlobPropMessage(CCassBlobFetch *  fetch_details,
120                                 const string &  processor_id,
121                                 const string &  msg,
122                                 CRequestStatus::ECode  status,
123                                 int  err_code,
124                                 EDiagSev  severity);
125     void PrepareTSEBlobPropMessage(CCassBlobFetch *       fetch_details,
126                                    const string &         processor_id,
127                                    int64_t                id2_chunk,
128                                    const string &         id2_info,
129                                    const string &         msg,
130                                    CRequestStatus::ECode  status,
131                                    int                    err_code,
132                                    EDiagSev               severity);
133     void PrepareBlobPropData(size_t                   item_id,
134                              const string &           processor_id,
135                              const string &           blob_id,
136                              const string &           content,
137                              CBlobRecord::TTimestamp  last_modified=-1);
138     void PrepareBlobPropData(CCassBlobFetch *         fetch_details,
139                              const string &           processor_id,
140                              const string &           content,
141                              CBlobRecord::TTimestamp  last_modified=-1);
142     void PrepareTSEBlobPropData(size_t            item_id,
143                                 const string &    processor_id,
144                                 int64_t           id2_chunk,
145                                 const string &    id2_info,
146                                 const string &    content);
147     void PrepareTSEBlobPropData(CCassBlobFetch *  fetch_details,
148                                 const string &    processor_id,
149                                 int64_t           id2_chunk,
150                                 const string &    id2_info,
151                                 const string &    content);
152     void PrepareBlobData(size_t                   item_id,
153                          const string &           processor_id,
154                          const string &           blob_id,
155                          const unsigned char *    chunk_data,
156                          unsigned int             data_size,
157                          int                      chunk_no,
158                          CBlobRecord::TTimestamp  last_modified=-1);
159     void PrepareBlobData(CCassBlobFetch *         fetch_details,
160                          const string &           processor_id,
161                          const unsigned char *    chunk_data,
162                          unsigned int             data_size,
163                          int                      chunk_no,
164                          CBlobRecord::TTimestamp  last_modified=-1);
165     void PrepareTSEBlobData(size_t                 item_id,
166                             const string &         processor_id,
167                             const unsigned char *  chunk_data,
168                             unsigned int           data_size,
169                             int                    chunk_no,
170                             int64_t                id2_chunk,
171                             const string &         id2_info);
172     void PrepareTSEBlobData(CCassBlobFetch *  fetch_details,
173                             const string &  processor_id,
174                             const unsigned char *  chunk_data,
175                             unsigned int  data_size,
176                             int  chunk_no,
177                             int64_t  id2_chunk,
178                             const string &  id2_info);
179     void PrepareBlobPropCompletion(size_t  item_id,
180                                    const string &  processor_id,
181                                    size_t  chunk_count);
182     void PrepareBlobPropCompletion(CCassBlobFetch *  fetch_details,
183                                    const string &  processor_id);
184     void PrepareTSEBlobPropCompletion(CCassBlobFetch *  fetch_details,
185                                       const string &  processor_id);
186     void PrepareBlobMessage(size_t  item_id,
187                             const string &  processor_id,
188                             const string &  blob_id,
189                             const string &  msg,
190                             CRequestStatus::ECode  status,
191                             int  err_code,
192                             EDiagSev  severity,
193                             CBlobRecord::TTimestamp  last_modified=-1);
194     void PrepareBlobMessage(CCassBlobFetch *  fetch_details,
195                             const string &  processor_id,
196                             const string &  msg,
197                             CRequestStatus::ECode  status, int  err_code,
198                             EDiagSev  severity,
199                             CBlobRecord::TTimestamp  last_modified=-1);
200     void PrepareTSEBlobMessage(CCassBlobFetch *  fetch_details,
201                                const string &  processor_id,
202                                int64_t  id2_chunk,
203                                const string &  id2_info,
204                                const string &  msg,
205                                CRequestStatus::ECode  status, int  err_code,
206                                EDiagSev  severity);
207     void PrepareBlobCompletion(size_t  item_id,
208                                const string &  processor_id,
209                                size_t  chunk_count);
210     void PrepareTSEBlobCompletion(size_t item_id,
211                                   const string &  processor_id,
212                                   size_t  chunk_count);
213     void PrepareTSEBlobCompletion(CCassBlobFetch *  fetch_details,
214                                   const string &  processor_id);
215     void PrepareBlobExcluded(const string &  blob_id,
216                              const string &  processor_id,
217                              EPSGS_BlobSkipReason  skip_reason,
218                              CBlobRecord::TTimestamp  last_modified=-1);
219     void PrepareTSEBlobExcluded(const string &  processor_id,
220                                 int64_t  id2_chunk,
221                                 const string &  id2_info,
222                                 EPSGS_BlobSkipReason  skip_reason);
223     void PrepareBlobExcluded(size_t  item_id,
224                              const string &  processor_id,
225                              const string &  blob_id,
226                              EPSGS_BlobSkipReason  skip_reason);
227     void PrepareBlobCompletion(CCassBlobFetch *  fetch_details,
228                                const string &  processor_id);
229     void PrepareProcessorMessage(size_t  item_id, const string &  processor_id,
230                                  const string &  msg,
231                                  CRequestStatus::ECode  status, int  err_code,
232                                  EDiagSev  severity);
233     void PreparePublicComment(const string &  processor_id,
234                               const string &  public_comment,
235                               const string &  blob_id,
236                               CBlobRecord::TTimestamp  last_modified);
237     void PreparePublicComment(const string &  processor_id,
238                               const string &  public_comment,
239                               int64_t  id2_chunk,
240                               const string &  id2_info);
241     void PrepareReplyMessage(const string &  msg,
242                              CRequestStatus::ECode  status, int  err_code,
243                              EDiagSev  severity);
244     void PrepareNamedAnnotationData(const string &  annot_name,
245                                     const string &  processor_id,
246                                     const string &  content);
247     void PrepareReplyCompletion(void);
248     void SendTrace(const string &  msg,
249                    const TPSGS_HighResolutionTimePoint &  create_timestamp);
250 
251 public:
252     // HTTP facilities
253     void SendData(const string &  data_ptr, EPSGS_ReplyMimeType  mime_type);
254 
255 private:
256     void x_PrepareTSEBlobPropCompletion(size_t          item_id,
257                                         const string &  processor_id,
258                                         size_t          chunk_count);
259     void x_PrepareTSEBlobPropMessage(size_t  item_id,
260                                      const string &  processor_id,
261                                      int64_t  id2_chunk,
262                                      const string &  id2_info,
263                                      const string &  msg,
264                                      CRequestStatus::ECode  status,
265                                      int  err_code,
266                                      EDiagSev  severity);
267     void x_PrepareTSEBlobMessage(size_t  item_id,
268                                  const string &  processor_id,
269                                  int64_t  id2_chunk,
270                                  const string &  id2_info,
271                                  const string &  msg,
272                                  CRequestStatus::ECode  status,
273                                  int  err_code,
274                                  EDiagSev  severity);
275 
276 private:
277     CHttpReply<CPendingOperation> *     m_Reply;
278     bool                                m_ReplyOwned;
279     atomic<bool>                        m_NextItemIdLock;
280     size_t                              m_NextItemId;
281     int32_t                             m_TotalSentReplyChunks;
282     atomic<bool>                        m_ChunksLock;
283     vector<h2o_iovec_t>                 m_Chunks;
284 };
285 
286 
287 #endif
288