37#include <sys/socket.h>
47#include "BESServerHandler.h"
48#include "Connection.h"
50#include "BESXMLInterface.h"
51#include "TheBESKeys.h"
52#include "BESInternalError.h"
53#include "ServerExitConditions.h"
55#include "PPTStreamBuf.h"
56#include "PPTProtocolNames.h"
59#include "BESStopWatch.h"
63#define MODULE "server"
64#define prolog std::string("BESServerHandler::").append(__func__).append("() - ")
68#define EXIT_ON_INTERNAL_ERROR "BES.ExitOnInternalError"
70BESServerHandler::BESServerHandler()
77 cerr <<
"Unable to determine method to handle clients, "
78 <<
"single or multiple as defined by BES.ProcessManagerMethod" <<
": " << e.
get_message() << endl;
79 exit(SERVER_EXIT_FATAL_CANNOT_START);
82 if (_method !=
"multiple" && _method !=
"single") {
83 cerr <<
"Unable to determine method to handle clients, "
84 <<
"single or multiple as defined by BES.ProcessManagerMethod" << endl;
85 exit(SERVER_EXIT_FATAL_CANNOT_START);
98 if (_method ==
"single") {
110 if ((pid = fork()) < 0) {
111 string error(
"fork error");
112 const char* error_info = strerror(errno);
113 if (error_info) error +=
" " + (string) error_info;
114 throw BESInternalError(error, __FILE__, __LINE__);
122void BESServerHandler::execute(
Connection *connection)
129 strm <<
"ip " << connection->getSocket()->getIp() <<
", port " << connection->getSocket()->getPort();
130 string from = strm.str();
132 map<string, string> extensions;
134 int socket_d = connection->getSocket()->getSocketDescriptor();
135 unsigned int bufsize = connection->getSendChunkSize();
136 PPTStreamBuf fds(socket_d, bufsize);
137 ostream my_ostrm(&fds);
141 msg << prolog <<
"Using ostream: " << (
void *) &my_ostrm <<
" cout: " << (
void *) &cout << endl;
142 BESDEBUG(MODULE, msg.str());
154 BESDEBUG(MODULE,prolog <<
"Waiting for client to send commands." << endl);
156 done = connection->receive(extensions, &ss);
158 BESDEBUG(MODULE,prolog <<
"Received client command. status: '" << extensions[
"status"] <<
"'" << endl);
162 if (extensions[
"status"] == connection->exit()) {
171 BESDEBUG(MODULE,prolog <<
"Received PPT_EXIT_NOW in an extension chunk." << endl);
177 connection->closeConnection();
179 BESDEBUG(MODULE,prolog <<
"Calling exit(CHILD_SUBPROCESS_READY) which has a value of " << CHILD_SUBPROCESS_READY << endl);
181 INFO_LOG(
"Received exit command.");
183 exit(CHILD_SUBPROCESS_READY);
186 string cmd_str = ss.str();
188 BESDEBUG(MODULE, prolog <<
"Processing client command:" << endl << cmd_str << endl);
190 BES_STOPWATCH_START(MODULE, prolog +
"Timer");
194 BESXMLInterface cmd(cmd_str, &my_ostrm);
196 int status = cmd.execute_request(from);
200 BESDEBUG(MODULE, prolog <<
"Client command successfully processed." << endl);
203 BESDEBUG(MODULE, prolog <<
"ERROR - cmd.execute_request() returned: " << status << endl);
208 map<string, string> extensions;
209 extensions[
"status"] =
"error";
210 if (status == BES_INTERNAL_FATAL_ERROR) {
211 extensions[
"exit"] =
"true";
213 connection->sendExtensions(extensions);
222 case BES_INTERNAL_FATAL_ERROR:
223 ERROR_LOG(
"BES Internal Fatal Error; child returning "
224 + std::to_string(SERVER_EXIT_ABNORMAL_TERMINATION) +
" to the master listener.");
226 connection->closeConnection();
227 exit(SERVER_EXIT_ABNORMAL_TERMINATION);
231 case BES_INTERNAL_ERROR:
234 ERROR_LOG(
"BES Internal Error; child returning "
235 + std::to_string(SERVER_EXIT_ABNORMAL_TERMINATION) +
" to the master listener.");
237 connection->closeConnection();
238 exit(SERVER_EXIT_ABNORMAL_TERMINATION);
243 case BES_SYNTAX_USER_ERROR:
244 case BES_FORBIDDEN_ERROR:
245 case BES_NOT_FOUND_ERROR:
261 strm << BESIndent::LMarg <<
"BESServerHandler::dump - (" << (
void *)
this <<
")" << endl;
263 strm << BESIndent::LMarg <<
"server method: " << _method << endl;
264 BESIndent::UnIndent();
std::string get_message() const
get the error message for this exception
pid_t update_pid()
Update the d_pid and the d_log_record_prolog_base values.
void dump(std::ostream &strm) const override
dumps information about this object
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Access to the singleton.