NCBI C++ ToolKit
nst_handler.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef NETSTORAGE_HANDLER__HPP
2 #define NETSTORAGE_HANDLER__HPP
3 
4 /* $Id: nst_handler.hpp 99345 2023-03-14 14:21:41Z 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: Denis Vakatov
30  *
31  * File Description: NetStorage commands handler
32  *
33  */
34 
35 #include <string>
37 #include <corelib/ncbitime.hpp>
38 #include <corelib/request_ctx.hpp>
39 #include <connect/server.hpp>
41 
42 #include "nst_clients.hpp"
43 #include "nst_users.hpp"
44 #include "nst_metadata_options.hpp"
45 #include "nst_database.hpp"
47 #include "nst_timing.hpp"
48 
49 
51 
52 const size_t kReadBufferSize = 1024 * 1024;
53 const size_t kWriteBufferSize = 16 * 1024;
54 
55 
56 // Forward declarations
57 class CNetStorageServer;
59 struct SStorageFlags;
60 struct SICacheSettings;
61 struct SUserKey;
62 
63 
64 // Helper class to make sure the current request context is reset at the end of
65 // the scope
67 {
68  public:
71 };
72 
73 
74 // Helper class to make sure the pushed IMessageListener is popped
75 // approprietely at the end of the scope
77 {
78  public:
81 };
82 
83 
84 // The CRelocateCallback is used to provide a callback during the RELOCATE
85 // message processing. The NetStorageAPI Relocate call is synchronous so
86 // it may take a long time within which the client socket could time out.
87 // The callback is called after each portion of data is relocated so it is
88 // a good suitable point to send a heartbeat message to the client. The
89 // heartbeat - in addition to the keeping the connection active - sends some
90 // progress information, notably the number of the relocated bytes.
91 class CNetStorageHandler;
93 {
94  public:
96  const SCommonRequestArguments & common_args,
97  CDirectNetStorageObject & object,
98  bool need_progress_report);
99 
100  public:
101  // Should match TNetStorageProgressCb prototype
102  void Callback(CJsonNode info);
103 
104  private:
109 };
110 
111 
113 {
114 public:
115 
118 
119  // IServer_ConnectionHandler protocol
120  virtual EIO_Event GetEventsToPollFor(const CTime** alarm_time) const;
121  virtual void OnOpen(void);
122  virtual void OnRead(void);
123  virtual void OnWrite(void);
125  virtual void OnTimeout(void);
126  virtual void OnOverflow(EOverflowReason reason);
127 
128  // Statuses of commands to be set in diagnostics' request context
129  // Additional statuses can be taken from
130  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
131  enum EHTTPStatus {
132  eStatus_OK = 200, // Command is ok and execution
133  // is good
134 
135  eStatus_BadRequest = 400, // Command is incorrect
136  eStatus_NotFound = 404, // Object is not found
137  eStatus_Inactive = 408, // Connection was closed due to
138  // inactivity timeout
139  eStatus_Probe = 444, // Routine test from systems
140  eStatus_SocketIOError = 499, // Error writing to socket
141 
142  eStatus_ServerError = 500, // Internal server error
143  eStatus_NotImplemented = 501, // Command is not implemented
144  eStatus_ShuttingDown = 503 // Server is shutting down
145  };
146 
147  // In most of the case a socket timeout is considered as an error however
148  // there could be a case -- e.g. candidate is the relocate progress message
149  // -- when a timeout needs to be ignored. So there is an enumeration below.
153  };
154 
155 private:
156  // Application specific part
157  bool x_ReadRawData();
158  void x_OnMessage(const CJsonNode & message);
159  void x_OnData(const void * data, size_t data_size);
161 
162  // It closes the connection if there were socket writing errors
164  const CJsonNode & message,
165  ESocketTimeoutTreat timeout_treat = eTimeoutIsError);
167  void x_OnSocketWriteError(EIO_Status status, size_t bytes_written,
168  const char * output_buffer,
169  size_t output_buffer_size);
170  void x_PrintMessageRequestStart(const CJsonNode & message);
171  void x_PrintMessageRequestStop(void);
172 
173  // Future versions may send the messages asynchronously
174  void x_SendAsyncMessage(const CJsonNode & message);
175 
176 private:
177  void x_SetQuickAcknowledge(void);
178  void x_SetCmdRequestStatus(unsigned int status)
179  { if (m_CmdContext.NotNull())
180  m_CmdContext->SetRequestStatus(status); }
181  void x_SetConnRequestStatus(unsigned int status)
182  { if (m_ConnContext.NotNull())
183  m_ConnContext->SetRequestStatus(status); }
184 
185 private:
186  void x_CreateConnContext(void);
187  unsigned int x_GetPeerAddress(void);
188 
190 
191  // Diagnostics context for the current connection
193  // Diagnostics context for the currently executed command
195 
196  // The client identification. It appears after HELLO.
197  string m_Service;
198  string m_Client;
199 
200 private:
201  enum EReadMode {
204  };
205 
210 
214 
216  vector<CJsonNode> m_OutputQueue;
217 
218 private:
219  // Asynchronous write support
229 
230 private:
234 
236 
237  typedef void (CNetStorageHandler::*FProcessor)(
238  const CJsonNode &,
239  const SCommonRequestArguments &);
241  {
244  };
247 
248  // Individual message processors
249  // The return value is how many bytes are expected as raw data
250  void x_ProcessBye(const CJsonNode & message,
251  const SCommonRequestArguments & common_args);
252  void x_ProcessHello(const CJsonNode & message,
253  const SCommonRequestArguments & common_args);
254  void x_ProcessInfo(const CJsonNode & message,
255  const SCommonRequestArguments & common_args);
256  void x_ProcessConfiguration(const CJsonNode & message,
257  const SCommonRequestArguments & common_args);
258  void x_ProcessHealth(const CJsonNode & message,
259  const SCommonRequestArguments & common_args);
260  void x_ProcessAckAlert(const CJsonNode & message,
261  const SCommonRequestArguments & common_args);
262  void x_ProcessReconfigure(const CJsonNode & message,
263  const SCommonRequestArguments & common_args);
264  void x_ProcessShutdown(const CJsonNode & message,
265  const SCommonRequestArguments & common_args);
266  void x_ProcessGetClientsInfo(const CJsonNode & message,
267  const SCommonRequestArguments & common_args);
268  void x_ProcessGetUsersInfo(const CJsonNode & message,
269  const SCommonRequestArguments & common_args);
270  void x_ProcessGetMetadataInfo(const CJsonNode & message,
271  const SCommonRequestArguments & common_args);
272  void x_ProcessGetObjectInfo(const CJsonNode & message,
273  const SCommonRequestArguments & common_args);
274  void x_ProcessGetAttrList(const CJsonNode & message,
275  const SCommonRequestArguments & common_args);
276  void x_ProcessGetClientObjects(const CJsonNode & message,
277  const SCommonRequestArguments & comm_args);
278  void x_ProcessGetUserObjects(const CJsonNode & message,
279  const SCommonRequestArguments & comm_args);
280  void x_ProcessGetAttr(const CJsonNode & message,
281  const SCommonRequestArguments & common_args);
282  void x_ProcessSetAttr(const CJsonNode & message,
283  const SCommonRequestArguments & common_args);
284  void x_ProcessDelAttr(const CJsonNode & message,
285  const SCommonRequestArguments & common_args);
286  void x_ProcessRead(const CJsonNode & message,
287  const SCommonRequestArguments & common_args);
288  void x_ProcessCreate(const CJsonNode & message,
289  const SCommonRequestArguments & common_args);
290  void x_ProcessWrite(const CJsonNode & message,
291  const SCommonRequestArguments & common_args);
292  void x_ProcessDelete(const CJsonNode & message,
293  const SCommonRequestArguments & common_args);
294  void x_ProcessRelocate(const CJsonNode & message,
295  const SCommonRequestArguments & common_args);
296  void x_ProcessExists(const CJsonNode & message,
297  const SCommonRequestArguments & common_args);
298  void x_ProcessGetSize(const CJsonNode & message,
299  const SCommonRequestArguments & common_args);
300  void x_ProcessSetExpTime(const CJsonNode & message,
301  const SCommonRequestArguments & common_args);
302  void x_ProcessLockFTPath(const CJsonNode & message,
303  const SCommonRequestArguments & common_args);
304 
305 private:
307  bool need_fake_write = false);
308  void x_CheckObjectLoc(const string & object_loc) const;
309  void x_CheckICacheSettings(const SICacheSettings & icache_settings);
310  void x_CheckUserKey(const SUserKey & user_key);
311  void x_GetStorageParams(const CJsonNode & message,
312  SICacheSettings * icache_settings,
313  SUserKey * user_key,
316  const SICacheSettings & icache_settings,
319  EMetadataOption x_ConvertMetadataArgument(const CJsonNode & message) const;
320  void x_ValidateWriteMetaDBAccess(const CJsonNode & message,
321  bool expect_object = true) const;
322  bool x_DetectMetaDBNeedUpdate(const CJsonNode & message,
323  CNSTServiceProperties & props) const;
326  const CJsonNode & message,
327  CNSTServiceProperties & props) const;
328  void x_CreateClient(void);
329  Int8 x_GetClientID(const string & client);
330  void x_CreateUser(void);
331  Int8 x_GetUserID(const CNSTUserID & user);
332  void x_FillObjectInfo(CJsonNode & reply, const string & val);
333  void x_SetObjectInfoReply(CJsonNode & reply, const string & name,
334  const TNSTDBValue<CTime> & value);
335  void x_SetObjectInfoReply(CJsonNode & reply, const string & name,
336  const TNSTDBValue<Int8> & value);
337  void x_SetObjectInfoReply(CJsonNode & reply, const string & name,
338  const TNSTDBValue<string> & value);
339 
341  CJsonNode & reply,
342  const string & user_message);
343  void x_CheckExistanceStatus(int status);
344  void x_CheckExpirationStatus(int status);
345  void x_CheckNonAnonymousClient(const string & op) const;
346  string x_GetConnRef(void);
347 
348 private:
349  enum EOp {
353  };
355  const string & object_key,
356  const CNSTServiceProperties & service_props);
357 
358  friend class CRelocateCallback;
359 }; // CNetStorageHandler
360 
361 
363 
364 #endif
365 
CFastMutex –.
Definition: ncbimtx.hpp:667
JSON node abstraction.
EIO_Status x_SendSyncMessage(const CJsonNode &message, ESocketTimeoutTreat timeout_treat=eTimeoutIsError)
string x_GetConnRef(void)
virtual void OnRead(void)
The client has just sent data.
void x_SetObjectInfoReply(CJsonNode &reply, const string &name, const TNSTDBValue< CTime > &value)
void x_ProcessHello(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_CheckExistanceStatus(int status)
void x_SendAsyncMessage(const CJsonNode &message)
virtual void OnOpen(void)
Runs in response to an external event [asynchronous].
void x_CheckNonAnonymousClient(const string &op) const
void x_ProcessConfiguration(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_ProcessSetExpTime(const CJsonNode &message, const SCommonRequestArguments &common_args)
bool x_DetectMetaDBNeedOnGetObjectInfo(const CJsonNode &message, CNSTServiceProperties &props) const
void x_PrintMessageRequestStart(const CJsonNode &message)
unsigned int x_GetPeerAddress(void)
void x_ProcessWrite(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_ProcessSetAttr(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_CheckUserKey(const SUserKey &user_key)
TNSTDBValue< CTimeSpan > m_CreateTTL
virtual EIO_Event GetEventsToPollFor(const CTime **alarm_time) const
Following three methods are guaranteed to be called NOT at the same time as On*, so if you implement ...
CDirectNetStorageObject x_CreateObjectStream(const SICacheSettings &icache_settings, TNetStorageFlags flags)
void x_ProcessGetSize(const CJsonNode &message, const SCommonRequestArguments &common_args)
EIO_Status x_SendOutputBuffer(ESocketTimeoutTreat timeout_treat)
void x_ProcessAckAlert(const CJsonNode &message, const SCommonRequestArguments &common_args)
void(CNetStorageHandler::* FProcessor)(const CJsonNode &, const SCommonRequestArguments &)
CRef< CRequestContext > m_ConnContext
void x_ProcessRead(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_CreateConnContext(void)
void x_ProcessGetClientObjects(const CJsonNode &message, const SCommonRequestArguments &comm_args)
void x_ProcessGetObjectInfo(const CJsonNode &message, const SCommonRequestArguments &common_args)
virtual void OnWrite(void)
The client is ready to receive data.
void x_ProcessShutdown(const CJsonNode &message, const SCommonRequestArguments &common_args)
CUTTPReader m_UTTPReader
void x_CreateUser(void)
void x_ProcessReconfigure(const CJsonNode &message, const SCommonRequestArguments &common_args)
CNetStorageHandler(CNetStorageServer *server)
void x_ProcessGetClientsInfo(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_SetConnRequestStatus(unsigned int status)
void x_SetQuickAcknowledge(void)
void x_CreateClient(void)
CNSTServiceProperties m_WriteServiceProps
void x_PrintMessageRequestStop(void)
void x_FillObjectInfo(CJsonNode &reply, const string &val)
void x_ProcessGetUsersInfo(const CJsonNode &message, const SCommonRequestArguments &common_args)
char m_WriteBuffer[kWriteBufferSize]
virtual void OnOverflow(EOverflowReason reason)
Runs when there are insufficient resources to queue a connection, prior to closing it.
void x_ProcessGetMetadataInfo(const CJsonNode &message, const SCommonRequestArguments &common_args)
virtual void OnTimeout(void)
Runs when a client has been idle for too long, prior to closing the connection [synchronous].
void x_ProcessDelAttr(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_OnSocketWriteError(EIO_Status status, size_t bytes_written, const char *output_buffer, size_t output_buffer_size)
CUTTPWriter m_UTTPWriter
void x_ProcessGetAttrList(const CJsonNode &message, const SCommonRequestArguments &common_args)
CFastMutex m_OutputQueueMutex
void x_CheckExpirationStatus(int status)
EMetadataOption x_ConvertMetadataArgument(const CJsonNode &message) const
CDirectNetStorageObject m_ObjectBeingWritten
void x_ProcessRelocate(const CJsonNode &message, const SCommonRequestArguments &common_args)
virtual void OnClose(IServer_ConnectionHandler::EClosePeer peer)
The connection has closed (with information on type of closing)
CNetStorageServer * m_Server
void x_ProcessBye(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_ProcessGetAttr(const CJsonNode &message, const SCommonRequestArguments &common_args)
EIO_Status x_SendOverUTTP()
CRef< CRequestContext > m_CmdContext
CDirectNetStorageObject x_GetObject(const CJsonNode &message, bool need_fake_write=false)
bool x_DetectMetaDBNeedUpdate(const CJsonNode &message, CNSTServiceProperties &props) const
void x_ProcessInfo(const CJsonNode &message, const SCommonRequestArguments &common_args)
bool m_WriteCreateNeedMetaDBUpdate
CJsonOverUTTPWriter m_JSONWriter
Int8 x_GetUserID(const CNSTUserID &user)
void x_ProcessLockFTPath(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_CheckICacheSettings(const SICacheSettings &icache_settings)
void x_OptionalExpirationUpdate(CDirectNetStorageObject &object, CJsonNode &reply, const string &user_message)
static SProcessorMap sm_Processors[]
bool x_DetectMetaDBNeedOnCreate(TNetStorageFlags flags)
EMetadataOption m_MetadataOption
void x_ProcessGetUserObjects(const CJsonNode &message, const SCommonRequestArguments &comm_args)
char m_ReadBuffer[kReadBufferSize]
Int8 x_GetClientID(const string &client)
void x_GetStorageParams(const CJsonNode &message, SICacheSettings *icache_settings, SUserKey *user_key, TNetStorageFlags *flags)
void x_SendWriteConfirmation()
vector< CJsonNode > m_OutputQueue
void x_ProlongObjectOnFailure(EOp operation, const string &object_key, const CNSTServiceProperties &service_props)
void x_ProcessCreate(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_ProcessDelete(const CJsonNode &message, const SCommonRequestArguments &common_args)
FProcessor x_FindProcessor(const SCommonRequestArguments &common_args)
void x_CheckObjectLoc(const string &object_loc) const
CJsonOverUTTPReader m_JSONReader
void x_OnData(const void *data, size_t data_size)
void x_ValidateWriteMetaDBAccess(const CJsonNode &message, bool expect_object=true) const
void x_OnMessage(const CJsonNode &message)
void x_ProcessHealth(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_ProcessExists(const CJsonNode &message, const SCommonRequestArguments &common_args)
void x_SetCmdRequestStatus(unsigned int status)
const SCommonRequestArguments & m_CommonArgs
CNetStorageHandler & m_Handler
CRelocateCallback(CNetStorageHandler &handler, const SCommonRequestArguments &common_args, CDirectNetStorageObject &object, bool need_progress_report)
void Callback(CJsonNode info)
CDirectNetStorageObject & m_Object
CTime –.
Definition: ncbitime.hpp:296
Class for reading series of chunks sent by a CUTTPWriter instance as a stream of bytes.
Definition: uttp.hpp:94
Class that serializes series of chunks of data for sending over binary streams.
Definition: uttp.hpp:297
IServer_ConnectionHandler::
Definition: server.hpp:226
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
static uch flags
char data[12]
Definition: iconv.c:80
void SetRequestStatus(int status)
unsigned TNetStorageFlags
Bitwise OR of ENetStorageFlags.
Definition: netstorage.hpp:147
bool NotNull(void) const THROWS_NONE
Check if pointer is not null – same effect as NotEmpty().
Definition: ncbiobj.hpp:744
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
EClosePeer
Type of connection closing.
Definition: server.hpp:268
EOverflowReason
Error codes for OnOverflow method in IServer_ConnectionHandler.
Definition: server.hpp:210
EIO_Status
I/O status.
Definition: ncbi_core.h:132
EIO_Event
I/O event (or direction).
Definition: ncbi_core.h:118
operation
Bit operations.
Definition: bmconst.h:191
static MDB_envinfo info
Definition: mdb_load.c:37
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
Defines: CTimeFormat - storage class for time format.
const size_t kWriteBufferSize
Definition: nst_handler.hpp:53
const size_t kReadBufferSize
Definition: nst_handler.hpp:52
Defines CRequestContext class for NCBI C++ diagnostic API.
Framework to create multithreaded network servers with thread-per-request scheduling.
static CNamedPipeClient * client
Modified on Fri Sep 20 14:57:53 2024 by modify_doxy.py rev. 669887