1 #ifndef CASS_FETCH__HPP
2 #define CASS_FETCH__HPP
3 
4 /*  $Id: cass_fetch.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 
36 #include "pubseq_gateway_types.hpp"
37 #include "psgs_request.hpp"
38 #include "cass_blob_id.hpp"
39 
40 #include <objtools/pubseq_gateway/impl/cassandra/blob_task/load_blob.hpp>
41 #include <objtools/pubseq_gateway/impl/cassandra/nannot_task/fetch.hpp>
42 #include <objtools/pubseq_gateway/impl/cassandra/bioseq_info_task/fetch.hpp>
43 #include <objtools/pubseq_gateway/impl/cassandra/si2csi_task/fetch.hpp>
44 #include <objtools/pubseq_gateway/impl/cassandra/blob_task/fetch_split_history.hpp>
45 #include <objtools/pubseq_gateway/impl/cassandra/status_history/get_public_comment.hpp>
46 USING_IDBLOB_SCOPE;
47 
48 
49 class CPendingOperation;
50 class CPSGS_Reply;
51 
52 // Keeps track of the retrieving something from cassandra
53 class CCassFetch
54 {
55 public:
CCassFetch()56     CCassFetch() :
57         m_FinishedRead(false),
58         m_FetchType(ePSGS_UnknownFetch),
59         m_Cancelled(false)
60     {}
61 
~CCassFetch()62     virtual ~CCassFetch()
63     {}
64 
65     virtual void ResetCallbacks(void) = 0;
66     virtual string Serialize(void) const = 0;
67 
68 public:
GetLoader(void)69     CCassBlobWaiter * GetLoader(void)
70     { return m_Loader.get(); }
71 
SetReadFinished(void)72     void SetReadFinished(void)
73     { m_FinishedRead = true; }
74 
GetFetchType(void) const75     EPSGS_DbFetchType GetFetchType(void) const
76     { return m_FetchType; }
77 
ReadFinished(void) const78     bool ReadFinished(void) const
79     { return m_FinishedRead; }
80 
Cancelled(void) const81     bool Cancelled(void) const
82     { return m_Cancelled; }
83 
Cancel(void)84     void Cancel(void)
85     {
86         if (m_Loader) {
87             if (!m_Cancelled) {
88                 m_Cancelled = true;
89                 m_Loader->Cancel();
90             }
91         }
92     }
93 
94 protected:
95     // There are multiple types of the loaders stored here:
96     // - CCassBlobTaskLoadBlob to load a blob
97     // - CCassNAnnotTaskFetch to load an annotation
98     // The loader must be here because it exposes a few generic interfaces
99     // including errors
100     unique_ptr<CCassBlobWaiter>     m_Loader;
101 
102     // Indication that there will be no more data
103     bool                            m_FinishedRead;
104 
105     // At the time of a x_Peek() there is a last resort error handling.
106     // That code receives a pointer to the base class but it needs to know
107     // what kind of request it was because an appropriate error message needs
108     // to be send. Thus this member is required.
109     EPSGS_DbFetchType               m_FetchType;
110 
111     bool                            m_Cancelled;
112 };
113 
114 
115 
116 class CCassNamedAnnotFetch : public CCassFetch
117 {
118 public:
CCassNamedAnnotFetch(const SPSGS_AnnotRequest & annot_request)119     CCassNamedAnnotFetch(const SPSGS_AnnotRequest &  annot_request)
120     {
121         m_FetchType = ePSGS_AnnotationFetch;
122     }
123 
CCassNamedAnnotFetch()124     CCassNamedAnnotFetch()
125     {}
126 
~CCassNamedAnnotFetch()127     virtual ~CCassNamedAnnotFetch()
128     {}
129 
Serialize(void) const130     virtual string Serialize(void) const
131     {
132         return "CCassNamedAnnotFetch";
133     }
134 
135 public:
SetLoader(CCassNAnnotTaskFetch * fetch)136     void SetLoader(CCassNAnnotTaskFetch *  fetch)
137     { m_Loader.reset(fetch); }
138 
GetLoader(void)139     CCassNAnnotTaskFetch * GetLoader(void)
140     { return static_cast<CCassNAnnotTaskFetch *>(m_Loader.get()); }
141 
142 public:
143     virtual void ResetCallbacks(void);
144 };
145 
146 
147 class CCassBlobFetch : public CCassFetch
148 {
149 public:
CCassBlobFetch(const SPSGS_BlobBySeqIdRequest & blob_request,const SCass_BlobId & blob_id)150     CCassBlobFetch(const SPSGS_BlobBySeqIdRequest &  blob_request,
151                    const SCass_BlobId &  blob_id) :
152         m_BlobId(blob_id),
153         m_TSEOption(blob_request.m_TSEOption),
154         m_ClientId(blob_request.m_ClientId),
155         m_BlobPropSent(false),
156         m_UserProvidedBlobId(false),
157         m_TotalSentBlobChunks(0),
158         m_BlobPropItemId(0),
159         m_BlobChunkItemId(0)
160     {
161         m_FetchType = ePSGS_BlobBySeqIdFetch;
162     }
163 
CCassBlobFetch(const SPSGS_BlobBySatSatKeyRequest & blob_request,const SCass_BlobId & blob_id)164     CCassBlobFetch(const SPSGS_BlobBySatSatKeyRequest &  blob_request,
165                    const SCass_BlobId &  blob_id) :
166         m_BlobId(blob_id),
167         m_TSEOption(blob_request.m_TSEOption),
168         m_ClientId(blob_request.m_ClientId),
169         m_BlobPropSent(false),
170         m_UserProvidedBlobId(true),
171         m_TotalSentBlobChunks(0),
172         m_BlobPropItemId(0),
173         m_BlobChunkItemId(0)
174     {
175         m_FetchType = ePSGS_BlobBySatSatKeyFetch;
176     }
177 
Serialize(void) const178     virtual string Serialize(void) const
179     {
180         return "CCassBlobFetch; BlobId: " + m_BlobId.ToString() +
181                " BlobPropSent: " + to_string(m_BlobPropSent) +
182                " TotalSentBlobChunks: " + to_string(m_TotalSentBlobChunks);
183     }
184 
185     // The TSE chunk request is pretty much the same as a blob request
186     // - eUnknownTSE is used to skip the blob prop analysis logic
187     // - client id is empty so the cache of blobs sent to the user is not used
188     // - UserProvidedBlobId == false is used to report a server error 500 in
189     //   case the blob props are not found.
CCassBlobFetch(const SPSGS_TSEChunkRequest & chunk_request,const SCass_BlobId & tse_id)190     CCassBlobFetch(const SPSGS_TSEChunkRequest &  chunk_request,
191                    const SCass_BlobId &  tse_id) :
192         m_BlobId(tse_id),
193         m_TSEOption(SPSGS_BlobRequestBase::ePSGS_UnknownTSE),
194         m_ClientId(""),
195         m_BlobPropSent(false),
196         m_UserProvidedBlobId(false),
197         m_TotalSentBlobChunks(0),
198         m_BlobPropItemId(0),
199         m_BlobChunkItemId(0)
200     {
201         m_FetchType = ePSGS_TSEChunkFetch;
202     }
203 
CCassBlobFetch()204     CCassBlobFetch() :
205         m_TSEOption(SPSGS_BlobRequestBase::ePSGS_UnknownTSE),
206         m_BlobPropSent(false),
207         m_UserProvidedBlobId(true),
208         m_TotalSentBlobChunks(0),
209         m_BlobPropItemId(0),
210         m_BlobChunkItemId(0)
211     {}
212 
~CCassBlobFetch()213     virtual ~CCassBlobFetch()
214     {}
215 
216 public:
GetClientId(void) const217     string GetClientId(void) const
218     { return m_ClientId; }
219 
GetTSEOption(void) const220     SPSGS_BlobRequestBase::EPSGS_TSEOption GetTSEOption(void) const
221     { return m_TSEOption; }
222 
GetUserProvidedBlobId(void) const223     bool GetUserProvidedBlobId(void) const
224     { return m_UserProvidedBlobId; }
225 
GetBlobId(void) const226     SCass_BlobId GetBlobId(void) const
227     { return m_BlobId; }
228 
GetTotalSentBlobChunks(void) const229     int32_t GetTotalSentBlobChunks(void) const
230     { return m_TotalSentBlobChunks; }
231 
IncrementTotalSentBlobChunks(void)232     void IncrementTotalSentBlobChunks(void)
233     { ++m_TotalSentBlobChunks; }
234 
ResetTotalSentBlobChunks(void)235     void ResetTotalSentBlobChunks(void)
236     { m_TotalSentBlobChunks = 0; }
237 
SetBlobPropSent(void)238     void SetBlobPropSent(void)
239     { m_BlobPropSent = true; }
240 
241     // At the time of an error report it needs to be known to what the
242     // error message is associated - to blob properties or to blob chunks
IsBlobPropStage(void) const243     bool IsBlobPropStage(void) const
244     { return !m_BlobPropSent; }
245 
SetLoader(CCassBlobTaskLoadBlob * fetch)246     void SetLoader(CCassBlobTaskLoadBlob *  fetch)
247     { m_Loader.reset(fetch); }
248 
GetLoader(void)249     CCassBlobTaskLoadBlob *  GetLoader(void)
250     { return static_cast<CCassBlobTaskLoadBlob *>(m_Loader.get()); }
251 
252 public:
253     size_t GetBlobPropItemId(CPSGS_Reply *  reply);
254     size_t GetBlobChunkItemId(CPSGS_Reply *  reply);
255 
256     virtual void ResetCallbacks(void);
257 
258 private:
259     SCass_BlobId                            m_BlobId;
260     SPSGS_BlobRequestBase::EPSGS_TSEOption  m_TSEOption;
261     string                                  m_ClientId;
262 
263     bool                                    m_BlobPropSent;
264 
265     // There are three cases when a blob is requested and depending on which
266     // one is used a different error message should be reported (blob
267     // properties are not found):
268     // 1. The user provided seq_id. In this case the error is a server data
269     //    error (500) because the seq_id has been resolved
270     // 2. The user provided blob sat & sat_key. In this case it is a client
271     //    error (404) because the user provided something unknown
272     // 3. The TSE chunk request also should lead to a server error because
273     //    the chunks in this request are coming for already resolved split blob
274     bool                                    m_UserProvidedBlobId;
275 
276     int32_t                                 m_TotalSentBlobChunks;
277 
278     size_t                                  m_BlobPropItemId;
279     size_t                                  m_BlobChunkItemId;
280 };
281 
282 
283 class CCassBioseqInfoFetch : public CCassFetch
284 {
285 public:
CCassBioseqInfoFetch()286     CCassBioseqInfoFetch()
287     {
288         m_FetchType = ePSGS_BioseqInfoFetch;
289     }
290 
~CCassBioseqInfoFetch()291     virtual ~CCassBioseqInfoFetch()
292     {}
293 
Serialize(void) const294     virtual string Serialize(void) const
295     {
296         return "CCassBioseqInfoFetch";
297     }
298 
299 public:
SetLoader(CCassBioseqInfoTaskFetch * fetch)300     void SetLoader(CCassBioseqInfoTaskFetch *  fetch)
301     { m_Loader.reset(fetch); }
302 
GetLoader(void)303     CCassBioseqInfoTaskFetch * GetLoader(void)
304     { return static_cast<CCassBioseqInfoTaskFetch *>(m_Loader.get()); }
305 
306 public:
307     virtual void ResetCallbacks(void);
308 };
309 
310 
311 class CCassSi2csiFetch : public CCassFetch
312 {
313 public:
CCassSi2csiFetch()314     CCassSi2csiFetch()
315     {
316         m_FetchType = ePSGS_Si2csiFetch;
317     }
318 
~CCassSi2csiFetch()319     virtual ~CCassSi2csiFetch()
320     {}
321 
Serialize(void) const322     virtual string Serialize(void) const
323     {
324         return "CCassSi2csiFetch";
325     }
326 
327 public:
SetLoader(CCassSI2CSITaskFetch * fetch)328     void SetLoader(CCassSI2CSITaskFetch *  fetch)
329     { m_Loader.reset(fetch); }
330 
GetLoader(void)331     CCassSI2CSITaskFetch * GetLoader(void)
332     { return static_cast<CCassSI2CSITaskFetch *>(m_Loader.get()); }
333 
334 public:
335     virtual void ResetCallbacks(void);
336 };
337 
338 
339 class CCassSplitHistoryFetch : public CCassFetch
340 {
341 public:
CCassSplitHistoryFetch(const SPSGS_TSEChunkRequest & chunk_request,const SCass_BlobId & tse_id,int64_t split_version)342     CCassSplitHistoryFetch(const SPSGS_TSEChunkRequest &  chunk_request,
343                            const SCass_BlobId &  tse_id,
344                            int64_t  split_version) :
345         m_TSEId(tse_id),
346         m_Chunk(chunk_request.m_Id2Chunk),
347         m_SplitVersion(split_version),
348         m_UseCache(chunk_request.m_UseCache)
349     {
350         m_FetchType = ePSGS_SplitHistoryFetch;
351     }
352 
~CCassSplitHistoryFetch()353     virtual ~CCassSplitHistoryFetch()
354     {}
355 
Serialize(void) const356     virtual string Serialize(void) const
357     {
358         return "CCassSplitHistoryFetch";
359     }
360 
361 public:
GetTSEId(void) const362     SCass_BlobId  GetTSEId(void) const
363     { return m_TSEId; }
364 
GetChunk(void) const365     int64_t  GetChunk(void) const
366     { return m_Chunk; }
367 
GetSplitVersion(void) const368     int64_t  GetSplitVersion(void) const
369     { return m_SplitVersion; }
370 
GetUseCache(void) const371     SPSGS_RequestBase::EPSGS_CacheAndDbUse  GetUseCache(void) const
372     { return m_UseCache; }
373 
SetLoader(CCassBlobTaskFetchSplitHistory * fetch)374     void SetLoader(CCassBlobTaskFetchSplitHistory *  fetch)
375     { m_Loader.reset(fetch); }
376 
GetLoader(void)377     CCassBlobTaskFetchSplitHistory * GetLoader(void)
378     { return static_cast<CCassBlobTaskFetchSplitHistory *>(m_Loader.get()); }
379 
380 public:
381     virtual void ResetCallbacks(void);
382 
383 private:
384     SCass_BlobId                            m_TSEId;
385     int64_t                                 m_Chunk;
386     int64_t                                 m_SplitVersion;
387     SPSGS_RequestBase::EPSGS_CacheAndDbUse  m_UseCache;
388 };
389 
390 
391 class CCassPublicCommentFetch : public CCassFetch
392 {
393 public:
394     enum EPSGS_Identification {
395         ePSGS_ByCassBlob,
396         ePSGS_ById2
397     };
398 
399 public:
CCassPublicCommentFetch()400     CCassPublicCommentFetch() :
401         m_Identification(ePSGS_ByCassBlob),
402         m_LastModified(-1),
403         m_Id2Chunk(-1)
404     {
405         m_FetchType = ePSGS_PublicCommentFetch;
406     }
407 
~CCassPublicCommentFetch()408     virtual ~CCassPublicCommentFetch()
409     {}
410 
Serialize(void) const411     virtual string Serialize(void) const
412     {
413         return "CCassPublicCommentFetch";
414     }
415 
416 public:
GetIdentification(void) const417     EPSGS_Identification  GetIdentification(void) const
418     {
419         return m_Identification;
420     }
421 
SetCassBlobIdentification(const SCass_BlobId & blob_id,int64_t last_modified)422     void SetCassBlobIdentification(const SCass_BlobId &  blob_id,
423                                    int64_t  last_modified)
424     {
425         m_Identification = ePSGS_ByCassBlob;
426         m_BlobId = blob_id;
427         m_LastModified = last_modified;
428     }
429 
SetId2Identification(int64_t id2_chunk,const string & id2_info)430     void SetId2Identification(int64_t  id2_chunk,
431                               const string &  id2_info)
432     {
433         m_Identification = ePSGS_ById2;
434         m_Id2Chunk = id2_chunk;
435         m_Id2Info = id2_info;
436     }
437 
GetBlobId(void) const438     SCass_BlobId  GetBlobId(void) const
439     { return m_BlobId; }
440 
GetLastModified(void) const441     int64_t  GetLastModified(void) const
442     { return m_LastModified; }
443 
GetId2Chunk(void) const444     int64_t  GetId2Chunk(void) const
445     { return m_Id2Chunk; }
446 
GetId2Info(void) const447     string  GetId2Info(void) const
448     { return m_Id2Info; }
449 
SetLoader(CCassStatusHistoryTaskGetPublicComment * fetch)450     void SetLoader(CCassStatusHistoryTaskGetPublicComment *  fetch)
451     { m_Loader.reset(fetch); }
452 
GetLoader(void)453     CCassStatusHistoryTaskGetPublicComment * GetLoader(void)
454     { return static_cast<CCassStatusHistoryTaskGetPublicComment *>(m_Loader.get()); }
455 
456 public:
457     virtual void ResetCallbacks(void);
458 
459 private:
460     // Selector between two options
461     EPSGS_Identification    m_Identification;
462 
463     // ePSGS_ByCassBlob
464     SCass_BlobId            m_BlobId;
465     int64_t                 m_LastModified;
466 
467     // ePSGS_ById2
468     int64_t                 m_Id2Chunk;
469     string                  m_Id2Info;
470 };
471 
472 
473 
474 
475 #endif
476 
477