X-Git-Url: https://git.llucax.com/z.facultad/75.42/plaqui.git/blobdiff_plain/6e0194f46ac77c18bfeabf84ef94a32f23e41073..e4f66a8221e3f2156d89a7a358073863503b2564:/Server/src/server.cpp diff --git a/Server/src/server.cpp b/Server/src/server.cpp index 6507d6d..8f76922 100644 --- a/Server/src/server.cpp +++ b/Server/src/server.cpp @@ -26,40 +26,343 @@ // #include "plaqui/server/server.h" +#include "plaqui/server/connection.h" +#include "plaqui/server/controlserver.h" +#include +// FIXME - sacar sstream (a menos que se necesite) +#include #ifdef DEBUG +# include "plaqui/server/string.h" # include #endif // DEBUG -using namespace Plaqui; +using namespace std; -Server::Server(int port): - socket(sockbuf::sock_stream) { - socket.bind(port); +namespace PlaQui { + +namespace Server { + +Server::~Server(void) { +#ifdef DEBUG + cerr << __FILE__ << ": 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); + } +} + +Server::Server(const string& plant_filename, const Connection::Port& port): + TCPServer(port) { +#ifdef DEBUG + cerr << __FILE__ << ": port = " << port << endl; +#endif // DEBUG + // FIXME + 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"]->run(); +} + +Connection* Server::new_connection( + const sockbuf::sockdesc& sd) { +#ifdef DEBUG + cerr << __FILE__ << ": new_connection(sd = " << sd.sock << ")" + << endl; +#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)); + // TODO: + return connection; +} + +void Server::on_plant_updated(const Plant* plant) { #ifdef DEBUG - std::cerr << "Escuchando en " << socket.localhost() << - ":" << socket.localport() << "." << std::endl; + cerr << __FILE__ << ": on_plant_updated(plant = " << plant << ")." << endl; #endif // DEBUG - socket.listen(); } -bool Server::start_transmission(std::string host, int port) { - // TODO - return false; +void Server::on_plant_finished(const char* plant) { +#ifdef DEBUG + cerr << __FILE__ << ": on_plant_finished(plant_name = " << plant << endl; +#endif // DEBUG + Glib::Mutex::Lock lock(plants_mutex); + plants.erase(plant); +} + +/// \todo Terminar de implementar. +void Server::on_control_command_received(const Command& command, + ControlServer* controlserver) { +#ifdef DEBUG + cerr << __FILE__ << ": on_control_command_received(target = " + << command.get_target() << ", command = " << command.get_command() + << ", args = [" << String::join(command.get_args(), ", ") << "])" + << endl; +#endif // DEBUG + HTTPResponse* response; + //bool stop_controlserver = false; + if (command.get_target() == "server") { + if (command.get_command() == "status") { + response = cmd_server_status(); + } else if (command.get_command() == "stop") { + finish(); + response = new HTTPResponse(HTTPMessage::OK, + "El server se apagará en instantes..."); + } else { + response = new HTTPResponse(HTTPMessage::NOT_FOUND, + "Invalid command for 'server' taget!"); + } + } else if (command.get_target() == "connection") { + if (command.get_command() == "list") { + response = cmd_connection_list(); + } else if (command.get_command() == "stop") { + response = cmd_connection_stop(command); + } else { + response = new HTTPResponse(HTTPMessage::NOT_FOUND, + "Invalid command for 'connection' taget!"); + } + } else if (command.get_target() == "transmission") { + if (command.get_command() == "list") { + response = cmd_transmission_list(); + } else if (command.get_command() == "start") { + response = cmd_transmission_start(command); + } else if (command.get_command() == "stop") { + response = cmd_transmission_stop(command); + } else { + response = new HTTPResponse(HTTPMessage::NOT_FOUND, + "Invalid command for 'transmission' taget!"); + } + } else if (command.get_target() == "plant") { + if (command.get_command() == "list") { + response = cmd_plant_list(); + } else if (command.get_command() == "get") { + response = cmd_plant_get(command); + } else if (command.get_command() == "set") { + response = cmd_plant_set(command); + } else if (command.get_command() == "stop") { + response = cmd_plant_stop(command); + } else { + response = new HTTPResponse(HTTPMessage::NOT_FOUND, + "Invalid command for 'plant' taget!"); + } + } else { + response = new HTTPResponse(HTTPMessage::NOT_FOUND, "Invalid taget!"); + } + // FIXME + response->headers["Content-Type"] = "text/xml; charset=iso-8859-1"; + //response->headers["Connection"] = "close"; + controlserver->send(*response); + delete response; + // FIXME con timeout no debería ser necesario. Verificar cabecera Connection + // para saber si hay que finish()earlo o no. + //if (stop_controlserver) { + // controlserver->finish(); + //} +} + +HTTPResponse* Server::cmd_server_status(void) const { + // FIXME + stringstream response_xml; + response_xml << "" << endl; + response_xml << "\t0.9" << endl; + response_xml << "\t" << endl; + response_xml << "\t\tNicolás Dimov" << endl; + response_xml << "\t\tLeandro Lucarella" << endl; + response_xml << "\t\tRicardo Markiewicz" << endl; + response_xml << "\t" << endl; + response_xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, response_xml.str()); +} + +HTTPResponse* Server::cmd_connection_list(void) { + // FIXME + TCPServer::ConnectionInfoList cil = get_connected(); + stringstream response_xml; + response_xml << "" << endl; + for (TCPServer::ConnectionInfoList::const_iterator i = cil.begin(); + i != cil.end(); i++) { + response_xml << "\t" << endl; + response_xml << "\t\t" << i->host << "" << endl; + response_xml << "\t\t" << i->port << "" << endl; + response_xml << "\t" << endl; + } + response_xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, response_xml.str()); +} + +HTTPResponse* 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, + "Faltan argumentos."); + } else if (disconnect(args[0], String(args[1]).to(port))) { + return new HTTPResponse(HTTPMessage::OK, + string("La conexión a ") + args[0] + ":" + args[1] + + " se cerrará en instantes..."); + } else { + return new HTTPResponse(HTTPMessage::NOT_FOUND, + string("No existe una conexión a ") + args[0] + + ":" + args[1]); + } +} + +HTTPResponse* Server::cmd_transmission_list(void) { + // FIXME + stringstream response_xml; + response_xml << "" << endl; +/*TODO plants_mutex.lock(); + for (PlantList::const_iterator i = plants.begin(); + i != plants.end(); i++) { + trans + response_xml << "
  • " << (*i)->get_host() << ":" + << (*i)->get_port() << " [get_host() << "/" << (*i)->get_port() + << "\">desconectar]
  • " << endl; + } + transmissions_mutex.unlock();*/ + response_xml << "
    " << endl; + return new HTTPResponse(HTTPMessage::OK, response_xml.str()); +} + +HTTPResponse* Server::cmd_transmission_start(const Command& command) { + const Command::Arguments& args = command.get_args(); + if (args.size() < 3) { + return new HTTPResponse(HTTPMessage::CONFLICT, + "Faltan argumentos."); + } else { + string plant = args[0]; + string host = args[1]; + Connection::Port port = String(args[2]).to(port); + Glib::Mutex::Lock lock(plants_mutex); + PlantList::iterator p = plants.find(plant); + if (p == plants.end()) { + return new HTTPResponse(HTTPMessage::NOT_FOUND, + string("No existe la planta '") + plant + "'."); + // TODO - agregar chequeo de que la transmision a ese host:port no + // exista para otra planta? + } else if (plants[plant]->transmission_start(host, port)) { + return new HTTPResponse(HTTPMessage::OK, + string("Se empieza a transmitir la planta '") + plant + + "' a " + host + ":" + String().from(port) + "."); + } else { + return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, + string("Error al crear la transmisión a de la planta '") + + plant + "' a " + host + ":" + args[2] + "."); + } + } +} + +HTTPResponse* Server::cmd_transmission_stop(const Command& command) { + const Command::Arguments& args = command.get_args(); + if (args.size() < 2) { + return new HTTPResponse(HTTPMessage::CONFLICT, + "Faltan argumentos."); + } else { + const string& host = args[0]; + Connection::Port port = String(args[1]).to(port); + for (PlantList::iterator i = plants.begin(); i != plants.end(); i++) { + // TODO - agregar chequeo para saber si existe una conexion (para + // 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("Se finaliza la transmisión de la planta '") + + i->first + "' a " + host + ":" + args[1] + "."); + } + } + return new HTTPResponse(HTTPMessage::NOT_FOUND, + string("No se puede finalizar la transmisión a ") + + host + ":" + args[1] + "."); + } } -bool Server::stop_transmission(std::string host, int port) { - // TODO - return false; +HTTPResponse* Server::cmd_plant_list(void) { + // FIXME + stringstream response_xml; + response_xml << "" << endl; + plants_mutex.lock(); + for (PlantList::const_iterator i = plants.begin(); + i != plants.end(); i++) { + response_xml << "\t" << endl; + response_xml << "\t\t" << i->first << "" << endl; + response_xml << "\t" << endl; + } + plants_mutex.unlock(); + response_xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, response_xml.str()); } -void Server::real_run(void) { - // FIXME se tiene que ir a la clase para poder frenarlo desde afuera. - bool stop = false; - ControlServer* control_server; - while (!stop) { - control_server = new ControlServer(socket.accept()); - controllers.push_back(control_server); - control_server->run(); +HTTPResponse* Server::cmd_plant_get(const Command& command) { + if (!command.get_args().size()) { + return new HTTPResponse(HTTPMessage::CONFLICT, + "Faltan argumentos."); + } + 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("No existe la planta ") + plant); + } + string xml = plants[plant]->get_xml(); + if (xml.length()) { + return new HTTPResponse(HTTPMessage::OK, xml); + } else { + return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, + ("No se pudo obtener el XML de la planta ") + plant); + } +} + +HTTPResponse* Server::cmd_plant_set(const Command& command) { + const Command::Arguments& args = command.get_args(); + if (args.size() < 4) { + return new HTTPResponse(HTTPMessage::CONFLICT, + "Faltan argumentos."); + } + string plant = args[0]; + string element = args[1]; + string key = args[2]; + 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("No existe la planta '") + plant + "'."); } +/* if (!plants[plant]->set_element(host, port)) { + return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, + string("Error al crear la transmisión a de la planta '") + + plant + "' a " + host + ":" + args[2] + "."); + }*/ + return new HTTPResponse(HTTPMessage::OK); } +HTTPResponse* Server::cmd_plant_stop(const Command& command) { + if (!command.get_args().size()) { + return new HTTPResponse(HTTPMessage::CONFLICT, + "Faltan argumentos."); + } + 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("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("La planta '") + name + "' se cerrará en instantes..."); +} + +} // namespace Server + +} // namespace PlaQui +