1 /* $Id: wn_automation.cpp 554817 2018-01-09 17:38:11Z 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: Dmitry Kazimirov
27 *
28 * File Description: Worker node automation implementation.
29 *
30 */
31
32 #include <ncbi_pch.hpp>
33
34 #include "wn_automation.hpp"
35
36 USING_NCBI_SCOPE;
37
38 using namespace NAutomation;
39
40 const string SWorkerNode::kName = "wn";
41
SWorkerNode(CAutomationProc * automation_proc,CNetScheduleAPI ns_api)42 SWorkerNode::SWorkerNode(
43 CAutomationProc* automation_proc, CNetScheduleAPI ns_api) :
44 SNetService(automation_proc),
45 m_NetScheduleAPI(ns_api)
46 {
47 m_WorkerNode = GetServer();
48
49 if (GetService().IsLoadBalanced()) {
50 NCBI_THROW(CAutomationException, eCommandProcessingError,
51 "WorkerNode constructor: 'wn_address' "
52 "must be a host:port combination");
53 }
54 }
55
NewCommand()56 CCommand SWorkerNode::NewCommand()
57 {
58 return CCommand(kName, ExecNew<TSelf>, {
59 { "wn_address", CJsonNode::eString, },
60 { "client_name", "", },
61 });
62 }
63
Create(const TArguments & args,CAutomationProc * automation_proc)64 CAutomationObject* SWorkerNode::Create(const TArguments& args, CAutomationProc* automation_proc)
65 {
66 _ASSERT(args.size() == 2);
67
68 const auto wn_address = args["wn_address"].AsString();
69 const auto client_name = args["client_name"].AsString();
70
71 CNetScheduleAPIExt ns_api(CNetScheduleAPIExt::CreateWnCompat(
72 wn_address, client_name));
73
74 return new SWorkerNode(automation_proc, ns_api);
75 }
76
CallCommand()77 CCommand SWorkerNode::CallCommand()
78 {
79 return CCommand(kName, TCommandGroup(CallCommands(), CheckCall<TSelf>));
80 }
81
CallCommands()82 TCommands SWorkerNode::CallCommands()
83 {
84 TCommands cmds =
85 {
86 { "version", ExecMethod<TSelf, &TSelf::ExecVersion>, },
87 { "wn_info", ExecMethod<TSelf, &TSelf::ExecWnInfo>, },
88 { "suspend", ExecMethod<TSelf, &TSelf::ExecSuspend>, {
89 { "pullback_mode", false, },
90 { "timeout", 0, },
91 }},
92 { "resume", ExecMethod<TSelf, &TSelf::ExecResume>, },
93 { "shutdown", ExecMethod<TSelf, &TSelf::ExecShutdown>, {
94 { "level", 0 },
95 }},
96 };
97
98 TCommands base_cmds = SNetService::CallCommands();
99 cmds.insert(cmds.end(), base_cmds.begin(), base_cmds.end());
100
101 return cmds;
102 }
103
ExecVersion(const TArguments &,SInputOutput & io)104 void SWorkerNode::ExecVersion(const TArguments&, SInputOutput& io)
105 {
106 auto& reply = io.reply;
107 reply.Append(g_ServerInfoToJson(GetService(), false));
108 }
109
ExecWnInfo(const TArguments &,SInputOutput & io)110 void SWorkerNode::ExecWnInfo(const TArguments&, SInputOutput& io)
111 {
112 auto& reply = io.reply;
113 reply.Append(g_WorkerNodeInfoToJson(m_WorkerNode));
114 }
115
ExecSuspend(const TArguments & args,SInputOutput &)116 void SWorkerNode::ExecSuspend(const TArguments& args, SInputOutput&)
117 {
118 _ASSERT(args.size() == 2);
119
120 const auto pullback_mode = args["pullback_mode"].AsBoolean();
121 const auto timeout = args["timeout"].AsInteger<unsigned int>();
122 g_SuspendWorkerNode(m_WorkerNode, pullback_mode, timeout);
123 }
124
ExecResume(const TArguments &,SInputOutput &)125 void SWorkerNode::ExecResume(const TArguments&, SInputOutput&)
126 {
127 g_ResumeWorkerNode(m_WorkerNode);
128 }
129
s_GetWorkerNodeShutdownMode(Int8 level)130 CNetScheduleAdmin::EShutdownLevel s_GetWorkerNodeShutdownMode(Int8 level)
131 {
132 enum EWorkerNodeShutdownMode { eNormalShutdown, eShutdownNow, eKillNode };
133
134 switch (level) {
135 case eShutdownNow: return CNetScheduleAdmin::eShutdownImmediate;
136 case eKillNode: return CNetScheduleAdmin::eDie;
137 default: return CNetScheduleAdmin::eNormalShutdown;
138 }
139 }
140
ExecShutdown(const TArguments & args,SInputOutput &)141 void SWorkerNode::ExecShutdown(const TArguments& args, SInputOutput&)
142 {
143 _ASSERT(args.size() == 1);
144
145 const auto level = args["level"].AsInteger();
146 m_NetScheduleAPI.GetAdmin().ShutdownServer(s_GetWorkerNodeShutdownMode(level));
147 }
148