1 /*  $Id: cass_processor_base.cpp 629837 2021-04-22 12:47:49Z ivanov $
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: base class for processors which may generate cassandra
29  *                   fetches
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 
35 #include <corelib/request_status.hpp>
36 #include <corelib/ncbidiag.hpp>
37 
38 #include "cass_processor_base.hpp"
39 #include "pubseq_gateway.hpp"
40 
41 
CPSGS_CassProcessorBase()42 CPSGS_CassProcessorBase::CPSGS_CassProcessorBase() :
43     m_Completed(false),
44     m_Cancelled(false),
45     m_InPeek(false),
46     m_Status(CRequestStatus::e200_Ok)
47 {}
48 
49 
CPSGS_CassProcessorBase(shared_ptr<CPSGS_Request> request,shared_ptr<CPSGS_Reply> reply,TProcessorPriority priority)50 CPSGS_CassProcessorBase::CPSGS_CassProcessorBase(
51                                             shared_ptr<CPSGS_Request> request,
52                                             shared_ptr<CPSGS_Reply> reply,
53                                             TProcessorPriority  priority) :
54     m_Completed(false),
55     m_Cancelled(false),
56     m_InPeek(false),
57     m_Status(CRequestStatus::e200_Ok)
58 {
59     IPSGS_Processor::m_Request = request;
60     IPSGS_Processor::m_Reply = reply;
61     IPSGS_Processor::m_Priority = priority;
62 }
63 
64 
~CPSGS_CassProcessorBase()65 CPSGS_CassProcessorBase::~CPSGS_CassProcessorBase()
66 {}
67 
68 
GetStatus(void) const69 IPSGS_Processor::EPSGS_Status CPSGS_CassProcessorBase::GetStatus(void) const
70 {
71     if (m_Completed) {
72         // Finished before initiating any cassandra fetches
73         return x_GetProcessorStatus();
74     }
75 
76     if (AreAllFinishedRead()) {
77         // Finished because all cassandra requests completed reading
78         return x_GetProcessorStatus();
79     }
80 
81     return IPSGS_Processor::ePSGS_InProgress;
82 }
83 
84 
AreAllFinishedRead(void) const85 bool CPSGS_CassProcessorBase::AreAllFinishedRead(void) const
86 {
87     size_t      started_count = 0;
88     for (const auto &  details: m_FetchDetails) {
89         if (details) {
90             ++started_count;
91             if (!details->Cancelled()) {
92                 if (!details->ReadFinished()) {
93                     return false;
94                 }
95             }
96         }
97     }
98     return started_count != 0;
99 }
100 
101 
CancelLoaders(void)102 void CPSGS_CassProcessorBase::CancelLoaders(void)
103 {
104     for (auto &  loader: m_FetchDetails) {
105         if (loader) {
106             if (!loader->ReadFinished()) {
107                 loader->Cancel();
108 
109                 // Imitate the Cassandra data ready event. This will eventually
110                 // lead to a pending operation Peek() call which in turn calls
111                 // Wait() for the loader. The Wait() return value should say in
112                 // this case that there will be nothing else.
113                 IPSGS_Processor::m_Reply->GetDataReadyCB()->OnData();
114             }
115         }
116     }
117 }
118 
119 
120 IPSGS_Processor::EPSGS_Status
x_GetProcessorStatus(void) const121 CPSGS_CassProcessorBase::x_GetProcessorStatus(void) const
122 {
123     switch (m_Status) {
124         case CRequestStatus::e200_Ok:
125             return IPSGS_Processor::ePSGS_Found;
126         case CRequestStatus::e404_NotFound:
127             return IPSGS_Processor::ePSGS_NotFound;
128         default:
129             break;
130     }
131     return IPSGS_Processor::ePSGS_Error;
132 }
133 
134 
135 void
UpdateOverallStatus(CRequestStatus::ECode status)136 CPSGS_CassProcessorBase::UpdateOverallStatus(CRequestStatus::ECode  status)
137 {
138     m_Status = max(status, m_Status);
139 }
140 
141 
142 bool
IsCassandraProcessorEnabled(shared_ptr<CPSGS_Request> request) const143 CPSGS_CassProcessorBase::IsCassandraProcessorEnabled(
144                                     shared_ptr<CPSGS_Request> request) const
145 {
146     // CXX-11549: for the time being the processor name does not participate in
147     //            the decision. Only the hardcoded "cassandra" is searched in
148     //            the enable/disable list.
149     //            Also, what list is consulted depends on a configuration file
150     //            setting which tells whether the cassandra processors are
151     //            enabled or not. This leads to a nice case when looking at the
152     //            request it is impossible to say if a processor was enabled or
153     //            disabled at the time of request if enable/disable options are
154     //            not in the request.
155     static string   kCassandra = "cassandra";
156 
157     auto *      app = CPubseqGatewayApp::GetInstance();
158     bool        enabled = app->GetCassandraProcessorsEnabled();
159 
160     if (enabled) {
161         for (const auto &  dis_processor :
162                 request->GetRequest<SPSGS_RequestBase>().m_DisabledProcessors) {
163             if (NStr::CompareNocase(dis_processor, kCassandra) == 0) {
164                 return false;
165             }
166         }
167     } else {
168         for (const auto &  en_processor :
169                 request->GetRequest<SPSGS_RequestBase>().m_EnabledProcessors) {
170             if (NStr::CompareNocase(en_processor, kCassandra) == 0) {
171                 return true;
172             }
173         }
174     }
175 
176     return enabled;
177 }
178 
179