Skip to content
Snippets Groups Projects
gridListReader.cxx 4.67 KiB
#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;
}