#include namespace MetadataExporter_ns { //============================================================================== // ProtocolManager::ProtocolManager() //============================================================================== ProtocolManager::ProtocolManager(Tango::DeviceImpl* deviceImpl_p, Configuration::SP configuration_sp, DBManager::SP dBManager_sp) : Tango::LogAdapter(deviceImpl_p), m_configuration_sp(configuration_sp), m_dBManager_sp(dBManager_sp) { DEBUG_STREAM << "ProtocolManager::ProtocolManager()" << endl; m_isAuthorised = false; m_isValidated = false; } //============================================================================== // ProtocolManager::ProtocolManager() //============================================================================== ProtocolManager::~ProtocolManager() { DEBUG_STREAM << "ProtocolManager::~ProtocolManager()" << endl; } //============================================================================== // ProtocolManager::ProtocolManager() //============================================================================== ProtocolManager::SP ProtocolManager::create(Tango::DeviceImpl* deviceImpl_p, Configuration::SP configuration_sp, DBManager::SP dBManager_sp) { ProtocolManager::SP d_sp(new ProtocolManager(deviceImpl_p, configuration_sp, dBManager_sp), ProtocolManager::Deleter()); return d_sp; } //============================================================================== // ProtocolManager::ProtocolManager() //============================================================================== void ProtocolManager::setRemoteEndpoint(std::string remoteEndpoint) { DEBUG_STREAM << "ProtocolManager::setRemoteEndpoint()" << endl; m_remoteEndpoint = remoteEndpoint; } //============================================================================== // ProtocolManager::prepareResponse() //============================================================================== ResponseSP ProtocolManager::prepareResponse(RequestSP request_sp) throw(std::runtime_error) { DEBUG_STREAM << "ProtocolManager::prepareResponse()" << endl; ResponseSP response_sp; switch(request_sp->type()) { case Request::AUTHORIZATION: { response_sp = prepareAuthroisation(request_sp); break; } case Request::VALIDATION: { response_sp = prepareValidation(request_sp); break; } case Request::METADATA: { response_sp = prepareMetadata(request_sp); break; } default: throw std::runtime_error("Unknown request type!"); } if(!response_sp->IsInitialized()) throw std::runtime_error("Not initialized response!"); return response_sp; } //============================================================================== // ProtocolManager::prepareAuthroisation() //============================================================================== ResponseSP ProtocolManager::prepareAuthroisation(RequestSP request_sp) throw(std::runtime_error) { DEBUG_STREAM << "ProtocolManager::prepareAuthroisation()" << endl; ResponseSP response_sp(new Response()); response_sp->set_type(Response::AUTHORIZATION); Response::Authorization* auth_resp = response_sp->mutable_authorization(); if(!m_isAuthorised) { const Request::Authorization& auth_req = request_sp->authorization(); std::string username = auth_req.username(); std::string password = auth_req.password(); if(m_configuration_sp->isUserAuthorized(username, password)) { INFO_STREAM << "ProtocolManager::prepareAuthroisation() " << "Authorization accepted from " << m_remoteEndpoint << endl; m_isAuthorised = true; auth_resp->set_state(Response::Authorization::ACCEPTED); auth_resp->set_status("Authorization accepted"); } else { WARN_STREAM << "ProtocolManager::prepareAuthroisation() " << "Invalid username or password from " << m_remoteEndpoint << endl; m_isAuthorised = false; auth_resp->set_state(Response::Authorization::REJECTED); auth_resp->set_status("Invalid username or password"); } } else { WARN_STREAM << "ProtocolManager::prepareAuthroisation() " << "Already authorized from " << m_remoteEndpoint << endl; auth_resp->set_state(Response::Authorization::REJECTED); auth_resp->set_status("Already authorized"); } return response_sp; } //============================================================================== // ProtocolManager::prepareValidation() //============================================================================== ResponseSP ProtocolManager::prepareValidation(RequestSP request_sp) throw(std::runtime_error) { DEBUG_STREAM << "ProtocolManager::prepareValidation()" << endl; ResponseSP response_sp(new Response()); response_sp->set_type(Response::VALIDATION); Response::Validation* validationRes = response_sp->mutable_validation(); if(m_isAuthorised) { if(!m_isValidated) { const Request::Validation& validationReq = request_sp->validation(); const std::string& schema = validationReq.schema(); const std::string& table = validationReq.table(); try { DBManager::InformationList informationList = m_dBManager_sp->retrieveInformation(schema, table); if(validationReq.columns_size() != (int)informationList.size()) throw std::runtime_error("Columns number does not match"); const google::protobuf::RepeatedPtrField < Request::Validation::Column >& columns = validationReq.columns(); google::protobuf::RepeatedPtrField < Request::Validation::Column >::const_iterator it; for(it=columns.begin(); it!=columns.end(); ++it) validateColumn(*it, informationList); INFO_STREAM << "ProtocolManager::prepareValidation() " << "Validation accepted from " << m_remoteEndpoint << endl; m_isValidated = true; validationRes->set_state(Response::Validation::ACCEPTED); validationRes->set_status("Table validated"); } catch(std::runtime_error& ex) { WARN_STREAM << "ProtocolManager::prepareValidation() " << ex.what() << " from " << m_remoteEndpoint << endl; validationRes->set_state(Response::Validation::REJECTED); validationRes->set_status(ex.what()); } } else { WARN_STREAM << "ProtocolManager::prepareValidation() " << "Already validated from " << m_remoteEndpoint << endl; validationRes->set_state(Response::Validation::REJECTED); validationRes->set_status("Already validated"); } } else { WARN_STREAM << "ProtocolManager::prepareValidation() " << "Not authorised from " << m_remoteEndpoint << endl; validationRes->set_state(Response::Validation::REJECTED); validationRes->set_status("Not authorised"); } return response_sp; } //============================================================================== // ProtocolManager::prepareMetadata() //============================================================================== ResponseSP ProtocolManager::prepareMetadata(RequestSP request_sp) throw(std::runtime_error) { DEBUG_STREAM << "ProtocolManager::prepareMetadata()" << endl; ResponseSP response_sp(new Response()); response_sp->set_type(Response::METADATA); Response::Metadata* metadataRes = response_sp->mutable_metadata(); metadataRes->set_partial(0); metadataRes->set_total(0); if(m_isAuthorised) { if(m_isValidated) { const Request::Metadata& metadataReq = request_sp->metadata(); std::string schema = metadataReq.schema(); std::string table = metadataReq.table(); int64_t rawTimestamp = metadataReq.timestamp(); std::tm timestamp = *localtime(&rawTimestamp); DEBUG_STREAM << "ProtocolManager::prepareMetadata() " << "schema " << schema << " table " << table << " timestamp " << asctime(×tamp) << " from " << m_remoteEndpoint << endl; try { DBManager::MetadataList metadataList = m_dBManager_sp->retrieveNewTuples(schema, table, timestamp); fillResponse(metadataRes, metadataList); metadataRes->set_state(Response::Metadata::ACCEPTED); metadataRes->set_status("Metadata ready"); } catch(std::runtime_error& ex) { WARN_STREAM << "ProtocolManager::prepareMetadata() " << ex.what() << " from " << m_remoteEndpoint << endl; metadataRes->set_state(Response::Metadata::REJECTED); metadataRes->set_status(ex.what()); } } else { WARN_STREAM << "ProtocolManager::prepareMetadata() " << "Not validated from " << m_remoteEndpoint << endl; metadataRes->set_state(Response::Metadata::REJECTED); metadataRes->set_status("Not validated"); } } else { WARN_STREAM << "ProtocolManager::prepareMetadata() " << "Not authorised from " << m_remoteEndpoint << endl; metadataRes->set_state(Response::Metadata::REJECTED); metadataRes->set_status("Not authorised"); } return response_sp; } //============================================================================== // ProtocolManager::validateColumn() //============================================================================== void ProtocolManager::validateColumn(const Request::Validation::Column& column, DBManager::InformationList& informationList) throw(std::runtime_error) { DEBUG_STREAM << "ProtocolManager::validateColumn()" << endl; bool found = false; DBManager::InformationList::const_iterator it; for(it=informationList.begin(); it!=informationList.end(); ++it) { if(!it->get<0>()) throw std::runtime_error("Empty column name"); std::string columnName = it->get<0>().get(); if(column.name().compare(columnName)==0) { found = true; if(!it->get<1>()) throw std::runtime_error("Empty column type"); std::string columnType = it->get<1>().get(); if(column.type().compare(columnType)!=0) { std::stringstream errorStream; errorStream << "Column " << column.name() << " type error " << "server " << columnType << " client " << column.type(); throw std::runtime_error(errorStream.str()); } if(!it->get<2>()) throw std::runtime_error("Empty is nullable"); std::string isNullable = it->get<2>().get(); if(column.nullable().compare(isNullable)!=0) { std::stringstream errorStream; errorStream << "Column " << column.name() << " nullable error " << "server " << isNullable << " client " << column.nullable(); throw std::runtime_error(errorStream.str()); } #ifdef VERBOSE_DEBUG INFO_STREAM << "SERVER: " << columnName << " | " << columnType << " | " << isNullable << endl; INFO_STREAM << "SERVER: " << column.name() << " | " << column.type() << " | " << column.nullable() << endl; #endif } } if(!found) { std::stringstream errorStream; errorStream << "Column " << column.name() << " not found on server"; throw std::runtime_error(errorStream.str()); } } //============================================================================== // ProtocolManager::fillResponse() //============================================================================== void ProtocolManager::fillResponse(const Response::Metadata& metadataRes, DBManager::MetadataList metadataList) throw(std::runtime_error) { DEBUG_STREAM << "ProtocolManager::fillResponse()" << endl; } } //namespace