refs #478, use data cache in readers

* URLs no longer have to be passed
* watchdog for DB readers to check DB status

In same step:
* fixed some log messages and comments
* allow to self signed SSL certificates
* adjusted namespace for CNetworkUtils (now in network)
This commit is contained in:
Klaus Basan
2015-10-14 02:36:14 +02:00
committed by Mathew Sutcliffe
parent 4fce848c59
commit 53ba50dd3a
18 changed files with 281 additions and 178 deletions

View File

@@ -8,6 +8,7 @@
*/ */
#include "databasereader.h" #include "databasereader.h"
#include "blackmisc/network/networkutils.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/datastoreutility.h" #include "blackmisc/datastoreutility.h"
#include <QJsonDocument> #include <QJsonDocument>
@@ -19,11 +20,14 @@ namespace BlackCore
{ {
CDatabaseReader::CDatabaseReader(QObject *owner, const QString &name) : CDatabaseReader::CDatabaseReader(QObject *owner, const QString &name) :
BlackMisc::CThreadedReader(owner, name) BlackMisc::CThreadedReader(owner, name)
{ } {
connect(&m_watchdogTimer, &QTimer::timeout, this, &CDatabaseReader::ps_watchdog);
}
void CDatabaseReader::readInBackgroundThread(CEntityFlags::Entity entities) void CDatabaseReader::readInBackgroundThread(CEntityFlags::Entity entities)
{ {
if (m_shutdown) { return; } if (m_shutdown) { return; }
this->m_watchdogTimer.stop();
bool s = QMetaObject::invokeMethod(this, "ps_read", Q_ARG(BlackMisc::Network::CEntityFlags::Entity, entities)); bool s = QMetaObject::invokeMethod(this, "ps_read", Q_ARG(BlackMisc::Network::CEntityFlags::Entity, entities));
Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed"); Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed");
Q_UNUSED(s); Q_UNUSED(s);
@@ -35,7 +39,6 @@ namespace BlackCore
JsonDatastoreResponse datastoreResponse; JsonDatastoreResponse datastoreResponse;
if (m_shutdown || this->isFinished()) if (m_shutdown || this->isFinished())
{ {
CLogMessage(this).debug() << Q_FUNC_INFO;
CLogMessage(this).info("Terminated data parsing process"); // for users CLogMessage(this).info("Terminated data parsing process"); // for users
nwReply->abort(); nwReply->abort();
return datastoreResponse; // stop, terminate straight away, ending thread return datastoreResponse; // stop, terminate straight away, ending thread
@@ -72,10 +75,85 @@ namespace BlackCore
return datastoreResponse; return datastoreResponse;
} }
CDatabaseReader::JsonDatastoreResponse CDatabaseReader::setStatusAndTransformReplyIntoDatastoreResponse(QNetworkReply *nwReply)
{
setConnectionStatus(nwReply);
return transformReplyIntoDatastoreResponse(nwReply);
}
void CDatabaseReader::setWatchdogUrl(const CUrl &url)
{
bool start;
{
QWriteLocker wl(&this->m_watchdogLock);
m_watchdogUrl = url;
start = url.isEmpty();
}
if (start)
{
m_watchdogTimer.start(30 * 1000);
}
else
{
m_watchdogTimer.stop();
}
}
bool CDatabaseReader::canConnect() const bool CDatabaseReader::canConnect() const
{ {
QReadLocker rl(&this->m_watchdogLock);
return m_canConnect;
}
bool CDatabaseReader::canConnect(QString &message) const
{
QReadLocker rl(&this->m_watchdogLock);
message = m_watchdogMessage;
return m_canConnect;
}
void CDatabaseReader::setConnectionStatus(bool ok, const QString &message)
{
{
QWriteLocker wl(&this->m_watchdogLock);
this->m_watchdogMessage = message;
this->m_canConnect = ok;
if (this->m_watchdogUrl.isEmpty()) { return; }
}
this->m_updateTimer->start(); // restart
}
void CDatabaseReader::setConnectionStatus(QNetworkReply *nwReply)
{
Q_ASSERT_X(nwReply, Q_FUNC_INFO, "Missing network reply");
if (nwReply->isFinished())
{
if (nwReply->error() == QNetworkReply::NoError)
{
setConnectionStatus(true);
}
else
{
setConnectionStatus(false, nwReply->errorString());
}
}
}
void CDatabaseReader::ps_watchdog()
{
CUrl url;
{
QReadLocker rl(&this->m_watchdogLock);
url = this->m_watchdogUrl;
}
if (url.isEmpty())
{
this->m_watchdogTimer.stop();
return;
}
QString m; QString m;
return canConnect(m); bool ok = CNetworkUtils::canConnect(url, m);
this->setConnectionStatus(ok, m);
} }
} // namespace } // namespace

View File

@@ -18,6 +18,8 @@
#include <QNetworkReply> #include <QNetworkReply>
#include <QJsonArray> #include <QJsonArray>
#include <QDateTime> #include <QDateTime>
#include <QTimer>
namespace BlackCore namespace BlackCore
{ {
@@ -57,18 +59,46 @@ namespace BlackCore
void readInBackgroundThread(BlackMisc::Network::CEntityFlags::Entity entities); void readInBackgroundThread(BlackMisc::Network::CEntityFlags::Entity entities);
//! Can connect to DB //! Can connect to DB
//! \threadsafe
bool canConnect() const; bool canConnect() const;
//! Can connect to server? //! Can connect to server?
//! \return message why connect failed //! \return message why connect failed
virtual bool canConnect(QString &message) const = 0; //! \threadsafe
bool canConnect(QString &message) const;
protected: protected:
BlackMisc::Network::CUrl m_watchdogUrl; //!< URL for checking if alive
QTimer m_watchdogTimer { this }; //!< Timer for watchdog
QString m_watchdogMessage; //!< Returned status message
bool m_canConnect = false; //!< Successful connection?
mutable QReadWriteLock m_watchdogLock; //!< Lock
//! Constructor //! Constructor
CDatabaseReader(QObject *owner, const QString &name); CDatabaseReader(QObject *owner, const QString &name);
//! Watchdog URL, empty means no checking
//! \threadsafe
void setWatchdogUrl(const BlackMisc::Network::CUrl &url);
//! Check if terminated or error, otherwise split into array of objects
CDatabaseReader::JsonDatastoreResponse setStatusAndTransformReplyIntoDatastoreResponse(QNetworkReply *nwReply);
private slots:
//! Watchdog
void ps_watchdog();
private:
//! Check if terminated or error, otherwise split into array of objects //! Check if terminated or error, otherwise split into array of objects
JsonDatastoreResponse transformReplyIntoDatastoreResponse(QNetworkReply *nwReply) const; JsonDatastoreResponse transformReplyIntoDatastoreResponse(QNetworkReply *nwReply) const;
//! Feedback about connection status
//! \threadsafe
void setConnectionStatus(bool ok, const QString &message = "");
//! Feedback about connection status
//! \threadsafe
void setConnectionStatus(QNetworkReply *nwReply);
}; };
} // namespace } // namespace

View File

@@ -10,7 +10,8 @@
#include "databasewriter.h" #include "databasewriter.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/datastoreutility.h" #include "blackmisc/datastoreutility.h"
#include "blackmisc/networkutils.h" #include "blackmisc/network/networkutils.h"
#include "blackmisc/project.h"
#include <QUrlQuery> #include <QUrlQuery>
#include <QJsonDocument> #include <QJsonDocument>
#include <QHttpPart> #include <QHttpPart>
@@ -21,9 +22,9 @@ using namespace BlackMisc::Simulation;
namespace BlackCore namespace BlackCore
{ {
CDatabaseWriter::CDatabaseWriter(const QString &protocol, const QString &server, const QString &baseUrl, QObject *parent) : CDatabaseWriter::CDatabaseWriter(const Network::CUrl &baseUrl, QObject *parent) :
QObject(parent), QObject(parent),
m_modelUrl(getModelWriteUrl(protocol, server, baseUrl)) m_modelUrl(getModelWriteUrl(baseUrl))
{ {
this->m_networkManager = new QNetworkAccessManager(this); this->m_networkManager = new QNetworkAccessManager(this);
this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CDatabaseWriter::ps_postResponse); this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CDatabaseWriter::ps_postResponse);
@@ -44,7 +45,7 @@ namespace BlackCore
return msg; return msg;
} }
QUrl url(m_modelUrl); QUrl url(m_modelUrl.toQUrl());
QNetworkRequest request(url); QNetworkRequest request(url);
const QByteArray jsonData(QJsonDocument(model.toJson()).toJson(QJsonDocument::Compact)); const QByteArray jsonData(QJsonDocument(model.toJson()).toJson(QJsonDocument::Compact));
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
@@ -54,7 +55,7 @@ namespace BlackCore
textPart.setBody(jsonData); textPart.setBody(jsonData);
multiPart->append(textPart); multiPart->append(textPart);
if (m_phpDebug) if (m_phpDebug && CProject::isRunningInDeveloperEnvironment())
{ {
QHttpPart textPartDebug; QHttpPart textPartDebug;
textPartDebug.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"XDEBUG_SESSION_START\"")); textPartDebug.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"XDEBUG_SESSION_START\""));
@@ -113,9 +114,9 @@ namespace BlackCore
} }
} }
QString CDatabaseWriter::getModelWriteUrl(const QString &protocol, const QString &server, const QString &baseUrl) Network::CUrl CDatabaseWriter::getModelWriteUrl(const Network::CUrl &baseUrl)
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/swiftwritemodel.php"); return baseUrl.withAppendedPath("service/swiftwritemodel.php");
} }
QList<QByteArray> CDatabaseWriter::splitData(const QByteArray &data, int size) QList<QByteArray> CDatabaseWriter::splitData(const QByteArray &data, int size)

View File

@@ -29,7 +29,7 @@ namespace BlackCore
public: public:
//! Constructor //! Constructor
CDatabaseWriter(const QString &protocol, const QString &server, const QString &baseUrl, QObject *parent); CDatabaseWriter(const BlackMisc::Network::CUrl &baseUrl, QObject *parent);
//! Write model to DB //! Write model to DB
BlackMisc::CStatusMessageList asyncWriteModel(const BlackMisc::Simulation::CAircraftModel &model); BlackMisc::CStatusMessageList asyncWriteModel(const BlackMisc::Simulation::CAircraftModel &model);
@@ -42,14 +42,14 @@ namespace BlackCore
void ps_postResponse(QNetworkReply *nwReplyPtr); void ps_postResponse(QNetworkReply *nwReplyPtr);
private: private:
QString m_modelUrl; BlackMisc::Network::CUrl m_modelUrl;
QNetworkAccessManager *m_networkManager = nullptr; QNetworkAccessManager *m_networkManager = nullptr;
QNetworkReply *m_pendingReply = nullptr; QNetworkReply *m_pendingReply = nullptr;
bool m_shutdown = false; bool m_shutdown = false;
bool m_phpDebug = true; bool m_phpDebug = true;
//! URL model web service //! URL model web service
static QString getModelWriteUrl(const QString &protocol, const QString &server, const QString &baseUrl); static BlackMisc::Network::CUrl getModelWriteUrl(const BlackMisc::Network::CUrl &baseUrl);
//! Split data array //! Split data array
static QList<QByteArray> splitData(const QByteArray &data, int size); static QList<QByteArray> splitData(const QByteArray &data, int size);

View File

@@ -7,9 +7,10 @@
* contained in the LICENSE file. * contained in the LICENSE file.
*/ */
#include "blackcore/setupreader.h"
#include "blackmisc/sequence.h" #include "blackmisc/sequence.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/networkutils.h" #include "blackmisc/network/networkutils.h"
#include "blackmisc/fileutilities.h" #include "blackmisc/fileutilities.h"
#include "blackmisc/json.h" #include "blackmisc/json.h"
#include "icaodatareader.h" #include "icaodatareader.h"
@@ -21,14 +22,12 @@
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
using namespace BlackCore::Data;
namespace BlackCore namespace BlackCore
{ {
CIcaoDataReader::CIcaoDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl) : CIcaoDataReader::CIcaoDataReader(QObject *owner) :
CDatabaseReader(owner, "CIcaoDataReader"), CDatabaseReader(owner, "CIcaoDataReader")
m_urlAircraftIcao(getAircraftIcaoUrl(protocol, server, baseUrl)),
m_urlAirlineIcao(getAirlineIcaoUrl(protocol, server, baseUrl)),
m_urlCountry(getCountryUrl(protocol, server, baseUrl))
{ {
this->m_networkManagerAircraft = new QNetworkAccessManager(this); this->m_networkManagerAircraft = new QNetworkAccessManager(this);
this->m_networkManagerAirlines = new QNetworkAccessManager(this); this->m_networkManagerAirlines = new QNetworkAccessManager(this);
@@ -167,28 +166,31 @@ namespace BlackCore
Q_ASSERT(this->m_networkManagerAircraft); Q_ASSERT(this->m_networkManagerAircraft);
Q_ASSERT(this->m_networkManagerAirlines); Q_ASSERT(this->m_networkManagerAirlines);
Q_ASSERT(this->m_networkManagerCountries); Q_ASSERT(this->m_networkManagerCountries);
Q_ASSERT(!m_urlAircraftIcao.isEmpty());
Q_ASSERT(!m_urlAirlineIcao.isEmpty());
Q_ASSERT(!m_urlCountry.isEmpty());
CEntityFlags::Entity entitiesTriggered = CEntityFlags::NoEntity; CEntityFlags::Entity entitiesTriggered = CEntityFlags::NoEntity;
if (entities.testFlag(CEntityFlags::AircraftIcaoEntity)) if (entities.testFlag(CEntityFlags::AircraftIcaoEntity))
{ {
QNetworkRequest requestAircraft(m_urlAircraftIcao); QUrl url(getAircraftIcaoUrl());
QNetworkRequest requestAircraft(url);
CNetworkUtils::ignoreSslVerification(requestAircraft);
this->m_networkManagerAircraft->get(requestAircraft); this->m_networkManagerAircraft->get(requestAircraft);
entitiesTriggered |= CEntityFlags::AircraftIcaoEntity; entitiesTriggered |= CEntityFlags::AircraftIcaoEntity;
} }
if (entities.testFlag(CEntityFlags::AirlineIcaoEntity)) if (entities.testFlag(CEntityFlags::AirlineIcaoEntity))
{ {
QNetworkRequest requestAirline(m_urlAirlineIcao); QUrl url(getAirlineIcaoUrl());
QNetworkRequest requestAirline(url);
CNetworkUtils::ignoreSslVerification(requestAirline);
this->m_networkManagerAirlines->get(requestAirline); this->m_networkManagerAirlines->get(requestAirline);
entitiesTriggered |= CEntityFlags::AirlineIcaoEntity; entitiesTriggered |= CEntityFlags::AirlineIcaoEntity;
} }
if (entities.testFlag(CEntityFlags::CountryEntity)) if (entities.testFlag(CEntityFlags::CountryEntity))
{ {
QNetworkRequest requestCountry(m_urlCountry); QUrl url(getCountryUrl());
QNetworkRequest requestCountry(url);
CNetworkUtils::ignoreSslVerification(requestCountry);
this->m_networkManagerCountries->get(requestCountry); this->m_networkManagerCountries->get(requestCountry);
entitiesTriggered |= CEntityFlags::CountryEntity; entitiesTriggered |= CEntityFlags::CountryEntity;
} }
@@ -196,12 +198,19 @@ namespace BlackCore
emit dataRead(entitiesTriggered, CEntityFlags::StartRead, 0); emit dataRead(entitiesTriggered, CEntityFlags::StartRead, 0);
} }
CUrl CIcaoDataReader::getBaseUrl() const
{
CUrl baseUrl(this->m_setup.get().dbIcaoReader());
Q_ASSERT_X(!baseUrl.isEmpty(), Q_FUNC_INFO, "No URL");
return baseUrl;
}
void CIcaoDataReader::ps_parseAircraftIcaoData(QNetworkReply *nwReplyPtr) void CIcaoDataReader::ps_parseAircraftIcaoData(QNetworkReply *nwReplyPtr)
{ {
// wrap pointer, make sure any exit cleans up reply // wrap pointer, make sure any exit cleans up reply
// required to use delete later as object is created in a different thread // required to use delete later as object is created in a different thread
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QJsonArray array = this->transformReplyIntoDatastoreResponse(nwReply.data()); QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (array.isEmpty())
{ {
emit dataRead(CEntityFlags::AircraftIcaoEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::AircraftIcaoEntity, CEntityFlags::ReadFailed, 0);
@@ -221,7 +230,7 @@ namespace BlackCore
void CIcaoDataReader::ps_parseAirlineIcaoData(QNetworkReply *nwReplyPtr) void CIcaoDataReader::ps_parseAirlineIcaoData(QNetworkReply *nwReplyPtr)
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QJsonArray array = this->transformReplyIntoDatastoreResponse(nwReply.data()); QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (array.isEmpty())
{ {
emit dataRead(CEntityFlags::AirlineIcaoEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::AirlineIcaoEntity, CEntityFlags::ReadFailed, 0);
@@ -241,7 +250,7 @@ namespace BlackCore
void CIcaoDataReader::ps_parseCountryData(QNetworkReply *nwReplyPtr) void CIcaoDataReader::ps_parseCountryData(QNetworkReply *nwReplyPtr)
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QJsonArray array = this->transformReplyIntoDatastoreResponse(nwReply.data()); QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (array.isEmpty())
{ {
emit dataRead(CEntityFlags::CountryEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::CountryEntity, CEntityFlags::ReadFailed, 0);
@@ -258,15 +267,6 @@ namespace BlackCore
emit dataRead(CEntityFlags::CountryEntity, CEntityFlags::ReadFinished, n); emit dataRead(CEntityFlags::CountryEntity, CEntityFlags::ReadFinished, n);
} }
bool CIcaoDataReader::canConnect(QString &message) const
{
if (m_urlAircraftIcao.isEmpty() || m_urlAirlineIcao.isEmpty()) { return false; }
bool cm = CNetworkUtils::canConnect(m_urlAircraftIcao, message);
// currently only testing one URL, might be changed in the future
return cm;
}
bool CIcaoDataReader::readFromJsonFiles(const QString &dir, CEntityFlags::Entity whatToRead) bool CIcaoDataReader::readFromJsonFiles(const QString &dir, CEntityFlags::Entity whatToRead)
{ {
QDir directory(dir); QDir directory(dir);
@@ -365,19 +365,19 @@ namespace BlackCore
return true; return true;
} }
QString CIcaoDataReader::getAircraftIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl) CUrl CIcaoDataReader::getAircraftIcaoUrl() const
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/jsonaircrafticao.php"); return getBaseUrl().withAppendedPath("service/jsonaircrafticao.php");
} }
QString CIcaoDataReader::getAirlineIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl) CUrl CIcaoDataReader::getAirlineIcaoUrl() const
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/jsonairlineicao.php"); return getBaseUrl().withAppendedPath("service/jsonairlineicao.php");
} }
QString CIcaoDataReader::getCountryUrl(const QString &protocol, const QString &server, const QString &baseUrl) CUrl CIcaoDataReader::getCountryUrl() const
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/jsoncountry.php"); return getBaseUrl().withAppendedPath("service/jsoncountry.php");
} }
} // namespace } // namespace

View File

@@ -14,6 +14,7 @@
#include "blackcore/blackcoreexport.h" #include "blackcore/blackcoreexport.h"
#include "blackcore/databasereader.h" #include "blackcore/databasereader.h"
#include "blackcore/data/globalsetup.h"
#include "blackmisc/countrylist.h" #include "blackmisc/countrylist.h"
#include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/aircrafticaocodelist.h"
#include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/aviation/airlineicaocodelist.h"
@@ -33,7 +34,7 @@ namespace BlackCore
public: public:
//! Constructor //! Constructor
explicit CIcaoDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl); explicit CIcaoDataReader(QObject *owner);
//! Get aircraft ICAO information //! Get aircraft ICAO information
//! \threadsafe //! \threadsafe
@@ -95,12 +96,6 @@ namespace BlackCore
//! \threadsafe //! \threadsafe
bool areAllDataRead() const; bool areAllDataRead() const;
//! Can connect to server?
virtual bool canConnect(QString &message) const override;
//! \copydoc CDatabaseReader::canConnect()
using CDatabaseReader::canConnect;
//! Read from static DB data file //! Read from static DB data file
bool readFromJsonFiles(const QString &dir, BlackMisc::Network::CEntityFlags::Entity whatToRead = BlackMisc::Network::CEntityFlags::AllIcaoAndCountries); bool readFromJsonFiles(const QString &dir, BlackMisc::Network::CEntityFlags::Entity whatToRead = BlackMisc::Network::CEntityFlags::AllIcaoAndCountries);
@@ -128,28 +123,30 @@ namespace BlackCore
void ps_read(BlackMisc::Network::CEntityFlags::Entity entities); void ps_read(BlackMisc::Network::CEntityFlags::Entity entities);
private: private:
QNetworkAccessManager *m_networkManagerAircraft = nullptr; QNetworkAccessManager *m_networkManagerAircraft = nullptr;
QNetworkAccessManager *m_networkManagerAirlines = nullptr; QNetworkAccessManager *m_networkManagerAirlines = nullptr;
QNetworkAccessManager *m_networkManagerCountries = nullptr; QNetworkAccessManager *m_networkManagerCountries = nullptr;
BlackMisc::Aviation::CAircraftIcaoCodeList m_aircraftIcaos; BlackMisc::Aviation::CAircraftIcaoCodeList m_aircraftIcaos;
BlackMisc::Aviation::CAirlineIcaoCodeList m_airlineIcaos; BlackMisc::Aviation::CAirlineIcaoCodeList m_airlineIcaos;
BlackMisc::CCountryList m_countries; BlackMisc::CCountryList m_countries;
QString m_urlAircraftIcao;
QString m_urlAirlineIcao;
QString m_urlCountry;
mutable QReadWriteLock m_lockAirline; mutable QReadWriteLock m_lockAirline;
mutable QReadWriteLock m_lockAircraft; mutable QReadWriteLock m_lockAircraft;
mutable QReadWriteLock m_lockCountry; mutable QReadWriteLock m_lockCountry;
//! URL BlackCore::CData<BlackCore::Data::GlobalSetup> m_setup {this}; //!< setup cache
static QString getAircraftIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl);
//! Base URL
BlackMisc::Network::CUrl getBaseUrl() const;
//! URL //! URL
static QString getAirlineIcaoUrl(const QString &protocol, const QString &server, const QString &baseUrl); BlackMisc::Network::CUrl getAircraftIcaoUrl() const;
//! URL //! URL
static QString getCountryUrl(const QString &protocol, const QString &server, const QString &baseUrl); BlackMisc::Network::CUrl getAirlineIcaoUrl() const;
//! URL
BlackMisc::Network::CUrl getCountryUrl() const;
}; };
} }

View File

@@ -7,9 +7,10 @@
* contained in the LICENSE file. * contained in the LICENSE file.
*/ */
#include "blackcore/setupreader.h"
#include "blackmisc/sequence.h" #include "blackmisc/sequence.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/networkutils.h" #include "blackmisc/network/networkutils.h"
#include "blackmisc/fileutilities.h" #include "blackmisc/fileutilities.h"
#include "modeldatareader.h" #include "modeldatareader.h"
@@ -22,14 +23,12 @@ using namespace BlackMisc;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
using namespace BlackCore::Data;
namespace BlackCore namespace BlackCore
{ {
CModelDataReader::CModelDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl) : CModelDataReader::CModelDataReader(QObject *owner) :
CDatabaseReader(owner, "CModelDataReader"), CDatabaseReader(owner, "CModelDataReader")
m_urlLiveries(getLiveryUrl(protocol, server, baseUrl)),
m_urlDistributors(getDistributorUrl(protocol, server, baseUrl)),
m_urlModels(getModelUrl(protocol, server, baseUrl))
{ {
this->m_networkManagerLivery = new QNetworkAccessManager(this); this->m_networkManagerLivery = new QNetworkAccessManager(this);
this->m_networkManagerDistributor = new QNetworkAccessManager(this); this->m_networkManagerDistributor = new QNetworkAccessManager(this);
@@ -157,42 +156,34 @@ namespace BlackCore
getDistributorsCount() > 0; getDistributorsCount() > 0;
} }
bool CModelDataReader::canConnect(QString &message) const
{
if (m_urlDistributors.isEmpty() || m_urlLiveries.isEmpty() || m_urlModels.isEmpty()) { return false; }
bool cm = CNetworkUtils::canConnect(m_urlModels, message);
// currently only testing one URL, might be changed in the future
return cm;
}
void CModelDataReader::ps_read(CEntityFlags::Entity entity) void CModelDataReader::ps_read(CEntityFlags::Entity entity)
{ {
this->threadAssertCheck(); this->threadAssertCheck();
Q_ASSERT(this->m_networkManagerLivery); Q_ASSERT(this->m_networkManagerLivery);
Q_ASSERT(this->m_networkManagerDistributor); Q_ASSERT(this->m_networkManagerDistributor);
Q_ASSERT(this->m_networkManagerModel); Q_ASSERT(this->m_networkManagerModel);
Q_ASSERT(!m_urlLiveries.isEmpty());
Q_ASSERT(!m_urlDistributors.isEmpty());
CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity; CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity;
if (entity.testFlag(CEntityFlags::LiveryEntity)) if (entity.testFlag(CEntityFlags::LiveryEntity))
{ {
QNetworkRequest requestLivery(m_urlLiveries); QNetworkRequest requestLivery(getLiveryUrl());
CNetworkUtils::ignoreSslVerification(requestLivery);
this->m_networkManagerLivery->get(requestLivery); this->m_networkManagerLivery->get(requestLivery);
triggeredRead |= CEntityFlags::LiveryEntity; triggeredRead |= CEntityFlags::LiveryEntity;
} }
if (entity.testFlag(CEntityFlags::DistributorEntity)) if (entity.testFlag(CEntityFlags::DistributorEntity))
{ {
QNetworkRequest requestDistributor(m_urlDistributors); QNetworkRequest requestDistributor(getDistributorUrl());
CNetworkUtils::ignoreSslVerification(requestDistributor);
this->m_networkManagerDistributor->get(requestDistributor); this->m_networkManagerDistributor->get(requestDistributor);
triggeredRead |= CEntityFlags::DistributorEntity; triggeredRead |= CEntityFlags::DistributorEntity;
} }
if (entity.testFlag(CEntityFlags::ModelEntity)) if (entity.testFlag(CEntityFlags::ModelEntity))
{ {
QNetworkRequest requestModel(m_urlModels); QNetworkRequest requestModel(getModelUrl());
CNetworkUtils::ignoreSslVerification(requestModel);
this->m_networkManagerModel->get(requestModel); this->m_networkManagerModel->get(requestModel);
triggeredRead |= CEntityFlags::ModelEntity; triggeredRead |= CEntityFlags::ModelEntity;
} }
@@ -205,7 +196,7 @@ namespace BlackCore
// wrap pointer, make sure any exit cleans up reply // wrap pointer, make sure any exit cleans up reply
// required to use delete later as object is created in a different thread // required to use delete later as object is created in a different thread
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QJsonArray array = this->transformReplyIntoDatastoreResponse(nwReply.data()); QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (array.isEmpty())
{ {
emit dataRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFailed, 0);
@@ -226,7 +217,7 @@ namespace BlackCore
void CModelDataReader::ps_parseDistributorData(QNetworkReply *nwReplyPtr) void CModelDataReader::ps_parseDistributorData(QNetworkReply *nwReplyPtr)
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QJsonArray array = this->transformReplyIntoDatastoreResponse(nwReply.data()); QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (array.isEmpty())
{ {
emit dataRead(CEntityFlags::DistributorEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::DistributorEntity, CEntityFlags::ReadFailed, 0);
@@ -246,7 +237,7 @@ namespace BlackCore
void CModelDataReader::ps_parseModelData(QNetworkReply *nwReplyPtr) void CModelDataReader::ps_parseModelData(QNetworkReply *nwReplyPtr)
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QJsonArray array = this->transformReplyIntoDatastoreResponse(nwReply.data()); QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (array.isEmpty())
{ {
emit dataRead(CEntityFlags::ModelEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::ModelEntity, CEntityFlags::ReadFailed, 0);
@@ -362,19 +353,26 @@ namespace BlackCore
return true; return true;
} }
QString CModelDataReader::getLiveryUrl(const QString &protocol, const QString &server, const QString &baseUrl) CUrl CModelDataReader::getBaseUrl() const
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/jsonlivery.php"); CUrl baseUrl(m_setup.get().dbModelReader());
Q_ASSERT_X(!baseUrl.isEmpty(), Q_FUNC_INFO, "No URL");
return baseUrl;
} }
QString CModelDataReader::getDistributorUrl(const QString &protocol, const QString &server, const QString &baseUrl) CUrl CModelDataReader::getLiveryUrl() const
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/jsondistributor.php"); return getBaseUrl().withAppendedPath("service/jsonlivery.php");
} }
QString CModelDataReader::getModelUrl(const QString &protocol, const QString &server, const QString &baseUrl) CUrl CModelDataReader::getDistributorUrl() const
{ {
return CNetworkUtils::buildUrl(protocol, server, baseUrl, "service/jsonaircraftmodel.php"); return getBaseUrl().withAppendedPath("service/jsondistributor.php");
}
CUrl CModelDataReader::getModelUrl() const
{
return getBaseUrl().withAppendedPath("service/jsonaircraftmodel.php");
} }
} // namespace } // namespace

View File

@@ -14,6 +14,7 @@
#include "blackcore/blackcoreexport.h" #include "blackcore/blackcoreexport.h"
#include "blackcore/databasereader.h" #include "blackcore/databasereader.h"
#include "blackcore/data/globalsetup.h"
#include "blackmisc/network/webdataservicesprovider.h" #include "blackmisc/network/webdataservicesprovider.h"
#include "blackmisc/aviation/liverylist.h" #include "blackmisc/aviation/liverylist.h"
#include "blackmisc/simulation/distributorlist.h" #include "blackmisc/simulation/distributorlist.h"
@@ -33,7 +34,7 @@ namespace BlackCore
public: public:
//! Constructor //! Constructor
explicit CModelDataReader(QObject *owner, const QString &protocol, const QString &server, const QString &baseUrl); explicit CModelDataReader(QObject *owner);
//! Get aircraft liveries //! Get aircraft liveries
//! \threadsafe //! \threadsafe
@@ -87,13 +88,7 @@ namespace BlackCore
//! \threadsafe //! \threadsafe
bool areAllDataRead() const; bool areAllDataRead() const;
//! Can connect? //! Read to JSON file
virtual bool canConnect(QString &message) const override;
//! \copydoc CDatabaseReader::canConnect()
using CDatabaseReader::canConnect;
//! Write to JSON file
bool readFromJsonFiles(const QString &dir, BlackMisc::Network::CEntityFlags::Entity whatToRead = BlackMisc::Network::CEntityFlags::DistributorLiveryModel); bool readFromJsonFiles(const QString &dir, BlackMisc::Network::CEntityFlags::Entity whatToRead = BlackMisc::Network::CEntityFlags::DistributorLiveryModel);
//! Read from static DB data file //! Read from static DB data file
@@ -126,22 +121,27 @@ namespace BlackCore
BlackMisc::Aviation::CLiveryList m_liveries; BlackMisc::Aviation::CLiveryList m_liveries;
BlackMisc::Simulation::CDistributorList m_distributors; BlackMisc::Simulation::CDistributorList m_distributors;
BlackMisc::Simulation::CAircraftModelList m_models; BlackMisc::Simulation::CAircraftModelList m_models;
QString m_urlLiveries; BlackMisc::Network::CUrl m_urlLiveries;
QString m_urlDistributors; BlackMisc::Network::CUrl m_urlDistributors;
QString m_urlModels; BlackMisc::Network::CUrl m_urlModels;
mutable QReadWriteLock m_lockDistributor; mutable QReadWriteLock m_lockDistributor;
mutable QReadWriteLock m_lockLivery; mutable QReadWriteLock m_lockLivery;
mutable QReadWriteLock m_lockModels; mutable QReadWriteLock m_lockModels;
BlackCore::CData<BlackCore::Data::GlobalSetup> m_setup {this}; //!< setup cache
//! Base URL
BlackMisc::Network::CUrl getBaseUrl() const;
//! URL livery web service //! URL livery web service
static QString getLiveryUrl(const QString &protocol, const QString &server, const QString &baseUrl); BlackMisc::Network::CUrl getLiveryUrl() const;
//! URL distributor web service //! URL distributor web service
static QString getDistributorUrl(const QString &protocol, const QString &server, const QString &baseUrl); BlackMisc::Network::CUrl getDistributorUrl() const;
//! URL model web service //! URL model web service
static QString getModelUrl(const QString &protocol, const QString &server, const QString &baseUrl); BlackMisc::Network::CUrl getModelUrl() const;
}; };
} // ns } // ns

View File

@@ -22,9 +22,8 @@ using namespace BlackMisc::Network;
namespace BlackCore namespace BlackCore
{ {
CVatsimBookingReader::CVatsimBookingReader(QObject *owner, const QString &url) : CVatsimBookingReader::CVatsimBookingReader(QObject *owner) :
CThreadedReader(owner, "CVatsimBookingReader"), CThreadedReader(owner, "CVatsimBookingReader")
m_serviceUrl(url)
{ {
this->m_networkManager = new QNetworkAccessManager(this); this->m_networkManager = new QNetworkAccessManager(this);
this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimBookingReader::ps_parseBookings); this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimBookingReader::ps_parseBookings);
@@ -41,9 +40,10 @@ namespace BlackCore
void CVatsimBookingReader::ps_read() void CVatsimBookingReader::ps_read()
{ {
this->threadAssertCheck(); this->threadAssertCheck();
QUrl url(this->m_serviceUrl); Q_ASSERT_X(this->m_networkManager, Q_FUNC_INFO, "No network manager");
if (url.isEmpty()) return; QUrl url(m_setup.get().vatsimBookings());
Q_ASSERT(this->m_networkManager); if (url.isEmpty()) { return; }
QNetworkRequest request(url); QNetworkRequest request(url);
this->m_networkManager->get(request); this->m_networkManager->get(request);
} }

View File

@@ -13,6 +13,7 @@
#define BLACKCORE_VATSIMBOOKINGREADER_H #define BLACKCORE_VATSIMBOOKINGREADER_H
#include "blackcoreexport.h" #include "blackcoreexport.h"
#include "blackcore/data/globalsetup.h"
#include "blackmisc/threadedreader.h" #include "blackmisc/threadedreader.h"
#include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/atcstationlist.h"
@@ -30,7 +31,7 @@ namespace BlackCore
public: public:
//! Constructor //! Constructor
explicit CVatsimBookingReader(QObject *owner, const QString &url); explicit CVatsimBookingReader(QObject *owner);
//! Read / re-read bookings //! Read / re-read bookings
void readInBackgroundThread(); void readInBackgroundThread();
@@ -51,7 +52,7 @@ namespace BlackCore
void ps_read(); void ps_read();
private: private:
QString m_serviceUrl; //!< URL of the service BlackCore::CData<BlackCore::Data::GlobalSetup> m_setup {this}; //!< setup cache
QNetworkAccessManager *m_networkManager = nullptr; QNetworkAccessManager *m_networkManager = nullptr;
}; };
} }

View File

@@ -11,9 +11,11 @@
#include "blackmisc/aviation/atcstation.h" #include "blackmisc/aviation/atcstation.h"
#include "blackmisc/network/user.h" #include "blackmisc/network/user.h"
#include "blackmisc/network/server.h" #include "blackmisc/network/server.h"
#include "blackmisc/network/urllist.h"
#include "blackmisc/network/entityflags.h" #include "blackmisc/network/entityflags.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "vatsimdatafilereader.h" #include "blackcore/vatsimdatafilereader.h"
#include "blackcore/setupreader.h"
#include <QRegularExpression> #include <QRegularExpression>
@@ -23,12 +25,12 @@ using namespace BlackMisc::Network;
using namespace BlackMisc::Geo; using namespace BlackMisc::Geo;
using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation;
using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::PhysicalQuantities;
using namespace BlackCore::Data;
namespace BlackCore namespace BlackCore
{ {
CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner, const QStringList &urls) : CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner) :
CThreadedReader(owner, "CVatsimDataFileReader"), CThreadedReader(owner, "CVatsimDataFileReader")
m_serviceUrls(urls), m_currentUrlIndex(0)
{ {
this->m_networkManager = new QNetworkAccessManager(this); this->m_networkManager = new QNetworkAccessManager(this);
this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimDataFileReader::ps_parseVatsimFile); this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimDataFileReader::ps_parseVatsimFile);
@@ -150,17 +152,14 @@ namespace BlackCore
void CVatsimDataFileReader::ps_read() void CVatsimDataFileReader::ps_read()
{ {
this->threadAssertCheck(); this->threadAssertCheck();
if (this->m_serviceUrls.isEmpty()) { return; } if (m_setup.get().vatsimDataFile().size() < 1) { return; }
// round robin for load distribution
this->m_currentUrlIndex++;
if (this->m_serviceUrls.size() >= this->m_currentUrlIndex) this->m_currentUrlIndex = 0;
// round robin for load balancing
// remark: Don't use QThread to run network operations in the background // remark: Don't use QThread to run network operations in the background
// see http://qt-project.org/doc/qt-4.7/qnetworkaccessmanager.html // see http://qt-project.org/doc/qt-4.7/qnetworkaccessmanager.html
QUrl url(this->m_serviceUrls.at(this->m_currentUrlIndex)); QUrl url(m_setup.get().vatsimDataFile().getNextUrl());
if (url.isEmpty()) { return; } if (url.isEmpty()) { return; }
Q_ASSERT(this->m_networkManager); Q_ASSERT_X(this->m_networkManager, Q_FUNC_INFO, "Missing network manager");
QNetworkRequest request(url); QNetworkRequest request(url);
this->m_networkManager->get(request); this->m_networkManager->get(request);
} }

View File

@@ -13,6 +13,7 @@
#define BLACKCORE_VATSIMDATAFILEREADER_H #define BLACKCORE_VATSIMDATAFILEREADER_H
#include "blackcoreexport.h" #include "blackcoreexport.h"
#include "blackcore/data/globalsetup.h"
#include "blackmisc/threadedreader.h" #include "blackmisc/threadedreader.h"
#include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/atcstationlist.h"
@@ -35,7 +36,7 @@ namespace BlackCore
public: public:
//! Constructor //! Constructor
explicit CVatsimDataFileReader(QObject *owner, const QStringList &urls); explicit CVatsimDataFileReader(QObject *owner);
//! Get aircraft //! Get aircraft
//! \threadsafe //! \threadsafe
@@ -120,13 +121,12 @@ namespace BlackCore
private: private:
QNetworkAccessManager *m_networkManager = nullptr; QNetworkAccessManager *m_networkManager = nullptr;
QStringList m_serviceUrls; //!< URL of the service
int m_currentUrlIndex;
BlackMisc::Network::CServerList m_voiceServers; BlackMisc::Network::CServerList m_voiceServers;
BlackMisc::Network::CServerList m_fsdServers; BlackMisc::Network::CServerList m_fsdServers;
BlackMisc::Aviation::CAtcStationList m_atcStations; BlackMisc::Aviation::CAtcStationList m_atcStations;
BlackMisc::Simulation::CSimulatedAircraftList m_aircraft; BlackMisc::Simulation::CSimulatedAircraftList m_aircraft;
QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Network::CVoiceCapabilities> m_voiceCapabilities; QMap<BlackMisc::Aviation::CCallsign, BlackMisc::Network::CVoiceCapabilities> m_voiceCapabilities;
BlackCore::CData<BlackCore::Data::GlobalSetup> m_setup {this}; //!< setup cache
//! Split line and assign values to their corresponding attribute names //! Split line and assign values to their corresponding attribute names
static const QMap<QString, QString> clientPartsToMap(const QString &currentLine, const QStringList &clientSectionAttributes); static const QMap<QString, QString> clientPartsToMap(const QString &currentLine, const QStringList &clientSectionAttributes);

View File

@@ -7,7 +7,8 @@
* contained in the LICENSE file. * contained in the LICENSE file.
*/ */
#include "vatsimmetarreader.h" #include "blackcore/setupreader.h"
#include "blackcore/vatsimmetarreader.h"
#include "blackmisc/network/entityflags.h" #include "blackmisc/network/entityflags.h"
#include "blackmisc/sequence.h" #include "blackmisc/sequence.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
@@ -19,12 +20,12 @@
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
using namespace BlackMisc::Weather; using namespace BlackMisc::Weather;
using namespace BlackCore::Data;
namespace BlackCore namespace BlackCore
{ {
CVatsimMetarReader::CVatsimMetarReader(QObject *owner, const QString &url) : CVatsimMetarReader::CVatsimMetarReader(QObject *owner) :
CThreadedReader(owner, "CVatsimMetarReader"), CThreadedReader(owner, "CVatsimMetarReader")
m_metarUrl(url)
{ {
this->m_networkManager = new QNetworkAccessManager(this); this->m_networkManager = new QNetworkAccessManager(this);
this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimMetarReader::ps_decodeMetars); this->connect(this->m_networkManager, &QNetworkAccessManager::finished, this, &CVatsimMetarReader::ps_decodeMetars);
@@ -59,9 +60,9 @@ namespace BlackCore
void CVatsimMetarReader::ps_readMetars() void CVatsimMetarReader::ps_readMetars()
{ {
this->threadAssertCheck(); this->threadAssertCheck();
QUrl url(this->m_metarUrl); QUrl url(m_setup.get().vatsimMetars());
if (url.isEmpty()) return; if (url.isEmpty()) { return; }
Q_ASSERT(this->m_networkManager); Q_ASSERT_X(this->m_networkManager, Q_FUNC_INFO, "No network manager");
QNetworkRequest request(url); QNetworkRequest request(url);
this->m_networkManager->get(request); this->m_networkManager->get(request);
} }
@@ -74,7 +75,7 @@ namespace BlackCore
this->threadAssertCheck(); this->threadAssertCheck();
// Worker thread, make sure to write no members here! // Worker thread, make sure to write thread safe!
if (this->isFinished()) if (this->isFinished())
{ {
CLogMessage(this).debug() << Q_FUNC_INFO; CLogMessage(this).debug() << Q_FUNC_INFO;

View File

@@ -13,6 +13,7 @@
#define BLACKCORE_VATSIMMETARREADER_H #define BLACKCORE_VATSIMMETARREADER_H
#include "blackcoreexport.h" #include "blackcoreexport.h"
#include "blackcore/data/globalsetup.h"
#include "blackmisc/threadedreader.h" #include "blackmisc/threadedreader.h"
#include "blackmisc/weather/metardecoder.h" #include "blackmisc/weather/metardecoder.h"
#include "blackmisc/weather/metarset.h" #include "blackmisc/weather/metarset.h"
@@ -31,7 +32,7 @@ namespace BlackCore
public: public:
//! Constructor //! Constructor
explicit CVatsimMetarReader(QObject *owner, const QString &url); explicit CVatsimMetarReader(QObject *owner);
//! Read / re-read bookings //! Read / re-read bookings
void readInBackgroundThread(); void readInBackgroundThread();
@@ -64,10 +65,10 @@ namespace BlackCore
void ps_readMetars(); void ps_readMetars();
private: private:
QString m_metarUrl; //!< URL of the service
QNetworkAccessManager *m_networkManager = nullptr; QNetworkAccessManager *m_networkManager = nullptr;
BlackMisc::Weather::CMetarDecoder m_metarDecoder; BlackMisc::Weather::CMetarDecoder m_metarDecoder;
BlackMisc::Weather::CMetarSet m_metars; BlackMisc::Weather::CMetarSet m_metars;
BlackCore::CData<BlackCore::Data::GlobalSetup> m_setup {this}; //!< setup cache
}; };
} }
#endif // guard #endif // guard

View File

@@ -7,6 +7,7 @@
* contained in the LICENSE file. * contained in the LICENSE file.
*/ */
#include "blackcore/setupreader.h"
#include "blackcore/webdataservices.h" #include "blackcore/webdataservices.h"
#include "blackcore/modeldatareader.h" #include "blackcore/modeldatareader.h"
#include "blackcore/icaodatareader.h" #include "blackcore/icaodatareader.h"
@@ -14,16 +15,17 @@
#include "blackcore/vatsimbookingreader.h" #include "blackcore/vatsimbookingreader.h"
#include "blackcore/vatsimdatafilereader.h" #include "blackcore/vatsimdatafilereader.h"
#include "blackcore/vatsimmetarreader.h" #include "blackcore/vatsimmetarreader.h"
#include "settings/global_reader_settings.h" #include "data/globalsetup.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blackmisc/fileutilities.h" #include "blackmisc/fileutilities.h"
#include "blackmisc/worker.h" #include "blackmisc/worker.h"
#include "blackmisc/json.h" #include "blackmisc/json.h"
#include "blackmisc/network/networkutils.h"
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
using namespace BlackCore; using namespace BlackCore;
using namespace BlackCore::Settings; using namespace BlackCore::Data;
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
@@ -134,15 +136,17 @@ namespace BlackCore
bool CWebDataServices::canConnectSwiftDb() const bool CWebDataServices::canConnectSwiftDb() const
{ {
if (!m_icaoDataReader && !m_modelDataReader) { return false; } if (!m_icaoDataReader && !m_modelDataReader) { return false; }
// use the first one to test
if (m_icaoDataReader) if (m_icaoDataReader)
{ {
if (!m_icaoDataReader->canConnect()) { return false; } return m_icaoDataReader->canConnect();
} }
if (m_modelDataReader) else if (m_modelDataReader)
{ {
if (!m_modelDataReader->canConnect()) { return false; } return m_modelDataReader->canConnect();
} }
return true; return false;
} }
CEntityFlags::Entity CWebDataServices::triggerRead(CEntityFlags::Entity whatToRead) CEntityFlags::Entity CWebDataServices::triggerRead(CEntityFlags::Entity whatToRead)
@@ -386,7 +390,7 @@ namespace BlackCore
// 1. VATSIM bookings // 1. VATSIM bookings
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimBookingReader)) if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimBookingReader))
{ {
this->m_vatsimBookingReader = new CVatsimBookingReader(this, CGlobalReaderSettings::instance().bookingsUrl()); this->m_vatsimBookingReader = new CVatsimBookingReader(this);
bool c = connect(this->m_vatsimBookingReader, &CVatsimBookingReader::atcBookingsRead, this, &CWebDataServices::ps_receivedBookings); bool c = connect(this->m_vatsimBookingReader, &CVatsimBookingReader::atcBookingsRead, this, &CWebDataServices::ps_receivedBookings);
Q_ASSERT_X(c, Q_FUNC_INFO, "VATSIM booking reader signals"); Q_ASSERT_X(c, Q_FUNC_INFO, "VATSIM booking reader signals");
Q_UNUSED(c); Q_UNUSED(c);
@@ -397,7 +401,7 @@ namespace BlackCore
// 2. VATSIM data file // 2. VATSIM data file
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimDataReader)) if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimDataReader))
{ {
this->m_vatsimDataFileReader = new CVatsimDataFileReader(this, CGlobalReaderSettings::instance().vatsimDataFileUrls()); this->m_vatsimDataFileReader = new CVatsimDataFileReader(this);
bool c = connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataFileRead, this, &CWebDataServices::ps_dataFileRead); bool c = connect(this->m_vatsimDataFileReader, &CVatsimDataFileReader::dataFileRead, this, &CWebDataServices::ps_dataFileRead);
Q_ASSERT_X(c, Q_FUNC_INFO, "VATSIM data reader signals"); Q_ASSERT_X(c, Q_FUNC_INFO, "VATSIM data reader signals");
Q_UNUSED(c); Q_UNUSED(c);
@@ -408,7 +412,7 @@ namespace BlackCore
// 3. VATSIM metar data // 3. VATSIM metar data
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimMetarReader)) if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimMetarReader))
{ {
this->m_vatsimMetarReader = new CVatsimMetarReader(this, CGlobalReaderSettings::instance().urlVatsimMetars()); this->m_vatsimMetarReader = new CVatsimMetarReader(this);
bool c = connect(this->m_vatsimMetarReader, &CVatsimMetarReader::metarsRead, this, &CWebDataServices::ps_receivedMetars); bool c = connect(this->m_vatsimMetarReader, &CVatsimMetarReader::metarsRead, this, &CWebDataServices::ps_receivedMetars);
Q_ASSERT_X(c, Q_FUNC_INFO, "VATSIM METAR reader signals"); Q_ASSERT_X(c, Q_FUNC_INFO, "VATSIM METAR reader signals");
Q_UNUSED(c); Q_UNUSED(c);
@@ -420,7 +424,7 @@ namespace BlackCore
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::IcaoDataReader)) if (flags.testFlag(CWebReaderFlags::WebReaderFlag::IcaoDataReader))
{ {
bool c; bool c;
this->m_icaoDataReader = new CIcaoDataReader(this, CGlobalReaderSettings::instance().protocolIcaoReader(), CGlobalReaderSettings::instance().serverIcaoReader(), CGlobalReaderSettings::instance().baseUrlIcaoReader()); this->m_icaoDataReader = new CIcaoDataReader(this);
c = connect(this->m_icaoDataReader, &CIcaoDataReader::dataRead, this, &CWebDataServices::ps_readFromSwiftDb); c = connect(this->m_icaoDataReader, &CIcaoDataReader::dataRead, this, &CWebDataServices::ps_readFromSwiftDb);
Q_ASSERT_X(c, Q_FUNC_INFO, "ICAO reader signals"); Q_ASSERT_X(c, Q_FUNC_INFO, "ICAO reader signals");
Q_UNUSED(c); Q_UNUSED(c);
@@ -430,7 +434,7 @@ namespace BlackCore
// 5. Model reader // 5. Model reader
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::ModelReader)) if (flags.testFlag(CWebReaderFlags::WebReaderFlag::ModelReader))
{ {
this->m_modelDataReader = new CModelDataReader(this, CGlobalReaderSettings::instance().protocolModelReader(), CGlobalReaderSettings::instance().serverModelReader(), CGlobalReaderSettings::instance().baseUrlModelReader()); this->m_modelDataReader = new CModelDataReader(this);
bool c = connect(this->m_modelDataReader, &CModelDataReader::dataRead, this, &CWebDataServices::ps_readFromSwiftDb); bool c = connect(this->m_modelDataReader, &CModelDataReader::dataRead, this, &CWebDataServices::ps_readFromSwiftDb);
Q_ASSERT_X(c, Q_FUNC_INFO, "Model reader signals"); Q_ASSERT_X(c, Q_FUNC_INFO, "Model reader signals");
Q_UNUSED(c); Q_UNUSED(c);
@@ -441,9 +445,7 @@ namespace BlackCore
void CWebDataServices::initWriters() void CWebDataServices::initWriters()
{ {
this->m_databaseWriter = new CDatabaseWriter( this->m_databaseWriter = new CDatabaseWriter(
CGlobalReaderSettings::instance().protocolModelReader(), m_setup.get().dbModelReader(),
CGlobalReaderSettings::instance().serverModelReader(),
CGlobalReaderSettings::instance().baseUrlModelReader(),
this); this);
} }
@@ -464,8 +466,7 @@ namespace BlackCore
void CWebDataServices::ps_readFromSwiftDb(CEntityFlags::Entity entity, CEntityFlags::ReadState state, int number) void CWebDataServices::ps_readFromSwiftDb(CEntityFlags::Entity entity, CEntityFlags::ReadState state, int number)
{ {
CLogMessage(this).info("Read data %1 %3 %2") << CEntityFlags::flagToString(entity) << number << CEntityFlags::flagToString(state); CLogMessage(this).info("Read data %1 entries: %2 state: %3") << CEntityFlags::flagToString(entity) << number << CEntityFlags::flagToString(state);
// emit readSwiftDbData(entity, state, number);
} }
void CWebDataServices::readAllInBackground(int delayMs) void CWebDataServices::readAllInBackground(int delayMs)
@@ -532,34 +533,20 @@ namespace BlackCore
QDir directory(dir); QDir directory(dir);
if (!directory.exists()) { return false; } if (!directory.exists()) { return false; }
bool s = false;
if (this->m_icaoDataReader) if (this->m_icaoDataReader)
{ {
bool s = false; s = inBackground ?
if (inBackground) this->m_icaoDataReader->readFromJsonFilesInBackground(dir) :
{ this->m_icaoDataReader->readFromJsonFiles(dir);
s = (this->m_icaoDataReader->readFromJsonFilesInBackground(dir) != nullptr);
}
else
{
s = this->m_icaoDataReader->readFromJsonFiles(dir);
}
if (!s) { return false; }
} }
if (this->m_modelDataReader) if (s && this->m_modelDataReader)
{ {
bool s = false; s = inBackground ?
if (inBackground) this->m_modelDataReader->readFromJsonFilesInBackground(dir) :
{ this->m_modelDataReader->readFromJsonFiles(dir);
s = (this->m_modelDataReader->readFromJsonFilesInBackground(dir) != nullptr);
}
else
{
s = this->m_modelDataReader->readFromJsonFiles(dir);
}
if (!s) { return false; }
} }
return s;
return true;
} }
void CWebDataServices::readAtcBookingsInBackground() const void CWebDataServices::readAtcBookingsInBackground() const

View File

@@ -14,6 +14,8 @@
#include "blackcore/blackcoreexport.h" #include "blackcore/blackcoreexport.h"
#include "blackcore/webreaderflags.h" #include "blackcore/webreaderflags.h"
#include "blackcore/setupreader.h"
#include "blackcore/data/globalsetup.h"
#include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/atcstationlist.h"
#include "blackmisc/aviation/liverylist.h" #include "blackmisc/aviation/liverylist.h"
#include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/aviation/airlineicaocodelist.h"
@@ -267,6 +269,7 @@ namespace BlackCore
void initWriters(); void initWriters();
CWebReaderFlags::WebReader m_readerFlags = CWebReaderFlags::WebReaderFlag::None; //!< which readers are available CWebReaderFlags::WebReader m_readerFlags = CWebReaderFlags::WebReaderFlag::None; //!< which readers are available
BlackCore::CData<BlackCore::Data::GlobalSetup> m_setup {this}; //!< setup cache
// for reading XML and VATSIM data files // for reading XML and VATSIM data files
CVatsimBookingReader *m_vatsimBookingReader = nullptr; CVatsimBookingReader *m_vatsimBookingReader = nullptr;
@@ -277,6 +280,9 @@ namespace BlackCore
// writing objects directly into DB // writing objects directly into DB
CDatabaseWriter *m_databaseWriter = nullptr; CDatabaseWriter *m_databaseWriter = nullptr;
// Setup
CSetupReader m_setupReader { this };
}; };
} // namespace } // namespace

View File

@@ -9,6 +9,9 @@
#include "threadedreader.h" #include "threadedreader.h"
using namespace BlackMisc;
using namespace BlackMisc::Network;
namespace BlackMisc namespace BlackMisc
{ {
CThreadedReader::CThreadedReader(QObject *owner, const QString &name) : CThreadedReader::CThreadedReader(QObject *owner, const QString &name) :

View File

@@ -13,6 +13,7 @@
//! \file //! \file
#include "blackmiscexport.h" #include "blackmiscexport.h"
#include "blackmisc/network/urllist.h"
#include "blackmisc/network/entityflags.h" #include "blackmisc/network/entityflags.h"
#include "worker.h" #include "worker.h"
#include <QReadWriteLock> #include <QReadWriteLock>
@@ -63,14 +64,14 @@ namespace BlackMisc
CThreadedReader(QObject *owner, const QString &name); CThreadedReader(QObject *owner, const QString &name);
QTimer *m_updateTimer = nullptr; //!< update timer QTimer *m_updateTimer = nullptr; //!< update timer
bool m_shutdown = false; //!< in shutdown process bool m_shutdown = false; //!< in shutdown process
mutable QReadWriteLock m_lock {QReadWriteLock::Recursive}; //!< lock which can be used from the derived classes mutable QReadWriteLock m_lock {QReadWriteLock::Recursive}; //!< lock which can be used from the derived classes
//! Make sure everthing runs correctly in own thread //! Make sure everthing runs correctly in own thread
void threadAssertCheck() const; void threadAssertCheck() const;
private: private:
QDateTime m_updateTimestamp; //!< when was file / resource read QDateTime m_updateTimestamp; //!< when file/resource was read
}; };
} // namespace } // namespace