APIService.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <Parser.hpp>
  14. #include <NdbOut.hpp>
  15. #include <Properties.hpp>
  16. #include <socket_io.h>
  17. #include "APIService.hpp"
  18. #include "CPCD.hpp"
  19. #include <NdbMutex.h>
  20. #include <OutputStream.hpp>
  21. /**
  22.    const char * name;
  23.    const char * realName;
  24.    const Type type;
  25.    const ArgType argType;
  26.    const ArgRequired argRequired;
  27.    const ArgMinMax argMinMax;
  28.    const int minVal;
  29.    const int maxVal;
  30.    void (T::* function)(const class Properties & args);
  31.    const char * description;
  32. */
  33. #define CPCD_CMD(name, fun, desc) 
  34.  { name, 
  35.    0, 
  36.    ParserRow<CPCDAPISession>::Cmd, 
  37.    ParserRow<CPCDAPISession>::String, 
  38.    ParserRow<CPCDAPISession>::Optional, 
  39.    ParserRow<CPCDAPISession>::IgnoreMinMax, 
  40.    0, 0, 
  41.    fun, 
  42.    desc, 0 }
  43. #define CPCD_ARG(name, type, opt, desc) 
  44.  { name, 
  45.    0, 
  46.    ParserRow<CPCDAPISession>::Arg, 
  47.    ParserRow<CPCDAPISession>::type, 
  48.    ParserRow<CPCDAPISession>::opt, 
  49.    ParserRow<CPCDAPISession>::IgnoreMinMax, 
  50.    0, 0, 
  51.    0, 
  52.    desc, 0 }
  53. #define CPCD_ARG2(name, type, opt, min, max, desc) 
  54.  { name, 
  55.    0, 
  56.    ParserRow<CPCDAPISession>::Arg, 
  57.    ParserRow<CPCDAPISession>::type, 
  58.    ParserRow<CPCDAPISession>::opt, 
  59.    ParserRow<CPCDAPISession>::IgnoreMinMax, 
  60.    min, max, 
  61.    0, 
  62.    desc, 0 }
  63. #define CPCD_END() 
  64.  { 0, 
  65.    0, 
  66.    ParserRow<CPCDAPISession>::Arg, 
  67.    ParserRow<CPCDAPISession>::Int, 
  68.    ParserRow<CPCDAPISession>::Optional, 
  69.    ParserRow<CPCDAPISession>::IgnoreMinMax, 
  70.    0, 0, 
  71.    0, 
  72.    0, 0 }
  73. #define CPCD_CMD_ALIAS(name, realName, fun) 
  74.  { name, 
  75.    realName, 
  76.    ParserRow<CPCDAPISession>::CmdAlias, 
  77.    ParserRow<CPCDAPISession>::Int, 
  78.    ParserRow<CPCDAPISession>::Optional, 
  79.    ParserRow<CPCDAPISession>::IgnoreMinMax, 
  80.    0, 0, 
  81.    0, 
  82.    0, 0 }
  83. #define CPCD_ARG_ALIAS(name, realName, fun) 
  84.  { name, 
  85.    realName, 
  86.    ParserRow<CPCDAPISession>::ArgAlias, 
  87.    ParserRow<CPCDAPISession>::Int, 
  88.    ParserRow<CPCDAPISession>::Optional, 
  89.    ParserRow<CPCDAPISession>::IgnoreMinMax, 
  90.    0, 0, 
  91.    0, 
  92.    0, 0 }
  93. const
  94. ParserRow<CPCDAPISession> commands[] = 
  95. {
  96.   CPCD_CMD("define process" , &CPCDAPISession::defineProcess, ""),
  97.     CPCD_ARG("id",     Int,    Optional,  "Id of process."),
  98.     CPCD_ARG("name",   String, Mandatory, "Name of process"),
  99.     CPCD_ARG("group",  String, Mandatory, "Group of process"),
  100.     CPCD_ARG("env",    String, Optional,  "Environment variables for process"),
  101.     CPCD_ARG("path",   String, Mandatory, "Path to binary"),
  102.     CPCD_ARG("args",   String, Optional,  "Arguments to process"),
  103.     CPCD_ARG("type",   String, Mandatory, "Type of process"),
  104.     CPCD_ARG("cwd",    String, Mandatory, "Working directory of process"),
  105.     CPCD_ARG("owner",  String, Mandatory, "Owner of process"),
  106.     CPCD_ARG("runas",  String, Optional,  "Run as user"),
  107.     CPCD_ARG("stdout", String, Optional,  "Redirection of stdout"),
  108.     CPCD_ARG("stderr", String, Optional,  "Redirection of stderr"),
  109.     CPCD_ARG("stdin",  String, Optional,  "Redirection of stderr"),
  110.     CPCD_ARG("ulimit", String, Optional,  "ulimit"),
  111.     CPCD_ARG("shutdown", String, Optional,  "shutdown options"),  
  112.   CPCD_CMD("undefine process", &CPCDAPISession::undefineProcess, ""),
  113.     CPCD_CMD_ALIAS("undef", "undefine process", 0),
  114.     CPCD_ARG("id", Int, Mandatory, "Id of process"),
  115.     CPCD_ARG_ALIAS("i", "id", 0),
  116.     
  117.   CPCD_CMD("start process", &CPCDAPISession::startProcess, ""),
  118.     CPCD_ARG("id", Int, Mandatory, "Id of process"),
  119.   CPCD_CMD("stop process", &CPCDAPISession::stopProcess, ""),
  120.     CPCD_ARG("id", Int, Mandatory, "Id of process"),
  121.   
  122.   CPCD_CMD("list processes", &CPCDAPISession::listProcesses, ""),
  123.   
  124.   CPCD_END()
  125. };
  126. CPCDAPISession::CPCDAPISession(NDB_SOCKET_TYPE sock,
  127.        CPCD & cpcd)
  128.   : SocketServer::Session(sock)
  129.   , m_cpcd(cpcd)
  130. {
  131.   m_input = new SocketInputStream(sock);
  132.   m_output = new SocketOutputStream(sock);
  133.   m_parser = new Parser<CPCDAPISession>(commands, *m_input, true, true, true);
  134. }
  135. CPCDAPISession::CPCDAPISession(FILE * f, CPCD & cpcd)
  136.   : SocketServer::Session(1)
  137.   , m_cpcd(cpcd)
  138. {
  139.   m_input = new FileInputStream(f);
  140.   m_parser = new Parser<CPCDAPISession>(commands, *m_input, true, true, true);
  141. }
  142.   
  143. CPCDAPISession::~CPCDAPISession() {
  144.   delete m_input;
  145.   delete m_parser;
  146. }
  147. void
  148. CPCDAPISession::runSession(){
  149.   Parser_t::Context ctx;
  150.   while(!m_stop){
  151.     m_parser->run(ctx, * this); 
  152.     if(ctx.m_currentToken == 0)
  153.       break;
  154.     switch(ctx.m_status){
  155.     case Parser_t::Ok:
  156.       for(size_t i = 0; i<ctx.m_aliasUsed.size(); i++)
  157. ndbout_c("Used alias: %s -> %s", 
  158.  ctx.m_aliasUsed[i]->name, ctx.m_aliasUsed[i]->realName);
  159.       break;
  160.     case Parser_t::NoLine:
  161.     case Parser_t::EmptyLine:
  162.       break;
  163.     default:
  164.       break;
  165.     }
  166.   }
  167.   NDB_CLOSE_SOCKET(m_socket);
  168. }
  169. void
  170. CPCDAPISession::stopSession(){
  171.   CPCD::RequestStatus rs;
  172.   for(size_t i = 0; i<m_temporaryProcesses.size(); i++){
  173.     Uint32 id = m_temporaryProcesses[i];
  174.     m_cpcd.undefineProcess(&rs, id);
  175.   }
  176. }
  177. void
  178. CPCDAPISession::loadFile(){
  179.   Parser_t::Context ctx;
  180.   while(!m_stop){
  181.     m_parser->run(ctx, * this); 
  182.     if(ctx.m_currentToken == 0)
  183.       break;
  184.     switch(ctx.m_status){
  185.     case Parser_t::Ok:
  186.       for(size_t i = 0; i<ctx.m_aliasUsed.size(); i++)
  187. ndbout_c("Used alias: %s -> %s", 
  188.  ctx.m_aliasUsed[i]->name, ctx.m_aliasUsed[i]->realName);
  189.       break;
  190.     case Parser_t::NoLine:
  191.     case Parser_t::EmptyLine:
  192.       break;
  193.     default:
  194.       break;
  195.     }
  196.   }
  197. }
  198. static const int g_TimeOut = 1000;
  199. void
  200. CPCDAPISession::defineProcess(Parser_t::Context & /* unused */, 
  201.       const class Properties & args){
  202.   CPCD::Process * p = new CPCD::Process(args, &m_cpcd);
  203.   
  204.   CPCD::RequestStatus rs;
  205.   bool ret = m_cpcd.defineProcess(&rs, p);
  206.   if(!m_cpcd.loadingProcessList) {
  207.     m_output->println("define process");
  208.     m_output->println("status: %d", rs.getStatus());
  209.     if(ret == true){
  210.       m_output->println("id: %d", p->m_id);
  211.       if(p->m_processType == TEMPORARY){
  212. m_temporaryProcesses.push_back(p->m_id);
  213.       }
  214.     } else {
  215.       m_output->println("errormessage: %s", rs.getErrMsg());
  216.     }
  217.     m_output->println("");
  218.   }
  219. }
  220. void
  221. CPCDAPISession::undefineProcess(Parser_t::Context & /* unused */, 
  222. const class Properties & args){
  223.   Uint32 id;
  224.   CPCD::RequestStatus rs;
  225.   args.get("id", &id);
  226.   bool ret = m_cpcd.undefineProcess(&rs, id);
  227.   m_output->println("undefine process");
  228.   m_output->println("id: %d", id);
  229.   m_output->println("status: %d", rs.getStatus());
  230.   if(!ret)
  231.     m_output->println("errormessage: %s", rs.getErrMsg());
  232.   m_output->println("");
  233. }
  234. void
  235. CPCDAPISession::startProcess(Parser_t::Context & /* unused */, 
  236.      const class Properties & args){
  237.   Uint32 id;
  238.   CPCD::RequestStatus rs;
  239.   args.get("id", &id);
  240.   const int ret = m_cpcd.startProcess(&rs, id);
  241.   if(!m_cpcd.loadingProcessList) {
  242.     m_output->println("start process");
  243.     m_output->println("id: %d", id);
  244.     m_output->println("status: %d", rs.getStatus());
  245.     if(!ret)
  246.       m_output->println("errormessage: %s", rs.getErrMsg());
  247.     m_output->println("");
  248.   }
  249. }
  250. void
  251. CPCDAPISession::stopProcess(Parser_t::Context & /* unused */, 
  252.     const class Properties & args){
  253.   Uint32 id;
  254.   CPCD::RequestStatus rs;
  255.   args.get("id", &id);
  256.   int ret = m_cpcd.stopProcess(&rs, id);
  257.   m_output->println("stop process");
  258.   m_output->println("id: %d", id);
  259.   m_output->println("status: %d", rs.getStatus());
  260.   if(!ret)
  261.     m_output->println("errormessage: %s", rs.getErrMsg());
  262.   
  263.   m_output->println("");
  264. }
  265. static const char *
  266. propToString(Properties *prop, const char *key) {
  267.   static char buf[32];
  268.   const char *retval = NULL;
  269.   PropertiesType pt;
  270.   prop->getTypeOf(key, &pt);
  271.   switch(pt) {
  272.   case PropertiesType_Uint32:
  273.     Uint32 val;
  274.     prop->get(key, &val);
  275.     BaseString::snprintf(buf, sizeof buf, "%d", val);
  276.     retval = buf;
  277.     break;
  278.   case PropertiesType_char:
  279.     const char *str;
  280.     prop->get(key, &str);
  281.     retval = str;
  282.     break;
  283.   default:
  284.     BaseString::snprintf(buf, sizeof buf, "(unknown)");
  285.     retval = buf;
  286.   }
  287.   return retval;
  288. }
  289. void
  290. CPCDAPISession::printProperty(Properties *prop, const char *key) {
  291.   m_output->println("%s: %s", key, propToString(prop, key));
  292. }
  293. void
  294. CPCDAPISession::listProcesses(Parser_t::Context & /* unused */, 
  295.       const class Properties & /* unused */){
  296.   m_cpcd.m_processes.lock();
  297.   MutexVector<CPCD::Process *> *proclist = m_cpcd.getProcessList();
  298.   m_output->println("start processes");
  299.   m_output->println("");
  300.   
  301.   for(size_t i = 0; i < proclist->size(); i++) {
  302.     CPCD::Process *p = (*proclist)[i];
  303.     m_output->println("process");
  304.   
  305.     m_output->println("id: %d", p->m_id);
  306.     m_output->println("name: %s", p->m_name.c_str());
  307.     m_output->println("path: %s", p->m_path.c_str());
  308.     m_output->println("args: %s", p->m_args.c_str());
  309.     m_output->println("type: %s", p->m_type.c_str());
  310.     m_output->println("cwd: %s", p->m_cwd.c_str());
  311.     m_output->println("env: %s", p->m_env.c_str());
  312.     m_output->println("owner: %s", p->m_owner.c_str());
  313.     m_output->println("group: %s", p->m_group.c_str());
  314.     m_output->println("runas: %s", p->m_runas.c_str());
  315.     m_output->println("stdin: %s", p->m_stdin.c_str());
  316.     m_output->println("stdout: %s", p->m_stdout.c_str());
  317.     m_output->println("stderr: %s", p->m_stderr.c_str());    
  318.     m_output->println("ulimit: %s", p->m_ulimit.c_str());    
  319.     switch(p->m_status){
  320.     case STOPPED:
  321.       m_output->println("status: stopped");
  322.       break;
  323.     case STARTING:
  324.       m_output->println("status: starting");
  325.       break;
  326.     case RUNNING:
  327.       m_output->println("status: running");
  328.       break;
  329.     case STOPPING:
  330.       m_output->println("status: stopping");
  331.       break;
  332.     }
  333.     
  334.     m_output->println("");
  335.     
  336.   }
  337.   m_output->println("end processes");
  338.   m_output->println("");
  339.   m_cpcd.m_processes.unlock();
  340. }
  341. template class Vector<ParserRow<CPCDAPISession> const*>;