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