1 /* $Id: blob_storage.cpp 617414 2020-09-30 19:55:02Z saprykin $
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:
29 *
30 * The functionality not directly related to blob operations
31 *
32 */
33
34 #include <ncbi_pch.hpp>
35 #include <objtools/pubseq_gateway/impl/cassandra/blob_storage.hpp>
36
37 #define KEYSPACE_MAPPING_CONSISTENCY CassConsistency::CASS_CONSISTENCY_LOCAL_QUORUM
38 #define KEYSPACE_MAPPING_RETRY 5
39
40 BEGIN_IDBLOB_SCOPE
41
42
FetchSatToKeyspaceMapping(const string & mapping_keyspace,shared_ptr<CCassConnection> conn,vector<tuple<string,ECassSchemaType>> & mapping,string & resolver_keyspace,ECassSchemaType resolver_schema,string & err_msg)43 bool FetchSatToKeyspaceMapping(const string & mapping_keyspace,
44 shared_ptr<CCassConnection> conn,
45 vector<tuple<string, ECassSchemaType>> & mapping,
46 string & resolver_keyspace,
47 ECassSchemaType resolver_schema,
48 string & err_msg)
49 {
50 resolver_keyspace.clear();
51 mapping.clear();
52
53 if (mapping_keyspace.empty()) {
54 err_msg = "mapping_keyspace is not specified";
55 return false;
56 }
57
58 bool rv = false;
59 err_msg = "sat2keyspace info is empty";
60
61 for (int i = KEYSPACE_MAPPING_RETRY; i >= 0; --i) {
62 try {
63 shared_ptr<CCassQuery> query = conn->NewQuery();
64
65 query->SetSQL("SELECT\n"
66 " sat,\n"
67 " keyspace_name,\n"
68 " schema_type\n"
69 "FROM\n"
70 " " + mapping_keyspace + ".sat2keyspace", 0);
71 query->Query(KEYSPACE_MAPPING_CONSISTENCY, false, false);
72
73 rv = true;
74 while (query->NextRow() == ar_dataready) {
75 int32_t sat = query->FieldGetInt32Value(0);
76 string name = query->FieldGetStrValue(1);
77 ECassSchemaType schema_type = static_cast<ECassSchemaType>(query->FieldGetInt32Value(2));
78
79 if (schema_type <= eUnknownSchema || schema_type > eMaxSchema) {
80 // ignoring
81 }
82 else if (schema_type == resolver_schema) {
83 if (resolver_keyspace.empty()) {
84 resolver_keyspace = name;
85 }
86 else {
87 // More than one resolver keyspace
88 err_msg = "More than one resolver keyspace in the " +
89 mapping_keyspace + ".sat2keyspace table";
90 rv = false;
91 break;
92 }
93 }
94 else if (sat >= 0) {
95 while (static_cast<int32_t>(mapping.size()) <= sat)
96 mapping.push_back(make_tuple("", eUnknownSchema));
97 mapping[sat] = make_tuple(name, schema_type);
98 }
99 }
100 }
101 catch (const CCassandraException& e) {
102 if ((e.GetErrCode() == CCassandraException::eQueryTimeout || e.GetErrCode() == CCassandraException::eQueryFailedRestartable) && i > 0) {
103 continue;
104 }
105 throw;
106
107 }
108 break;
109 }
110
111 if (rv && mapping.empty()) {
112 err_msg = "sat2keyspace is incomplete";
113 rv = false;
114 }
115 if (rv && resolver_keyspace.empty() && resolver_schema != eUnknownSchema) {
116 err_msg = "resolver schema is not found in sat2keyspace";
117 rv = false;
118 }
119
120 return rv;
121 }
122
123
FetchSatToKeyspaceMapping(const string & mapping_keyspace,shared_ptr<CCassConnection> conn,vector<string> & mapping,ECassSchemaType mapping_schema,string & resolver_keyspace,ECassSchemaType resolver_schema,vector<pair<string,int32_t>> & bioseq_na_keyspaces,ECassSchemaType bioseq_na_schema,string & err_msg)124 bool FetchSatToKeyspaceMapping(const string & mapping_keyspace,
125 shared_ptr<CCassConnection> conn,
126 vector<string> & mapping,
127 ECassSchemaType mapping_schema,
128 string & resolver_keyspace,
129 ECassSchemaType resolver_schema,
130 vector<pair<string, int32_t>> & bioseq_na_keyspaces,
131 ECassSchemaType bioseq_na_schema,
132 string & err_msg)
133 {
134 vector<tuple<string, ECassSchemaType>> lmapping;
135 if (FetchSatToKeyspaceMapping(mapping_keyspace, conn, lmapping, resolver_keyspace, resolver_schema, err_msg)) {
136 for (size_t sat_id = 0; sat_id < lmapping.size(); ++sat_id) {
137 ECassSchemaType schema = get<1>(lmapping[sat_id]);
138 mapping.push_back((schema == mapping_schema ||
139 schema == bioseq_na_schema)? get<0>(lmapping[sat_id]) : "");
140
141 if (schema == bioseq_na_schema)
142 bioseq_na_keyspaces.push_back(
143 pair<string, int32_t>(get<0>(lmapping[sat_id]), sat_id));
144 }
145 return true;
146 }
147 return false;
148 }
149
FetchMessages(const string & mapping_keyspace,shared_ptr<CCassConnection> conn,CPSGMessages & messages,string & err_msg)150 bool FetchMessages(const string & mapping_keyspace,
151 shared_ptr<CCassConnection> conn,
152 CPSGMessages & messages,
153 string & err_msg)
154 {
155 if (mapping_keyspace.empty()) {
156 err_msg = "mapping_keyspace is not specified";
157 return false;
158 }
159
160 bool rv = false;
161 err_msg = mapping_keyspace + ".messages info is empty";
162 for (int i = KEYSPACE_MAPPING_RETRY; i >= 0; --i) {
163 try {
164 shared_ptr<CCassQuery> query = conn->NewQuery();
165 query->SetSQL("SELECT name, value FROM " + mapping_keyspace + ".messages", 0);
166 query->Query(KEYSPACE_MAPPING_CONSISTENCY, false, false);
167 while (query->NextRow() == ar_dataready) {
168 messages.Set(
169 query->FieldGetStrValue(0),
170 query->FieldGetStrValueDef(1, "")
171 );
172 err_msg.clear();
173 }
174 rv = true;
175 break;
176 }
177 catch (const CCassandraException& e) {
178 if (
179 (e.GetErrCode() == CCassandraException::eQueryTimeout || e.GetErrCode() == CCassandraException::eQueryFailedRestartable)
180 && i > 0
181 ) {
182 continue;
183 }
184 throw;
185 }
186 }
187
188 return rv;
189 }
190
191
192 END_IDBLOB_SCOPE
193