1 #ifndef NETCACHE_NC_UTILS__HPP
2 #define NETCACHE_NC_UTILS__HPP
3 /*  $Id: nc_utils.hpp 632770 2021-06-07 19:05:12Z ivanov $
4  * ===========================================================================
5  *
6  *                            PUBLIC DOMAIN NOTICE
7  *               National Center for Biotechnology Information
8  *
9  *  This software/database is a "United States Government Work" under the
10  *  terms of the United States Copyright Act.  It was written as part of
11  *  the author's official duties as a United States Government employee and
12  *  thus cannot be copyrighted.  This software/database is freely available
13  *  to the public for use. The National Library of Medicine and the U.S.
14  *  Government have not placed any restriction on its use or reproduction.
15  *
16  *  Although all reasonable efforts have been taken to ensure the accuracy
17  *  and reliability of the software and data, the NLM and the U.S.
18  *  Government do not and cannot warrant the performance or results that
19  *  may be obtained by using this software or data. The NLM and the U.S.
20  *  Government disclaim all warranties, express or implied, including
21  *  warranties of performance, merchantability or fitness for any particular
22  *  purpose.
23  *
24  *  Please cite the author in any work or product based on this material.
25  *
26  * ===========================================================================
27  *
28  * Authors:  Pavel Ivanov
29  *
30  * File Description:
31  *   Utility classes that now are used only in NetCache but can be used
32  *   anywhere else.
33  */
34 
35 
36 #include <util/simple_buffer.hpp>
37 
38 
39 #define ATTR_PACKED NCBI_PACKED
40 
41 #if 0 // NCBI_HAS_STD_ATTRIBUTE(aligned) -- speculative
42 # define ATTR_ALIGNED_8 [[aligned(8)]]
43 #elif NCBI_HAS_ATTRIBUTE(gnu::aligned)
44 # define ATTR_ALIGNED_8 [[gnu::aligned(8)]]
45 #elif __has_attribute(aligned)
46 # define ATTR_ALIGNED_8 __attribute__ ((aligned(8)))
47 #else
48 # define ATTR_ALIGNED_8
49 #endif
50 
51 
52 
53 BEGIN_NCBI_SCOPE
54 
55 
56 static const char* const kNCPeerClientName = "nc_peer";
57 
58 
59 typedef map<string, string> TStringMap;
60 typedef map<Uint8, string>  TNCPeerList;
61 typedef vector<Uint8>       TServersList;
62 //typedef CSimpleBufferT<char> TNCBufferType;
63 class TNCBufferType : public CSimpleBufferT<char>
64 {
65 public:
WriteText(const char * buf)66     TNCBufferType& WriteText(const char* buf) {
67         CSimpleBufferT<char>::append(buf, strlen(buf));
68         return *this;
69     }
WriteText(const string & buf)70     TNCBufferType& WriteText(const string& buf) {
71         CSimpleBufferT<char>::append(buf.data(), buf.size());
72         return *this;
73     }
74     template <typename NumType>
WriteNumber(NumType num)75     TNCBufferType& WriteNumber(NumType num) {
76         return WriteText(NStr::NumericToString(num));
77     }
WriteBool(bool b)78     TNCBufferType& WriteBool(bool b) {
79         return WriteText(b ? "true" : "false");
80     }
81 };
82 
83 
84 /// Type of access to NetCache blob
85 enum ENCAccessType {
86     eNCNone = 0,
87     eNCRead,        ///< Read meta information only
88     eNCReadData,    ///< Read blob data
89     eNCCreate,      ///< Create blob or re-write its contents
90     eNCCopyCreate   ///< (Re-)write blob from another NetCache (as opposed to
91                     ///< writing from client)
92 } NCBI_PACKED_ENUM_END();
93 
94 
95 /// Statuses of commands to be set in diagnostics' request context
96 /// Additional statuses can be taken from
97 /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
98 enum EHTTPStatus {
99 // synchronization-related
100     /// SYNC_START: synchronization by blobs list will be performed.
101     eStatus_SyncBList   = 121,
102     /// SYNC_START: synchronization by events will be performed.
103     eStatus_SyncEvents  = 122,
104     /// Same or newer blob is present on the server.
105     eStatus_NewerBlob   = 123,
106     /// Synchronization cannot start because server is busy doing cleaning or
107     /// some other synchronization on this slot.
108     eStatus_SyncBusy    = 124,
109     /// Synchronization is rejected because both servers tried to start it
110     /// simultaneously.
111     eStatus_CrossSync   = 125,
112 
113 // success
114     /// Command is ok and execution is good.
115     eStatus_OK          = 200,
116     /// New resource has been created
117     eStatus_Created     = 201,
118     /// The server is delivering only part of the resource
119     eStatus_PartialContent = 206,
120 
121 // errors
122     /// Command is incorrect.
123     eStatus_BadCmd      = 400,
124     /// Bad password for accessing the blob.
125     eStatus_BadPassword = 401,
126     /// Client was disabled in configuration.
127     eStatus_Disabled    = 403,
128     /// Blob was not found.
129     eStatus_NotFound    = 404,
130     /// Operation not allowed with current settings (e.g. password given but
131     /// ini-file says that only blobs without password are allowed)
132     eStatus_NotAllowed  = 405,
133     /// Command requires admin privileges.
134     eStatus_NeedAdmin   = 407,
135     /// Command timeout is exceeded.
136     eStatus_CmdTimeout  = 408,
137     /// SETVALID cannot be executed as new version was already written.
138     eStatus_RaceCond    = 409,
139     /// Blob version did not match
140     sStatus_BlobVersion = 410,
141     /// Precondition stated in command has failed (size of blob was given but
142     /// data has a different size)
143     eStatus_CondFailed  = 412,
144     /// Blob size exceeds the allowed maximum.
145     eStatus_BlobTooBig  = 413,
146     /// Connection was closed too early (client didn't send all data or didn't
147     /// get confirmation about successful execution).
148     eStatus_PrematureClose = 499,
149     /// Internal server error.
150     eStatus_ServerError = 500,
151     eStatus_CmdAborted  = 500,
152     /// Command is not implemented.
153     eStatus_NoImpl      = 501,
154     /// Peer returned something wrong
155     eStatus_BadPeer     = 502,
156     /// operation canceled because server needs to shutdown.
157     eStatus_ShuttingDown = 503,
158     eStatus_ServiceUnavailable = 503,
159     /// Command cannot be executed because NetCache didn't cache the database
160     /// contents yet.
161     eStatus_JustStarted  = 503,
162     /// Command should be proxied to peers but it's impossible to connect to any
163     eStatus_PeerError   = 504,
164     /// There's not enough disk space to execute the command.
165     eStatus_NoDiskSpace = 507,
166     /// Synchronization is aborted because something went wrong.
167     eStatus_SyncAborted = 520
168 };
169 
170 
171 /// Initializes maps between status codes and error texts sent to client
172 /// to explain these codes.
173 void InitClientMessages(void);
174 EHTTPStatus GetStatusByMessage(const string& msg, EHTTPStatus def);
175 const string& GetMessageByStatus(EHTTPStatus sts);
176 
177 
178 /////////////////////////////////////////////////////////////////////////////
179 // alerts
180 
181 class CNCAlerts
182 {
183 public:
184     enum EAlertType {
185         eUnknown,
186         eStartupConfigChanged,  ///< Configuration file changed
187         ePidFileFailed,         ///< Reporting Pid failed
188         eStartAfterCrash,       ///< InstanceGuard file was present on startup
189         eStorageReinit,         ///< Data storage was reinitialized
190         eAccessDenied,          ///< Command was rejected because client lacks administrative privileges
191         eSyncFailed,            ///< Synchronization failed
192         ePeerIpChanged,         ///< Peer IP address changed
193         eDiskSpaceNormal,       ///< Free disk space is back to normal
194         eDatabaseTooLarge,      ///< Database is too large (warning)
195         eDatabaseOverLimit,     ///< Database size exceeded its limit (error, stop write)
196         eDiskSpaceLow,          ///< Free disk space is below threshold
197         eDiskSpaceCritical,     ///< Free disk space is below critical threshold
198 #ifdef _DEBUG
199 // it is convenient way to keep track of some events
200         eDebugOrphanRecordFound,
201         eDebugOrphanRecordFound2,
202         eDebugWriteBlobInfoFailed,
203         eDebugReadBlobInfoFailed0,
204         eDebugReadBlobInfoFailed1,
205         eDebugReadBlobInfoFailed2,
206         eDebugUpdateUpCoords1,
207         eDebugUpdateUpCoords2,
208         eDebugWriteBlobInfo1,
209         eDebugWriteBlobInfo2,
210         eDebugWriteBlobInfo3,
211         eDebugWriteBlobInfo4,
212         eDebugMoveDataToGarbage,
213         eDebugReadMapInfo1,
214         eDebugReadMapInfo2,
215         eDebugReadChunkData1,
216         eDebugReadChunkData2,
217         eDebugReadChunkData3,
218         eDebugReadChunkData4,
219         eDebugDeleteNextData1,
220         eDebugDeleteNextData2,
221         eDebugDeleteVersionData,
222         eDebugSaveOneMapImpl1,
223         eDebugSaveOneMapImpl2,
224         eDebugWriteChunkData1,
225         eDebugWriteChunkData2,
226         eDebugMoveRecord0,
227         eDebugMoveRecord1,
228         eDebugMoveRecord2,
229         eDebugMoveRecord3,
230         eDebugDeleteFile,
231         eDebugReleaseCacheData1,
232         eDebugReleaseCacheData2,
233         eDebugDeleteSNCBlobVerData,
234         eDebugDeleteCNCBlobVerManager,
235         eDebugExtraWrite,
236         eDebugCacheDeleted1,
237         eDebugCacheDeleted2,
238         eDebugCacheDeleted3,
239         eDebugCacheDeleted4,
240         eDebugCacheFailedMgrAttach,
241         eDebugCacheFailedMgrDetach,
242         eDebugCacheWrongMgr,
243         eDebugCacheWrong,
244         eDebugWrongCacheFound1,
245         eDebugWrongCacheFound2,
246         eDebugSyncAborted1,
247         eDebugSyncAborted2,
248         eDebugConnAdjusted1,
249         eDebugConnAdjusted2,
250         eDebugDbFileNotFound,
251 #endif
252         eLastAlert
253     };
254 
255     enum EAlertAckResult {
256         eNotFound,
257         eAcknowledged
258     };
259 
260     static void Register(EAlertType alert_type, const string&  message);
261     static EAlertAckResult Acknowledge(const string&   alert_id,   const string&  user);
262     static void Report(CSrvSocketTask& task, bool report_all);
263 
264 private:
265     static EAlertType x_IdToType(const string&  alert_id);
266     static string     x_TypeToId(EAlertType  type);
267 };
268 
269 END_NCBI_SCOPE
270 
271 #endif /* NETCACHE_NC_UTILS__HPP */
272