1 #ifndef CONNECT_SERVICES__REMOTE_APP_MB_HPP
2 #define CONNECT_SERVICES__REMOTE_APP_MB_HPP
3 
4 /*  $Id: remote_app.hpp 584886 2019-04-18 16:59:46Z sadyrovr $
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:  Maxim Didneko, Dmitry Kazimirov
30  *
31  * File Description:
32  *
33  */
34 
35 #include <connect/services/netcache_api.hpp>
36 #include <connect/services/grid_rw_impl.hpp>
37 
38 #include <connect/connect_export.h>
39 
40 #include <corelib/ncbimisc.hpp>
41 #include <corelib/ncbiobj.hpp>
42 #include <corelib/ncbistre.hpp>
43 
44 #include <vector>
45 
46 BEGIN_NCBI_SCOPE
47 
48 const size_t kMaxBlobInlineSize = 500;
49 
50 enum EStdOutErrStorageType {
51     eLocalFile = 0,
52     eBlobStorage
53 };
54 
55 class NCBI_XCONNECT_EXPORT CBlobStreamHelper
56 {
57 public:
CBlobStreamHelper(CNetCacheAPI::TInstance storage,string & data,size_t & data_size)58     CBlobStreamHelper(CNetCacheAPI::TInstance storage,
59             string& data, size_t& data_size) :
60         m_Storage(storage), m_Data(&data), m_DataSize(&data_size)
61     {
62     }
63 
64     ~CBlobStreamHelper();
65 
66     CNcbiOstream& GetOStream(const string& fname = "",
67         EStdOutErrStorageType type = eBlobStorage,
68         size_t max_inline_size = kMaxBlobInlineSize);
69 
70     CNcbiIstream& GetIStream(string* fname = NULL,
71         EStdOutErrStorageType* type = NULL);
72     void Reset();
73 
74 protected:
75     static int x_GetTypeAndName(CNcbiIstream& istream, string& name);
76 
77 private:
78     CNetCacheAPI m_Storage;
79     SGridRead m_GridRead;
80     SGridWrite m_GridWrite;
81     string* m_Data;
82     size_t* m_DataSize;
83 };
84 
85 
86 /// Remote Application Request (both client side and application executor side)
87 ///
88 /// It is used by a client application which wants to run a remote application
89 /// through NetSchedule infrastructure and should be used in conjunction with
90 /// CGridJobSubmitter class
91 ///
92 /// It is also used by a grid worker node to get parameters
93 /// for the remote application.
94 ///
95 class NCBI_XCONNECT_EXPORT CRemoteAppRequest
96 {
97 public:
98     explicit CRemoteAppRequest(CNetCacheAPI::TInstance storage,
99             size_t max_inline_size = kMaxBlobInlineSize);
100 
101     ~CRemoteAppRequest();
102 
103     /// Set the command line for the remote application.
104     /// The command line must not contain the remote program
105     /// name -- only its arguments.
SetCmdLine(const string & cmdline)106     void SetCmdLine(const string& cmdline) { m_CmdLine = cmdline; }
107     /// Get the command line of the remote application.
GetCmdLine() const108     const string& GetCmdLine() const { return m_CmdLine; }
109 
SetAppRunTimeout(unsigned int sec)110     void SetAppRunTimeout(unsigned int sec) { m_AppRunTimeout = sec; }
GetAppRunTimeout() const111     unsigned int GetAppRunTimeout() const { return m_AppRunTimeout; }
112 
113     /// Transfer a file to an application executor side.
114     /// It only makes sense to transfer a file if its name also mentioned in
115     /// the command line for the remote application. When the file is transfered
116     /// the the executor side it gets stored to a temporary directory and then its
117     /// original name in the command line will be replaced with the new temporary name.
AddFileForTransfer(const string & fname,EStdOutErrStorageType tt=eBlobStorage)118     void AddFileForTransfer(const string& fname,
119         EStdOutErrStorageType tt = eBlobStorage)
120     {
121         m_Files[fname] = tt;
122     }
GetWorkingDir() const123     const string& GetWorkingDir() const { return m_TmpDirName; }
124 
125     /// Get an output stream to write data to a remote application stdin
GetStdIn()126     CNcbiOstream& GetStdIn()
127     {
128         return m_StdIn.GetOStream("", eBlobStorage, m_MaxInlineSize);
129     }
130     /// Get the stdin stream of the remote application.
GetStdInForRead()131     CNcbiIstream& GetStdInForRead()
132     {
133         return m_StdIn.GetIStream();
134     }
135 
SetExclusiveMode(bool on_off)136     void SetExclusiveMode(bool on_off) { m_ExlusiveMode = on_off; }
IsExclusiveMode() const137     bool IsExclusiveMode() const { return m_ExlusiveMode; }
138 
139 
SetStdOutErrFileNames(const string & stdout_fname,const string & stderr_fname,EStdOutErrStorageType type)140     void SetStdOutErrFileNames(const string& stdout_fname,
141         const string& stderr_fname,
142         EStdOutErrStorageType type)
143     {
144         m_StdOutFileName = stdout_fname;
145         m_StdErrFileName = stderr_fname;
146         m_StorageType = type;
147     }
148 
GetStdOutFileName() const149     const string& GetStdOutFileName() const { return m_StdOutFileName; }
GetStdErrFileName() const150     const string& GetStdErrFileName() const { return m_StdErrFileName; }
GetStdOutErrStorageType() const151     EStdOutErrStorageType GetStdOutErrStorageType() const
152         { return m_StorageType; }
153 
GetInBlobIdOrData() const154     const string& GetInBlobIdOrData() const { return m_InBlobIdOrData; }
155 
SetMaxInlineSize(size_t max_inline_size)156     void SetMaxInlineSize(size_t max_inline_size) { m_MaxInlineSize = max_inline_size; }
157 
158     /// Serialize a request to a given stream. After call to this method the instance
159     /// cleans itself an it can be reused.
160     void Send(CNcbiOstream& os);
Deserialize(CNcbiIstream & is)161     void Deserialize(CNcbiIstream& is) { x_Deserialize(is); }
162 
163     void Reset();
164 
165 protected:
166     typedef map<string, EStdOutErrStorageType> TFiles;
167 
GetNetCacheAPI()168     CNetCacheAPI& GetNetCacheAPI() { return m_NetCacheAPI; }
GetFileNames() const169     const TFiles& GetFileNames() const { return m_Files; }
170 
171     void x_CreateWDir();
172     void x_RemoveWDir();
173 
174     typedef map<string, string> TStoredFiles;
175     bool x_Deserialize(CNcbiIstream& is, TStoredFiles* files = NULL);
176 
177 private:
178     static CAtomicCounter sm_DirCounter;
179 
180     CNetCacheAPI m_NetCacheAPI;
181     string m_CmdLine;
182     unsigned int m_AppRunTimeout;
183 
184     string m_TmpDirPath;
185     string m_TmpDirName;
186     TFiles m_Files;
187 
188     CBlobStreamHelper m_StdIn;
189     size_t m_StdInDataSize;
190 
191     string m_InBlobIdOrData;
192 
193     string m_StdErrFileName;
194     string m_StdOutFileName;
195     EStdOutErrStorageType m_StorageType;
196     bool m_ExlusiveMode;
197     size_t m_MaxInlineSize;
198 };
199 
200 /// Remote Application Result (both client side and application executor side)
201 ///
202 /// It is used by a grid worker node to send results of a
203 /// finished remote application to the client.
204 ///
205 /// It is also used by the client application to get the job results
206 /// and should be used in conjunction with CGridJobStatus
207 ///
208 class NCBI_XCONNECT_EXPORT CRemoteAppResult
209 {
210 public:
CRemoteAppResult(CNetCacheAPI::TInstance netcache_api,size_t max_inline_size=kMaxBlobInlineSize)211     CRemoteAppResult(CNetCacheAPI::TInstance netcache_api,
212             size_t max_inline_size = kMaxBlobInlineSize) :
213         m_NetCacheAPI(netcache_api),
214         m_RetCode(-1),
215         m_StdOut(netcache_api, m_OutBlobIdOrData, m_OutBlobSize),
216         m_OutBlobSize(0),
217         m_StdErr(netcache_api, m_ErrBlobIdOrData, m_ErrBlobSize),
218         m_ErrBlobSize(0),
219         m_StorageType(eBlobStorage),
220         m_MaxInlineSize(max_inline_size)
221     {
222     }
223     ~CRemoteAppResult();
224 
225     /// Get a stream to put remote application's stdout to
GetStdOutForWrite()226     CNcbiOstream& GetStdOutForWrite()
227     {
228         return m_StdOut.GetOStream(m_StdOutFileName,
229             m_StorageType, m_MaxInlineSize);
230     }
231     /// Get a remote application stdout
GetStdOut()232     CNcbiIstream& GetStdOut()
233     {
234         return m_StdOut.GetIStream(&m_StdOutFileName, &m_StorageType);
235     }
236 
GetStdErrForWrite()237     CNcbiOstream& GetStdErrForWrite()
238     {
239         return m_StdErr.GetOStream(m_StdErrFileName,
240             m_StorageType, m_MaxInlineSize);
241     }
242     /// Get a remote application stderr
GetStdErr()243     CNcbiIstream& GetStdErr()
244     {
245         return m_StdErr.GetIStream(&m_StdErrFileName, &m_StorageType);
246     }
247 
SetRetCode(int ret_code)248     void SetRetCode(int ret_code) { m_RetCode = ret_code; }
GetRetCode() const249     int GetRetCode() const { return m_RetCode; }
250 
251     void Serialize(CNcbiOstream& os);
252     /// Deserialize a request from a given stream.
253     void Receive(CNcbiIstream& is);
254 
255     void Reset();
256 
SetStdOutErrFileNames(const string & stdout_fname,const string & stderr_fname,EStdOutErrStorageType type)257     void SetStdOutErrFileNames(const string& stdout_fname,
258                                const string& stderr_fname,
259                                EStdOutErrStorageType type)
260     {
261         m_StdOutFileName = stdout_fname;
262         m_StdErrFileName = stderr_fname;
263         m_StorageType = type;
264     }
GetStdOutFileName() const265     const string& GetStdOutFileName() const { return m_StdOutFileName; }
GetStdErrFileName() const266     const string& GetStdErrFileName() const { return m_StdErrFileName; }
GetStdOutErrStorageType() const267     EStdOutErrStorageType GetStdOutErrStorageType() const
268         { return m_StorageType; }
GetOutBlobIdOrData() const269     const string& GetOutBlobIdOrData() const { return m_OutBlobIdOrData; }
GetErrBlobIdOrData() const270     const string& GetErrBlobIdOrData() const { return m_ErrBlobIdOrData; }
271 
SetMaxInlineSize(size_t max_inline_size)272     void SetMaxInlineSize(size_t max_inline_size)
273         { m_MaxInlineSize = max_inline_size; }
274 
275 private:
276     CNetCacheAPI m_NetCacheAPI;
277     int m_RetCode;
278 
279     CBlobStreamHelper m_StdOut;
280     string m_OutBlobIdOrData;
281     size_t m_OutBlobSize;
282     string m_StdOutFileName;
283 
284     CBlobStreamHelper m_StdErr;
285     string m_ErrBlobIdOrData;
286     size_t m_ErrBlobSize;
287     string m_StdErrFileName;
288     EStdOutErrStorageType m_StorageType;
289     size_t m_MaxInlineSize;
290 };
291 
292 
293 NCBI_XCONNECT_EXPORT
294 void TokenizeCmdLine(const string& cmdline, vector<string>& args);
295 
296 NCBI_XCONNECT_EXPORT
297 string JoinCmdLine(const vector<string>& args);
298 
299 
300 END_NCBI_SCOPE
301 
302 #endif // CONNECT_SERVICES__REMOTE_APP_MB_HPP
303