1 /* $Id: nst_automation.cpp 572261 2018-10-10 19:24:55Z sadyrovr $
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: Rafael Sadyrov
27 *
28 * File Description: NetStorage automation implementation.
29 *
30 */
31
32 #include <ncbi_pch.hpp>
33
34 #include "nst_automation.hpp"
35
36 USING_NCBI_SCOPE;
37
38 using namespace NAutomation;
39
40 const string SNetStorageService::kName = "nstsvc";
41 const string SNetStorageServer::kName = "nstsrv";
42 const string SNetStorageObject::kName = "nstobj";
43
NewCommand()44 CCommand SNetStorageService::NewCommand()
45 {
46 return CCommand(kName, ExecNew<TSelf>, {
47 { "service_name", CJsonNode::eString, },
48 { "domain_name", "", },
49 { "client_name", "", },
50 { "metadata", "", },
51 { "ticket", "", },
52 { "hello_service", "", },
53 });
54 }
55
NewCommand()56 CCommand SNetStorageServer::NewCommand()
57 {
58 return CCommand(kName, ExecNew<TSelf>, {
59 { "service_name", CJsonNode::eString, },
60 { "domain_name", "", },
61 { "client_name", "", },
62 { "metadata", "", },
63 { "ticket", "", },
64 { "hello_service", "", },
65 });
66 }
67
s_GetInitString(const TArguments & args)68 string s_GetInitString(const TArguments& args)
69 {
70 _ASSERT(args.size() == 6);
71
72 const auto service_name = args["service_name"].AsString();
73 const auto domain_name = args["domain_name"].AsString();
74 const auto client_name = args["client_name"].AsString();
75 const auto metadata = args["metadata"].AsString();
76 const auto ticket = args["ticket"].AsString();
77 const auto hello_service = args["hello_service"].AsString();
78
79 const string init_string(
80 "nst=" + service_name + "&domain=" + domain_name +
81 "&client=" + client_name + "&metadata=" + metadata +
82 "&ticket=" + ticket + "&hello_service=" + hello_service);
83
84 return init_string;
85 }
86
Create(const TArguments & args,CAutomationProc * automation_proc)87 CAutomationObject* SNetStorageService::Create(const TArguments& args, CAutomationProc* automation_proc)
88 {
89 CNetStorage nst_api(s_GetInitString(args));
90 CNetStorageAdmin nst_api_admin(nst_api);
91 return new SNetStorageService(automation_proc, nst_api_admin);
92 }
93
Create(const TArguments & args,CAutomationProc * automation_proc)94 CAutomationObject* SNetStorageServer::Create(const TArguments& args, CAutomationProc* automation_proc)
95 {
96 CNetStorage nst_api(s_GetInitString(args));
97 CNetStorageAdmin nst_api_admin(nst_api);
98 CNetServer server = nst_api_admin.GetService().Iterate().GetServer();
99 return new SNetStorageServer(automation_proc, nst_api_admin, server);
100 }
101
SNetStorageService(CAutomationProc * automation_proc,CNetStorageAdmin nst_api)102 SNetStorageService::SNetStorageService(
103 CAutomationProc* automation_proc,
104 CNetStorageAdmin nst_api) :
105 SNetServiceBase(automation_proc),
106 m_NetStorageAdmin(nst_api)
107 {
108 auto warning_handler = [&](const string& m, CNetServer s) {
109 auto o = m_AutomationProc->ReturnNetStorageServerObject(m_NetStorageAdmin, s);
110 m_AutomationProc->SendWarning(m, o);
111 return true;
112 };
113
114 GetService().SetWarningHandler(warning_handler);
115 }
116
SNetStorageServer(CAutomationProc * automation_proc,CNetStorageAdmin nst_api,CNetServer::TInstance server)117 SNetStorageServer::SNetStorageServer(
118 CAutomationProc* automation_proc,
119 CNetStorageAdmin nst_api, CNetServer::TInstance server) :
120 SNetStorageService(automation_proc, nst_api.GetServer(server))
121 {
122 if (GetService().IsLoadBalanced()) {
123 NCBI_THROW(CAutomationException, eCommandProcessingError,
124 "NetStorageServer constructor: "
125 "'server_address' must be a host:port combination");
126 }
127 }
128
ReturnNetStorageServerObject(CNetStorageAdmin::TInstance nst_api,CNetServer::TInstance server)129 TAutomationObjectRef CAutomationProc::ReturnNetStorageServerObject(
130 CNetStorageAdmin::TInstance nst_api,
131 CNetServer::TInstance server)
132 {
133 TAutomationObjectRef object(new SNetStorageServer(this, nst_api, server));
134 AddObject(object);
135 return object;
136 }
137
CallCommand()138 CCommand SNetStorageService::CallCommand()
139 {
140 return CCommand(kName, TCommandGroup(CallCommands(), CheckCall<TSelf>));
141 }
142
CallCommands()143 TCommands SNetStorageService::CallCommands()
144 {
145 TCommands cmds =
146 {
147 { "clients_info", ExecMethod<TSelf, &TSelf::ExecClientsInfo>, },
148 { "users_info", ExecMethod<TSelf, &TSelf::ExecUsersInfo>, },
149 { "client_objects", ExecMethod<TSelf, &TSelf::ExecClientObjects>, {
150 { "client_name", CJsonNode::eString, },
151 { "limit", 0, },
152 }},
153 { "user_objects", ExecMethod<TSelf, &TSelf::ExecUserObjects>, {
154 { "user_name", CJsonNode::eString, },
155 { "user_ns", "" },
156 { "limit", 0, },
157 }},
158 { "open_object", ExecMethod<TSelf, &TSelf::ExecOpenObject>, {
159 { "object_loc", CJsonNode::eString, },
160 }},
161 { "server_info", ExecMethod<TSelf, &TSelf::ExecServerInfo>, },
162 { "get_servers", ExecMethod<TSelf, &TSelf::ExecGetServers>, },
163 };
164
165 TCommands base_cmds = SNetServiceBase::CallCommands();
166 cmds.insert(cmds.end(), base_cmds.begin(), base_cmds.end());
167
168 return cmds;
169 }
170
ExecRequest(const string & request_type,SInputOutput & io)171 void SNetStorageService::ExecRequest(const string& request_type, SInputOutput& io)
172 {
173 auto& reply = io.reply;
174 CJsonNode request(m_NetStorageAdmin.MkNetStorageRequest(request_type));
175 CJsonNode response(m_NetStorageAdmin.ExchangeJson(request));
176 NNetStorage::RemoveStdReplyFields(response);
177 reply.Append(response);
178 }
179
ExecClientsInfo(const TArguments &,SInputOutput & io)180 void SNetStorageService::ExecClientsInfo(const TArguments&, SInputOutput& io)
181 {
182 ExecRequest("GETCLIENTSINFO", io);
183 }
184
ExecUsersInfo(const TArguments &,SInputOutput & io)185 void SNetStorageService::ExecUsersInfo(const TArguments&, SInputOutput& io)
186 {
187 ExecRequest("GETUSERSINFO", io);
188 }
189
ExecClientObjects(const TArguments & args,SInputOutput & io)190 void SNetStorageService::ExecClientObjects(const TArguments& args, SInputOutput& io)
191 {
192 _ASSERT(args.size() == 2);
193
194 auto& reply = io.reply;
195 const auto client_name = args["client_name"].AsString();
196 const auto limit = args["limit"].AsInteger();
197 CJsonNode request(m_NetStorageAdmin.MkNetStorageRequest("GETCLIENTOBJECTS"));
198 request.SetString("ClientName", client_name);
199 if (limit) request.SetInteger("Limit", limit);
200
201 CJsonNode response(m_NetStorageAdmin.ExchangeJson(request));
202 NNetStorage::RemoveStdReplyFields(response);
203 reply.Append(response);
204 }
205
ExecUserObjects(const TArguments & args,SInputOutput & io)206 void SNetStorageService::ExecUserObjects(const TArguments& args, SInputOutput& io)
207 {
208 _ASSERT(args.size() == 3);
209
210 auto& reply = io.reply;
211 const auto user_name = args["user_name"].AsString();
212 const auto user_ns = args["user_ns"].AsString();
213 const auto limit = args["limit"].AsInteger();
214 CJsonNode request(m_NetStorageAdmin.MkNetStorageRequest("GETUSEROBJECTS"));
215 request.SetString("UserName", user_name);
216 if (!user_ns.empty()) request.SetString("UserNamespace", user_ns);
217 if (limit) request.SetInteger("Limit", limit);
218
219 CJsonNode response(m_NetStorageAdmin.ExchangeJson(request));
220 NNetStorage::RemoveStdReplyFields(response);
221 reply.Append(response);
222 }
223
ExecServerInfo(const TArguments &,SInputOutput & io)224 void SNetStorageService::ExecServerInfo(const TArguments&, SInputOutput& io)
225 {
226 auto& reply = io.reply;
227 NNetStorage::CExecToJson info_to_json(m_NetStorageAdmin, "INFO");
228 CNetService service(m_NetStorageAdmin.GetService());
229
230 CJsonNode response(g_ExecToJson(info_to_json, service,
231 CNetService::eIncludePenalized));
232 reply.Append(response);
233 }
234
ExecOpenObject(const TArguments & args,SInputOutput & io)235 void SNetStorageService::ExecOpenObject(const TArguments& args, SInputOutput& io)
236 {
237 _ASSERT(args.size() == 1);
238
239 auto& reply = io.reply;
240 const auto object_loc = args["object_loc"].AsString();
241 CNetStorageObject object(m_NetStorageAdmin.Open(object_loc));
242 TAutomationObjectRef automation_object(
243 new SNetStorageObject(m_AutomationProc, object));
244
245 TObjectID response(m_AutomationProc->AddObject(automation_object));
246 reply.AppendInteger(response);
247 }
248
ExecGetServers(const TArguments &,SInputOutput & io)249 void SNetStorageService::ExecGetServers(const TArguments&, SInputOutput& io)
250 {
251 auto& reply = io.reply;
252 CJsonNode object_ids(CJsonNode::NewArrayNode());
253 for (CNetServiceIterator it = m_NetStorageAdmin.GetService().Iterate(
254 CNetService::eIncludePenalized); it; ++it)
255 object_ids.AppendInteger(m_AutomationProc->
256 ReturnNetStorageServerObject(m_NetStorageAdmin, *it)->GetID());
257 reply.Append(object_ids);
258 }
259
CallCommand()260 CCommand SNetStorageServer::CallCommand()
261 {
262 return CCommand(kName, TCommandGroup(CallCommands(), CheckCall<TSelf>));
263 }
264
CallCommands()265 TCommands SNetStorageServer::CallCommands()
266 {
267 TCommands cmds =
268 {
269 { "health", ExecMethod<TSelf, &TSelf::ExecHealth>, },
270 { "conf", ExecMethod<TSelf, &TSelf::ExecConf>, },
271 { "metadata_info", ExecMethod<TSelf, &TSelf::ExecMetadataInfo>, },
272 { "reconf", ExecMethod<TSelf, &TSelf::ExecReconf>, },
273 { "ackalert", ExecMethod<TSelf, &TSelf::ExecAckAlert>, {
274 { "name", CJsonNode::eString, },
275 { "user", CJsonNode::eString, },
276 }},
277 };
278
279 TCommands base_cmds = SNetStorageService::CallCommands();
280 cmds.insert(cmds.end(), base_cmds.begin(), base_cmds.end());
281
282 return cmds;
283 }
284
ExecHealth(const TArguments &,SInputOutput & io)285 void SNetStorageServer::ExecHealth(const TArguments&, SInputOutput& io)
286 {
287 ExecRequest("HEALTH", io);
288 }
289
ExecConf(const TArguments &,SInputOutput & io)290 void SNetStorageServer::ExecConf(const TArguments&, SInputOutput& io)
291 {
292 ExecRequest("CONFIGURATION", io);
293 }
294
ExecMetadataInfo(const TArguments &,SInputOutput & io)295 void SNetStorageServer::ExecMetadataInfo(const TArguments&, SInputOutput& io)
296 {
297 ExecRequest("GETMETADATAINFO", io);
298 }
299
ExecReconf(const TArguments &,SInputOutput & io)300 void SNetStorageServer::ExecReconf(const TArguments&, SInputOutput& io)
301 {
302 ExecRequest("RECONFIGURE", io);
303 }
304
ExecAckAlert(const TArguments & args,SInputOutput & io)305 void SNetStorageServer::ExecAckAlert(const TArguments& args, SInputOutput& io)
306 {
307 _ASSERT(args.size() == 2);
308
309 auto& reply = io.reply;
310 const auto name = args["name"].AsString();
311 const auto user = args["user"].AsString();
312
313 CJsonNode request(m_NetStorageAdmin.MkNetStorageRequest("ACKALERT"));
314 request.SetString("Name", name);
315 request.SetString("User", user);
316
317 CJsonNode response(m_NetStorageAdmin.ExchangeJson(request));
318 NNetStorage::RemoveStdReplyFields(response);
319 reply.Append(response);
320 }
321
SNetStorageObject(CAutomationProc * automation_proc,CNetStorageObject::TInstance object)322 SNetStorageObject::SNetStorageObject(
323 CAutomationProc* automation_proc, CNetStorageObject::TInstance object) :
324 CAutomationObject(automation_proc),
325 m_Object(object)
326 {
327 }
328
CallCommand()329 CCommand SNetStorageObject::CallCommand()
330 {
331 return CCommand(kName, TCommandGroup(CallCommands(), CheckCall<TSelf>));
332 }
333
CallCommands()334 TCommands SNetStorageObject::CallCommands()
335 {
336 TCommands cmds =
337 {
338 { "info", ExecMethod<TSelf, &TSelf::ExecInfo>, },
339 { "attr_list", ExecMethod<TSelf, &TSelf::ExecAttrList>, },
340 { "get_attr", ExecMethod<TSelf, &TSelf::ExecGetAttr>, {
341 { "attr_name", CJsonNode::eString, },
342 }},
343 };
344
345 return cmds;
346 }
347
ExecInfo(const TArguments &,SInputOutput & io)348 void SNetStorageObject::ExecInfo(const TArguments&, SInputOutput& io)
349 {
350 auto& reply = io.reply;
351 CNetStorageObjectInfo object_info(m_Object.GetInfo());
352 CJsonNode response(object_info.ToJSON());
353 reply.Append(response);
354 }
355
ExecAttrList(const TArguments &,SInputOutput & io)356 void SNetStorageObject::ExecAttrList(const TArguments&, SInputOutput& io)
357 {
358 auto& reply = io.reply;
359 CNetStorageObject::TAttributeList attr_list(m_Object.GetAttributeList());
360 CJsonNode response(CJsonNode::eArray);
361 for (auto& attr : attr_list) response.AppendString(attr);
362 reply.Append(response);
363 }
364
ExecGetAttr(const TArguments & args,SInputOutput & io)365 void SNetStorageObject::ExecGetAttr(const TArguments& args, SInputOutput& io)
366 {
367 _ASSERT(args.size() == 1);
368
369 auto& reply = io.reply;
370 const auto attr_name = args["attr_name"].AsString();
371 CJsonNode response(m_Object.GetAttribute(attr_name));
372 reply.Append(response);
373 }
374