-
Jan Reher authored4b7743fd
#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;
}