NCBI C++ ToolKit
nst_protocol_utils.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: nst_protocol_utils.cpp 71392 2016-03-02 17:13:12Z satskyse $
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: NetStorage communication protocol utils
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/request_ctx.hpp>
34 #include <connect/ncbi_socket.hpp>
36 
37 #include "nst_protocol_utils.hpp"
38 #include "nst_exception.hpp"
39 #include "error_codes.hpp"
40 
41 
42 
44 
45 
46 void SetSessionAndIPAndPHID(const CJsonNode & message,
47  const CSocket & peer)
48 {
49  if (message.HasKey("SessionID")) {
50  string session = message.GetString("SessionID");
51  if (!session.empty())
53  session);
54  }
55 
56 
57  string client_ip;
58  if (message.HasKey("ClientIP"))
59  client_ip = message.GetString("ClientIP");
60 
61  if (client_ip.empty())
63  peer.GetPeerAddress(eSAF_IP));
64  else
66  client_ip);
67 
68  // CXX-7893: ncbi_context has preference over ncbi_phid
69  bool ncbi_context_deserialized = false;
70  if (message.HasKey("ncbi_context")) {
71  try {
72  string context = message.GetString("ncbi_context");
75 
76  ncbi_context_deserialized = true;
77  } catch (const exception & ex) {
78  ERR_POST(ex.what());
79  }
80  }
81 
82  if (ncbi_context_deserialized == false && message.HasKey("ncbi_phid")) {
83  try {
84  string ncbi_phid = message.GetString("ncbi_phid");
85  if (!ncbi_phid.empty())
87  } catch (const exception & ex) {
88  ERR_POST(ex.what());
89  }
90  }
91 }
92 
93 
96 {
98  try {
99  result.m_SerialNumber = message.GetInteger("SN");
100  result.m_MessageType = message.GetString("Type");
101  }
102  catch (const std::exception & ex) {
103  // Converting to the CNetStorageServerException is done to
104  // have generic request status handling.
105  NCBI_THROW(CNetStorageServerException, eInvalidIncomingMessage,
106  ex.what());
107  }
108  return result;
109 }
110 
111 
114 {
116 
117  if (message.HasKey("StorageFlags")) {
118  CJsonNode flags = message.GetByKey("StorageFlags");
119  if (flags.HasKey("Fast") && flags.GetBoolean("Fast"))
120  result |= fNST_Fast;
121  if (flags.HasKey("Persistent") && flags.GetBoolean("Persistent"))
123  if (flags.HasKey("NetCache") && flags.GetBoolean("NetCache"))
125  if (flags.HasKey("FileTrack") && flags.GetBoolean("FileTrack"))
127  if (flags.HasKey("Movable") && flags.GetBoolean("Movable"))
128  result |= fNST_Movable;
129  if (flags.HasKey("Cacheable") && flags.GetBoolean("Cacheable"))
131  if (flags.HasKey("NoMetaData") && flags.GetBoolean("NoMetaData"))
133  }
134  return result;
135 }
136 
137 
140 {
142 
143  if (message.HasKey("ICache")) {
144  CJsonNode settings = message.GetByKey("ICache");
145  if (settings.HasKey("ServiceName"))
146  result.m_ServiceName = settings.GetString("ServiceName");
147  if (settings.HasKey("CacheName"))
148  result.m_CacheName = settings.GetString("CacheName");
149  }
150  return result;
151 }
152 
153 
154 SUserKey
155 ExtractUserKey(const CJsonNode & message)
156 {
158 
159  if (message.HasKey("UserKey")) {
160  CJsonNode user_key = message.GetByKey("UserKey");
161  if (user_key.HasKey("UniqueID"))
162  result.m_UniqueID = user_key.GetString("UniqueID");
163  if (user_key.HasKey("AppDomain"))
164  result.m_AppDomain = user_key.GetString("AppDomain");
165  }
166  return result;
167 }
168 
169 
170 CJsonNode
172 {
173  CJsonNode reply_message(CJsonNode::NewObjectNode());
174 
175  reply_message.SetString("Type", kMessageTypeReply);
176  reply_message.SetString("Status", kStatusOK);
177  reply_message.SetInteger("RE", serial_number);
178 
179  return reply_message;
180 }
181 
182 
183 CJsonNode
185  Int8 error_code,
186  const string & error_message,
187  const string & scope,
188  Int8 sub_code)
189 {
190  CJsonNode reply_message(CJsonNode::NewObjectNode());
192 
193  reply_message.SetString("Type", kMessageTypeReply);
194  reply_message.SetString("Status", kStatusError);
195  reply_message.SetInteger("RE", serial_number);
196 
197  errors.Append(CreateIssue(error_code, error_message, scope, sub_code));
198 
199  reply_message.SetByKey("Errors", errors);
200 
201  return reply_message;
202 }
203 
204 
205 void
207  Int8 code,
208  const string & warning_message,
209  const string & scope,
210  Int8 sub_code)
211 {
212  CJsonNode warnings;
213  if (!message.HasKey("Warnings"))
214  message.SetByKey("Warnings", warnings = CJsonNode::NewArrayNode());
215  else
216  warnings = message.GetByKey("Warnings");
217 
218  warnings.Append(CreateIssue(code, warning_message, scope, sub_code));
219 }
220 
221 
222 void
224  Int8 code,
225  const string & error_message,
226  const string & scope,
227  Int8 sub_code,
228  bool update_status)
229 {
230  if (update_status)
231  message.SetString("Status", kStatusError);
232 
233  CJsonNode errors;
234  if (!message.HasKey("Errors"))
235  message.SetByKey("Errors", errors = CJsonNode::NewArrayNode());
236  else
237  errors = message.GetByKey("Errors");
238 
239  errors.Append(CreateIssue(code, error_message, scope, sub_code));
240 }
241 
242 
243 CJsonNode
244 CreateIssue(Int8 error_code,
245  const string & error_message,
246  const string & scope,
247  Int8 sub_code)
248 {
249  CJsonNode issue_node(CJsonNode::NewObjectNode());
250 
251  issue_node.SetInteger("Code", error_code);
252  issue_node.SetString("Message", error_message);
253  issue_node.SetString("Scope", scope);
254  issue_node.SetInteger("SubCode", sub_code);
255 
256  return issue_node;
257 }
258 
259 
260 bool GetReplyMessageProperties(const exception & ex,
261  string * error_scope,
262  Int8 * error_code,
263  unsigned int * error_sub_code)
264 {
265  const CNetStorageException * p =
266  dynamic_cast<const CNetStorageException *>(&ex);
267  if (p != NULL) {
268  *error_scope = p->GetType();
269  *error_code = NCBI_ERRCODE_X_NAME(NetStorageException_ErrorCode);
270  *error_sub_code = p->GetErrCode();
271  return true;
272  }
273 
274  const CNetServiceException * p1 =
275  dynamic_cast<const CNetServiceException *>(&ex);
276  if (p1 != NULL) {
277  *error_scope = p1->GetType();
278  *error_code = NCBI_ERRCODE_X_NAME(NetServiceException_ErrorCode);
279  *error_sub_code = p1->GetErrCode();
280  return true;
281  }
282 
283  const CNetStorageServerException * p2 =
284  dynamic_cast<const CNetStorageServerException *>(&ex);
285  if (p2 != NULL) {
286  *error_scope = p2->GetType();
287  *error_code = NCBI_ERRCODE_X_NAME(NetStorageServer_ErrorCode);
288  *error_sub_code = p2->GetErrCode();
289  return true;
290  }
291 
292  const CException * p3 =
293  dynamic_cast<const CException *>(&ex);
294  if (p3 != NULL) {
295  *error_scope = p3->GetType();
296  *error_code = NCBI_ERRCODE_X_NAME(NetStorageServer_ErrorCode);
297  *error_sub_code = 0;
298  return false;
299  }
300 
301  *error_scope = kScopeStdException;
302  *error_code = NCBI_ERRCODE_X_NAME(NetStorageServer_ErrorCode);
303  *error_sub_code = 0;
304  return false;
305 }
306 
307 
309 
JSON node abstraction.
static CJsonNode NewArrayNode()
Create a new JSON array node.
bool HasKey(const string &key) const
Check if an object node has an element accessible by the specified key.
void SetString(const string &key, const string &value)
Set a JSON object element to the specified string value.
Int8 GetInteger(const string &key) const
For a JSON object node, return the integer referred to by the specified key.
string GetString(const string &key) const
For a JSON object node, return the string referred to by the specified key.
void SetInteger(const string &key, Int8 value)
Set a JSON object element to the specified integer value.
void SetByKey(const string &key, CJsonNode::TInstance value)
For a JSON object node, insert a new element or update an existing element.
static CJsonNode NewObjectNode()
Create a new JSON object node.
void Append(CJsonNode::TInstance value)
For an array node, add a new element at the end of the array.
CJsonNode GetByKey(const string &key) const
For a JSON object node, return the value associated with the specified key.
Net Service exception.
Exception class for use by CNetStorage, CNetStorageByKey, and CNetStorageObject.
Definition: netstorage.hpp:67
Request context properties passed between tasks.
CSocket::
static uch flags
#define NULL
Definition: ncbistd.hpp:225
void SetSessionID(const string &session)
void SetClientIP(const string &client)
#define NCBI_ERRCODE_X_NAME(name)
Returns value of error code by its name defined by NCBI_DEFINE_ERRCODE_X.
Definition: ncbidiag.hpp:369
static CRequestContext & GetRequestContext(void)
Shortcut to CDiagContextThreadData::GetThreadData().GetRequestContext()
Definition: ncbidiag.cpp:1901
void Deserialize(CTempString data, EFormat format)
Deserialize values using the specified format.
void SetHitID(const string &hit)
Set explicit hit id. The id is reset on request end.
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
@ eFormat_UrlEncoded
name=value pairs URL-encoded and separated with '&'
virtual const char * GetType(void) const
Get class name as a string.
Definition: ncbiexpt.cpp:268
TErrCode GetErrCode(void) const
Get error code.
Definition: ncbiexpt.cpp:453
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
unsigned TNetStorageFlags
Bitwise OR of ENetStorageFlags.
Definition: netstorage.hpp:147
@ fNST_NoMetaData
Do not use NetStorage relational database to track ownership & changes.
Definition: netstorage.hpp:140
@ fNST_Persistent
Definition: netstorage.hpp:135
@ fNST_Cacheable
Has no effect at the moment.
Definition: netstorage.hpp:139
@ fNST_Fast
Definition: netstorage.hpp:134
@ fNST_NetCache
Use NetCache as the primary storage.
Definition: netstorage.hpp:130
@ fNST_FileTrack
Use FileTrack as the primary storage.
Definition: netstorage.hpp:131
@ fNST_Movable
Allow the object to move between storages.
Definition: netstorage.hpp:138
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
void GetPeerAddress(unsigned int *host, unsigned short *port, ENH_ByteOrder byte_order) const
Get peer address.
@ eSAF_IP
only numeric IP if INET socket, empty otherwise
Definition: ncbi_socket.h:1392
CJsonNode CreateIssue(Int8 error_code, const string &error_message, const string &scope, Int8 sub_code)
void AppendError(CJsonNode &message, Int8 code, const string &error_message, const string &scope, Int8 sub_code, bool update_status)
TNetStorageFlags ExtractStorageFlags(const CJsonNode &message)
bool GetReplyMessageProperties(const exception &ex, string *error_scope, Int8 *error_code, unsigned int *error_sub_code)
CJsonNode CreateResponseMessage(Int8 serial_number)
CJsonNode CreateErrorResponseMessage(Int8 serial_number, Int8 error_code, const string &error_message, const string &scope, Int8 sub_code)
SUserKey ExtractUserKey(const CJsonNode &message)
void AppendWarning(CJsonNode &message, Int8 code, const string &warning_message, const string &scope, Int8 sub_code)
void SetSessionAndIPAndPHID(const CJsonNode &message, const CSocket &peer)
SCommonRequestArguments ExtractCommonFields(const CJsonNode &message)
SICacheSettings ExtractICacheSettings(const CJsonNode &message)
const string kMessageTypeReply
const string kStatusError
const string kStatusOK
const string kScopeStdException
Defines CRequestContext class for NCBI C++ diagnostic API.
Definition: inftrees.h:24
else result
Definition: token2.c:20
static CS_CONTEXT * context
Definition: will_convert.c:21
Modified on Mon Jun 17 05:06:53 2024 by modify_doxy.py rev. 669887