#include "gridListReader.h" #include <iostream> #include <limits> #include <stdexcept> #include <unistd.h> #include <QtXml/QDomDocument> #include <QtXml/QDomNode> #include <QtXml/QDomNodeList> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkReply> #include <QtCore/QUrl> #include <QtNetwork/QNetworkAccessManager> gridListReader::gridListReader( int gridnumber , bool debug ) : networkManager ( new QNetworkAccessManager ( this ) ) { _debug = debug; gridApdListApiUrl = gridApdListBaseUrl + "?gridnumber=" + std::to_string(gridnumber); getAndProcessData(); } void gridListReader::getAndProcessData() { try { getApdListFromNetwork(); verifyHttpResponse(); getDataFromReply(); verifyDataFormat(); verifyQuerySuccess(); getApdNodeList(); readyToReadData = true; } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; readyToReadData = false; } } void gridListReader::getApdListFromNetwork() { if ( _debug ) std::cout << "Initiating network request to " << gridApdListApiUrl << std::endl; replyWithFullList = networkManager->get ( QNetworkRequest ( QUrl ( gridApdListApiUrl.c_str() ) ) ); connect ( replyWithFullList, SIGNAL ( finished() ), &_waitForNetwork, SLOT ( quit() ) ); _waitForNetwork.exec(); if ( _debug ) std::cout << "Done, received reply." << std::endl; } void gridListReader::verifyHttpResponse() { if ( replyWithFullList->attribute ( QNetworkRequest::HttpStatusCodeAttribute ).toInt() != 200 ) { const QString exceptionMsg = QString::fromUtf8 ( "HTTP error while invoking Production DB Web API: The server returned HTTP status code %1." ).arg ( replyWithFullList->attribute ( QNetworkRequest::HttpStatusCodeAttribute ).toInt() ); throw std::runtime_error ( exceptionMsg.toUtf8().constData() ); } } void gridListReader::getDataFromReply() { QString errorMsg; int errorLine; int errorColumn; documentFromNetworkReply = new QDomDocument(); if ( _debug ) std::cout << "Setting content of network reply to QDomDocument, verifying response..." << std::endl; if ( !documentFromNetworkReply->setContent ( replyWithFullList, &errorMsg, &errorLine, &errorColumn ) ) { const QString exceptionMsg = QString::fromUtf8 ( "Error in parsing data" ); throw std::runtime_error ( exceptionMsg.toUtf8().constData() ); } } void gridListReader::verifyDataFormat() { if ( documentFromNetworkReply->documentElement().nodeName() != QString::fromUtf8 ( "productiondb" ) || documentFromNetworkReply->documentElement().firstChild().nodeName() != QString::fromUtf8 ( "request" ) ) throw std::runtime_error ( "APD data has invalid format." ); QDomNode requestResult = documentFromNetworkReply->documentElement().firstChild(); if ( !requestResult.attributes().contains ( QString::fromUtf8 ( "successful" ) ) || !requestResult.attributes().contains ( QString::fromUtf8 ( "error_number" ) ) ) throw std::runtime_error ( "APD data has invalid format." ); } void gridListReader::verifyQuerySuccess() { QDomNode requestResult = documentFromNetworkReply->documentElement().firstChild(); if ( requestResult.attributes().namedItem ( QString::fromUtf8 ( "successful" ) ).nodeValue() != QString::fromUtf8 ( "true" ) ) { const QString exceptionMsg = QString::fromUtf8 ( "Server reports error %1 when querying data" ); throw std::runtime_error ( exceptionMsg.toUtf8().constData() ); } } void gridListReader::getApdNodeList() { nodeListApds = new QDomNodeList( documentFromNetworkReply->documentElement().elementsByTagName ( QString::fromUtf8 ( "apd" ) ) ); if ( _debug ) std::cout << "Got " << nodeListApds->length() << " APDs!" << std::endl; } std::vector<std::string> gridListReader::getListOfSerials() { try { return getSerialListIfDataCanBeRead(); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; std::vector<std::string> serialList; serialList.clear(); return serialList; } } std::vector<std::string> gridListReader::getSerialListIfDataCanBeRead() { if (!readyToReadData) throw std::runtime_error ( "No data loaded that can be read!" ); std::vector<std::string> serialList = getSerialListFromNodeList(); if ( _debug ) std::cout << "Returning serial list with " << serialList.size() << " entries!" << std::endl; return serialList; } std::vector<std::string> gridListReader::getSerialListFromNodeList() { std::vector<std::string> serialList; serialList.clear(); for ( int i = 0; i < nodeListApds->length(); i++ ) { QDomNode apdNode = nodeListApds->item ( i ); std::string serial = apdNode.attributes().namedItem ( QString::fromUtf8 ( "serial" ) ).nodeValue().toStdString(); serialList.push_back(serial); } return serialList; }