1 #ifndef GET_BLOB_CALLBACK__HPP
2 #define GET_BLOB_CALLBACK__HPP
3 
4 /*  $Id: get_blob_callback.hpp 611588 2020-07-08 14:00:18Z satskyse $
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 "cass_fetch.hpp"
36 #include "pubseq_gateway.hpp"
37 #include "pubseq_gateway_convert_utils.hpp"
38 
39 #include <functional>
40 
41 using TBlobChunkCB = function<void(CCassBlobFetch *  fetch_details,
42                                    CBlobRecord const &  blob,
43                                    const unsigned char *  chunk_data,
44                                    unsigned int  data_size,
45                                    int  chunk_no)>;
46 using TBlobPropsCB = function<void(CCassBlobFetch *  fetch_details,
47                                    CBlobRecord const &  blob,
48                                    bool  is_found)>;
49 using TBlobErrorCB = function<void(CCassBlobFetch *  fetch_details,
50                                    CRequestStatus::ECode  status,
51                                    int  code,
52                                    EDiagSev  severity,
53                                    const string &  message)>;
54 
55 
56 class CBlobChunkCallback
57 {
58     public:
CBlobChunkCallback(TBlobChunkCB blob_chunk_cb,CCassBlobFetch * fetch_details)59         CBlobChunkCallback(TBlobChunkCB  blob_chunk_cb,
60                            CCassBlobFetch *  fetch_details) :
61             m_BlobChunkCB(blob_chunk_cb),
62             m_FetchDetails(fetch_details),
63             m_BlobSize(0),
64             m_BlobRetrieveTiming(chrono::high_resolution_clock::now())
65         {}
66 
operator ()(CBlobRecord const & blob,const unsigned char * data,unsigned int size,int chunk_no)67         void operator()(CBlobRecord const & blob, const unsigned char *  data,
68                         unsigned int  size, int  chunk_no)
69         {
70             if (chunk_no >= 0)
71                 m_BlobSize += size;
72             else
73                 CPubseqGatewayApp::GetInstance()->GetTiming().
74                     Register(eBlobRetrieve, eOpStatusFound,
75                              m_BlobRetrieveTiming, m_BlobSize);
76 
77             m_BlobChunkCB(m_FetchDetails, blob, data, size, chunk_no);
78         }
79 
80     private:
81         TBlobChunkCB            m_BlobChunkCB;
82         CCassBlobFetch *        m_FetchDetails;
83 
84         unsigned long                                   m_BlobSize;
85         chrono::high_resolution_clock::time_point       m_BlobRetrieveTiming;
86 };
87 
88 
89 class CBlobPropCallback
90 {
91     public:
CBlobPropCallback(TBlobPropsCB blob_prop_cb,shared_ptr<CPSGS_Request> request,shared_ptr<CPSGS_Reply> reply,CCassBlobFetch * fetch_details,bool need_timing)92         CBlobPropCallback(
93                 TBlobPropsCB  blob_prop_cb,
94                 shared_ptr<CPSGS_Request>  request,
95                 shared_ptr<CPSGS_Reply>  reply,
96                 CCassBlobFetch *  fetch_details,
97                 bool  need_timing) :
98             m_BlobPropCB(blob_prop_cb),
99             m_Request(request),
100             m_Reply(reply),
101             m_FetchDetails(fetch_details),
102             m_InProcess(false),
103             m_NeedTiming(need_timing)
104         {
105             if (need_timing)
106                 m_BlobPropTiming = chrono::high_resolution_clock::now();
107         }
108 
operator ()(CBlobRecord const & blob,bool is_found)109         void operator()(CBlobRecord const &  blob, bool is_found)
110         {
111             if (!m_InProcess) {
112                 if (m_Request->NeedTrace()) {
113                     if (is_found) {
114                         m_Reply->SendTrace("Cassandra blob props: " +
115                             ToJson(blob).Repr(CJsonNode::fStandardJson),
116                             m_Request->GetStartTimestamp());
117                     } else {
118                         m_Reply->SendTrace("Cassandra blob props not found",
119                                            m_Request->GetStartTimestamp());
120                     }
121                 }
122 
123                 if (m_NeedTiming) {
124                     CPubseqGatewayApp *  app = CPubseqGatewayApp::GetInstance();
125                     if (is_found)
126                         app->GetTiming().Register(eLookupCassBlobProp,
127                                                   eOpStatusFound,
128                                                   m_BlobPropTiming);
129                     else
130                         app->GetTiming().Register(eLookupCassBlobProp,
131                                                   eOpStatusNotFound,
132                                                   m_BlobPropTiming);
133                 }
134 
135                 m_InProcess = true;
136                 m_BlobPropCB(m_FetchDetails, blob, is_found);
137                 m_InProcess = false;
138             }
139         }
140 
141     private:
142         TBlobPropsCB                    m_BlobPropCB;
143         shared_ptr<CPSGS_Request>       m_Request;
144         shared_ptr<CPSGS_Reply>         m_Reply;
145         CCassBlobFetch *                m_FetchDetails;
146 
147         // Avoid an infinite loop
148         bool                            m_InProcess;
149 
150         // Timing
151         bool                                            m_NeedTiming;
152         chrono::high_resolution_clock::time_point       m_BlobPropTiming;
153 };
154 
155 
156 class CGetBlobErrorCallback
157 {
158     public:
CGetBlobErrorCallback(TBlobErrorCB blob_error_cb,CCassBlobFetch * fetch_details)159         CGetBlobErrorCallback(TBlobErrorCB  blob_error_cb,
160                               CCassBlobFetch *  fetch_details) :
161             m_BlobErrorCB(blob_error_cb),
162             m_FetchDetails(fetch_details),
163             m_BlobRetrieveTiming(chrono::high_resolution_clock::now())
164         {}
165 
operator ()(CRequestStatus::ECode status,int code,EDiagSev severity,const string & message)166         void operator()(CRequestStatus::ECode  status,
167                         int  code,
168                         EDiagSev  severity,
169                         const string &  message)
170         {
171             if (status == CRequestStatus::e404_NotFound)
172                 CPubseqGatewayApp::GetInstance()->GetTiming().
173                     Register(eBlobRetrieve, eOpStatusNotFound,
174                              m_BlobRetrieveTiming);
175             m_BlobErrorCB(m_FetchDetails, status, code, severity, message);
176         }
177 
178     private:
179         TBlobErrorCB        m_BlobErrorCB;
180         CCassBlobFetch *    m_FetchDetails;
181 
182         chrono::high_resolution_clock::time_point       m_BlobRetrieveTiming;
183 };
184 
185 #endif
186 
187