X-Git-Url: https://git.llucax.com/z.facultad/75.42/plaqui.git/blobdiff_plain/7e74b790d290cd7d776349503bb361c47933c01f..31a4d1fea320e59487fa28bbb406ee50d4e7ec76:/Server/src/server.cpp?ds=inline diff --git a/Server/src/server.cpp b/Server/src/server.cpp index 340c2f0..5e7197a 100644 --- a/Server/src/server.cpp +++ b/Server/src/server.cpp @@ -26,13 +26,14 @@ // #include "plaqui/server/server.h" +#include "plaqui/server/string.h" #include "plaqui/server/connection.h" #include "plaqui/server/controlserver.h" #include +#include #include #include #ifdef DEBUG -# include "plaqui/server/string.h" # include #endif // DEBUG @@ -47,10 +48,19 @@ Server::~Server(void) { cerr << __FILE__ << "(" << __LINE__ << ")" << ": destructor." << endl; #endif // DEBUG - // Termino plantas. - Glib::Mutex::Lock lock(plants_mutex); - for (PlantList::iterator i = plants.end(); i != plants.end(); i++) { - i->second->finish(true); + // Mando a terminar todas las plantas. + plants_mutex.lock(); + for (PlantList::iterator i = plants.begin(); i != plants.end(); i++) { + i->second->finish(); + } + PlantList::size_type count = plants.size(); + plants_mutex.unlock(); + // Espero que terminen realmente. + while (count) { + Glib::usleep(10000); // 10 milisegundos + plants_mutex.lock(); + count = plants.size(); + plants_mutex.unlock(); } } @@ -60,13 +70,12 @@ Server::Server(const string& plant_filename, const Connection::Port& port) cerr << __FILE__ << "(" << __LINE__ << ")" << ": port = " << port << endl; #endif // DEBUG - // FIXME + // FIXME - hacer que se puedan cargar mas plantas bien. Glib::Mutex::Lock lock(plants_mutex); plants["default"] = new Plant(plant_filename); - plants["default"]->signal_finished().connect( - SigC::bind( - SigC::slot_class(*this, &Server::on_plant_finished), - "default")); + plants["default"]->signal_finished().connect(SigC::bind( + SigC::slot_class(*this, &Server::on_plant_finished), + "default")); plants["default"]->run(); } @@ -78,10 +87,9 @@ Connection* Server::new_connection(const sockbuf::sockdesc& sd) { #endif // DEBUG ControlServer* connection = new ControlServer(sd); // TODO verificar si el new se hace bien? no creo. - connection->signal_command_received().connect( - SigC::bind( - SigC::slot_class(*this, &Server::on_control_command_received), - connection)); + connection->signal_command_received().connect(SigC::bind( + SigC::slot_class(*this, &Server::on_control_command_received), + connection)); // TODO: return connection; } @@ -105,18 +113,24 @@ void Server::on_control_command_received(const Command& command, << ", args = [" << String::join(command.get_args(), ", ") << "])" << endl; #endif // DEBUG - HTTPResponse* response; - //bool stop_controlserver = false; + Response* response; if (command.get_target() == "server") { - if (command.get_command() == "status") { - response = cmd_server_status(); + if (command.get_command() == "info") { + response = cmd_server_info(); } else if (command.get_command() == "stop") { + response = new Response(Response::OK, + "El server se cerrará en instantes"); + // XXX - Sin mandar la respuesta enseguida podría ser que el server + // cierre la conexión antes de mandar la respuesta. + //response->headers["Content-Type"] = "text/xml; charset=iso-8859-1"; + //controlserver->send(*response); + //delete response; finish(); - response = new HTTPResponse(HTTPMessage::OK, - ""); + //return; } else { - response = new HTTPResponse(HTTPMessage::NOT_FOUND, - ""); + response = new Response(Response::INVALID_COMMAND, + command.get_command() + " es un comando inválido para " + + "el destino 'server'"); } } else if (command.get_target() == "connection") { if (command.get_command() == "list") { @@ -124,8 +138,9 @@ void Server::on_control_command_received(const Command& command, } else if (command.get_command() == "stop") { response = cmd_connection_stop(command); } else { - response = new HTTPResponse(HTTPMessage::NOT_FOUND, - ""); + response = new Response(Response::INVALID_COMMAND, + command.get_command() + " es un comando inválido para " + + "el destino 'connection'"); } } else if (command.get_target() == "transmission") { if (command.get_command() == "list") { @@ -135,8 +150,9 @@ void Server::on_control_command_received(const Command& command, } else if (command.get_command() == "stop") { response = cmd_transmission_stop(command); } else { - response = new HTTPResponse(HTTPMessage::NOT_FOUND, - ""); + response = new Response(Response::INVALID_COMMAND, + command.get_command() + " es un comando inválido para " + + "el destino 'transmission'"); } } else if (command.get_target() == "plant") { if (command.get_command() == "list") { @@ -145,18 +161,24 @@ void Server::on_control_command_received(const Command& command, response = cmd_plant_get(command); } else if (command.get_command() == "set") { response = cmd_plant_set(command); + } else if (command.get_command() == "set_frequency") { + response = cmd_plant_set_frequency(command); + } else if (command.get_command() == "start") { + response = cmd_plant_start(command); } else if (command.get_command() == "stop") { response = cmd_plant_stop(command); + } else if (command.get_command() == "remove") { + response = cmd_plant_remove(command); } else { - response = new HTTPResponse(HTTPMessage::NOT_FOUND, - ""); + response = new Response(Response::INVALID_COMMAND, + command.get_command() + " es un comando inválido para " + + "el destino 'plant'"); } } else { - response = new HTTPResponse(HTTPMessage::NOT_FOUND, - ""); + response = new Response(Response::INVALID_TARGET, command.get_target() + + " es un destino inválido"); } // FIXME - response->headers["Content-Type"] = "text/xml; charset=iso-8859-1"; //response->headers["Connection"] = "close"; controlserver->send(*response); delete response; @@ -167,7 +189,7 @@ void Server::on_control_command_received(const Command& command, //} } -HTTPResponse* Server::cmd_server_status(void) const { +Response* Server::cmd_server_info(void) const { // FIXME stringstream xml; xml << "" << endl; @@ -178,10 +200,10 @@ HTTPResponse* Server::cmd_server_status(void) const { xml << "\t\tRicardo Markiewicz" << endl; xml << "\t" << endl; xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, xml.str()); + return new Response(xml.str()); } -HTTPResponse* Server::cmd_connection_list(void) { +Response* Server::cmd_connection_list(void) { // FIXME TCPServer::ConnectionInfoList cil = get_connected(); stringstream xml; @@ -189,32 +211,30 @@ HTTPResponse* Server::cmd_connection_list(void) { for (TCPServer::ConnectionInfoList::const_iterator i = cil.begin(); i != cil.end(); i++) { xml << "\t" << endl; - xml << "\t\t" << i->host << "" << endl; - xml << "\t\t" << i->port << "" << endl; + xml << "\t\t" << i->host << "" << endl; + xml << "\t\t" << i->port << "" << endl; xml << "\t" << endl; } xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, xml.str()); + return new Response(xml.str()); } -HTTPResponse* Server::cmd_connection_stop(const Command& command) { +Response* Server::cmd_connection_stop(const Command& command) { const Command::Arguments& args = command.get_args(); Connection::Port port; if (args.size() < 2) { - return new HTTPResponse(HTTPMessage::CONFLICT, - ""); + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'stop' del destino 'connection'"); } else if (disconnect(args[0], to(args[1], port))) { - return new HTTPResponse(HTTPMessage::OK, - string(""); + return new Response(Response::OK, string("La conexión a ") + args[0] + + ":" + args[1] + " se cerrará en instantes"); } else { - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); + return new Response(Response::CONNECTION_NOT_FOUND, + string("No existe una conexión a ") + args[0] + ":" + args[1]); } } -HTTPResponse* Server::cmd_transmission_list(void) { +Response* Server::cmd_transmission_list(void) { // FIXME stringstream xml; xml << "" << endl; @@ -229,14 +249,14 @@ HTTPResponse* Server::cmd_transmission_list(void) { } transmissions_mutex.unlock();*/ xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, xml.str()); + return new Response(xml.str()); } -HTTPResponse* Server::cmd_transmission_start(const Command& command) { +Response* Server::cmd_transmission_start(const Command& command) { const Command::Arguments& args = command.get_args(); if (args.size() < 3) { - return new HTTPResponse(HTTPMessage::CONFLICT, - ""); + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'start' del destino 'transmission'"); } else { string plant = args[0]; string host = args[1]; @@ -244,27 +264,27 @@ HTTPResponse* Server::cmd_transmission_start(const Command& command) { Glib::Mutex::Lock lock(plants_mutex); PlantList::iterator p = plants.find(plant); if (p == plants.end()) { - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); - // TODO - agregar chequeo de que la transmision a ese host:port no - // exista para otra planta? + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + plant + "'"); + // FIXME - agregar chequeo de que la transmision a ese host:port no exista. + // que use respuesta ALLREADY_EXISTS } else if (plants[plant]->transmission_start(host, port)) { - return new HTTPResponse(HTTPMessage::OK, - string(""); + return new Response(Response::OK, + string("Se empieza a transmitir la planta '") + plant + + "' a " + host + ":" + String().from(port)); } else { - return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, - string(""); + return new Response(Response::ERROR_STARTING_TRANSMISSION, + string("Error al crear la transmisión a de la planta '") + + plant + "' a " + host + ":" + args[2]); } } } -HTTPResponse* Server::cmd_transmission_stop(const Command& command) { +Response* Server::cmd_transmission_stop(const Command& command) { const Command::Arguments& args = command.get_args(); if (args.size() < 2) { - return new HTTPResponse(HTTPMessage::CONFLICT, - ""); + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'stop' del destino 'transmission'"); } else { const string& host = args[0]; Connection::Port port = to(args[1], port); @@ -273,73 +293,74 @@ HTTPResponse* Server::cmd_transmission_stop(const Command& command) { // tirar error de que no hay conexion o de que no se pudo // desconectar. if (i->second->transmission_stop(host, port)) { - return new HTTPResponse(HTTPMessage::OK, - string("first + "' a " + host + ":" + args[1] + ".\" />"); + return new Response(Response::OK, + string("La transmisión de la planta '") + i->first + + "' a " + host + ":" + args[1] + + " se cerrará en instantes"); } } - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); + return new Response(Response::TRANSMISSION_NOT_FOUND, + string("No existe una transmisión a ") + host + ":" + args[1]); } } -HTTPResponse* Server::cmd_plant_list(void) { - // FIXME +Response* Server::cmd_plant_list(void) { + // FIXME hacer con ResponseList stringstream xml; xml << "" << endl; plants_mutex.lock(); for (PlantList::const_iterator i = plants.begin(); i != plants.end(); i++) { xml << "\t" << endl; - xml << "\t\t" << i->first << "" << endl; + xml << "\t\t" << i->first << "" << endl; xml << "\t" << endl; } plants_mutex.unlock(); xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, xml.str()); + return new Response(xml.str()); } -HTTPResponse* Server::cmd_plant_get(const Command& command) { +Response* Server::cmd_plant_get(const Command& command) { if (!command.get_args().size()) { - return new HTTPResponse(HTTPMessage::CONFLICT, - ""); + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'get' del destino 'plant'"); } Glib::Mutex::Lock lock(plants_mutex); string plant = command.get_args()[0]; if (plants.find(plant) == plants.end()) { - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + plant + "'"); } // TODO try/catch? string xml = plants[plant]->get_xml(); if (xml.length()) { - return new HTTPResponse(HTTPMessage::OK, xml); + return new Response(xml); } else { - return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, - (""); + return new Response(Response::ERROR_GETING_PLANT_XML, + ("No se pudo obtener el XML de la planta '") + plant + "'"); } } -HTTPResponse* Server::cmd_plant_set(const Command& command) { +Response* Server::cmd_plant_set(const Command& command) { const Command::Arguments& args = command.get_args(); if (args.size() < 4) { - return new HTTPResponse(HTTPMessage::CONFLICT, - ""); + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'set' del destino 'plant'"); } string plant = args[0]; string element = args[1]; - string key = args[2]; - if (key != "open") { - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); + string input = args[2]; + if (input != "open") { + return new Response(Response::ELEMENT_INPUT_NOT_FOUND, + string("El elemento '") + element + "' de la planta '" + plant + + "' no tiene una entrada '" + input + "'"); } string value = args[3]; Glib::Mutex::Lock lock(plants_mutex); PlantList::iterator p = plants.find(plant); if (p == plants.end()) { - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + plant + "'"); } bool open = true; if ((value == "false") || (value == "0") || (value == "off") @@ -347,28 +368,84 @@ HTTPResponse* Server::cmd_plant_set(const Command& command) { open = false; } if (!plants[plant]->set_open(element, open)) { - return new HTTPResponse(HTTPMessage::CONFLICT, - string(""); + return new Response(Response::ERROR_CHANGING_ELEMENT_INPUT, + string("No se pudo cambiar la entrada '") + input + + "' del elemento '" + element + "' de la planta '" + + plant + "'"); + } + return new Response(Response::OK, + string("Se cambió la entrada '") + input + "' del elemento '" + + element + "' de la planta '" + plant + "' a '" + value + "'"); +} + +Response* Server::cmd_plant_set_frequency(const Command& command) { + if (command.get_args().size() < 2) { + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'set_frequency' del destino 'plant'"); + } + Glib::Mutex::Lock lock(plants_mutex); + const string name = command.get_args()[0]; + if (plants.find(name) == plants.end()) { + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + name + "'"); + } + unsigned hz; + to(command.get_args()[1], hz); + /* TODO poner cantidad real que tomó: hz = */plants[name]->set_frequency(hz); + String shz; + shz.from(hz); + return new Response(Response::OK, + string("Se cambió la frecuencia de refresco de la planta '") + name + + "' a '" + shz + "' veces por segundo"); +} + +Response* Server::cmd_plant_start(const Command& command) { + if (!command.get_args().size()) { + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'start' del destino 'plant'"); + } + Glib::Mutex::Lock lock(plants_mutex); + const string name = command.get_args()[0]; + if (plants.find(name) == plants.end()) { + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + name + "'"); + } + plants[name]->set_paused(false); + return new Response(Response::OK, + string("La planta '") + name + "' fue reanudada"); +} + +Response* Server::cmd_plant_stop(const Command& command) { + if (!command.get_args().size()) { + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'stop' del destino 'plant'"); + } + Glib::Mutex::Lock lock(plants_mutex); + const string name = command.get_args()[0]; + if (plants.find(name) == plants.end()) { + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + name + "'"); } - return new HTTPResponse(HTTPMessage::OK, - string(""); + plants[name]->set_paused(true); + return new Response(Response::OK, + string("La planta '") + name + "' fue pausada"); } -HTTPResponse* Server::cmd_plant_stop(const Command& command) { +Response* Server::cmd_plant_remove(const Command& command) { if (!command.get_args().size()) { - return new HTTPResponse(HTTPMessage::CONFLICT, - ""); + return new Response(Response::ARGUMENT_MISSING, "Faltan argumentos " + " para el comando 'remove' del destino 'plant'"); } Glib::Mutex::Lock lock(plants_mutex); const string name = command.get_args()[0]; if (plants.find(name) == plants.end()) { - return new HTTPResponse(HTTPMessage::NOT_FOUND, - string(""); + return new Response(Response::PLANT_NOT_FOUND, + string("No existe la planta '") + name + "'"); } - // TODO Ver si al frenar la planta se destruye (no deberia!!!) plants[name]->finish(); - return new HTTPResponse(HTTPMessage::OK, - string(""); + return new Response(Response::OK, + string("La planta '") + name + "' fue será removida del servidor " + "en instantes"); } } // namespace Server