diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index fec444a92e..2b3768fe7d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -71,7 +71,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : // TODO: failure case for not receiving a token accountManager.requestAccessToken(username, password); - connect(&accountManager, &AccountManager::receivedAccessToken, this, &DomainServer::requestUUIDFromDataServer); + connect(&accountManager, &AccountManager::receivedAccessToken, this, &DomainServer::requestCreationFromDataServer); } else { qDebug() << "Authentication was requested against" << qPrintable(_nodeAuthenticationURL.toString()) @@ -89,20 +89,22 @@ DomainServer::DomainServer(int argc, char* argv[]) : } } -void DomainServer::requestUUIDFromDataServer() { +void DomainServer::requestCreationFromDataServer() { // this slot is fired when we get a valid access token from the data-server // now let's ask it to set us up with a UUID - AccountManager::getInstance().authenticatedRequest("/api/v1/domains/create", QNetworkAccessManager::PostOperation, - this, SLOT(parseUUIDFromDataServer())); + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "processCreateResponseFromDataServer"; + + AccountManager::getInstance().authenticatedRequest("/api/v1/domains/create", + QNetworkAccessManager::PostOperation, + callbackParams); } -void DomainServer::parseUUIDFromDataServer() { - QNetworkReply* requestReply = reinterpret_cast(sender()); - QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll()); - - if (jsonResponse.object()["status"].toString() == "success") { +void DomainServer::processCreateResponseFromDataServer(const QJsonObject& jsonObject) { + if (jsonObject["status"].toString() == "success") { // pull out the UUID the data-server is telling us to use, and complete our setup with it - QUuid newSessionUUID = QUuid(jsonResponse.object()["data"].toObject()["uuid"].toString()); + QUuid newSessionUUID = QUuid(jsonObject["data"].toObject()["uuid"].toString()); setupNodeListAndAssignments(newSessionUUID); } } @@ -303,7 +305,6 @@ void DomainServer::readAvailableDatagrams() { QByteArray receivedPacket; NodeType_t nodeType; - while (nodeList->getNodeSocket().hasPendingDatagrams()) { receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 51023b6fb4..7a3dac9e0f 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -36,6 +36,8 @@ public slots: /// Called by NodeList to inform us a node has been killed void nodeKilled(SharedNodePointer node); + void processCreateResponseFromDataServer(const QJsonObject& jsonObject); + private: void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid()); @@ -65,8 +67,7 @@ private: QStringList _argumentList; private slots: - void requestUUIDFromDataServer(); - void parseUUIDFromDataServer(); + void requestCreationFromDataServer(); void readAvailableDatagrams(); void addStaticAssignmentsBackToQueueAfterRestart(); diff --git a/libraries/shared/src/AccountManager.cpp b/libraries/shared/src/AccountManager.cpp index 2b779ecff1..501c4a6ca5 100644 --- a/libraries/shared/src/AccountManager.cpp +++ b/libraries/shared/src/AccountManager.cpp @@ -32,7 +32,8 @@ const QString ACCOUNT_TOKEN_GROUP = "tokens"; AccountManager::AccountManager() : _rootURL(), _username(), - _networkAccessManager(new QNetworkAccessManager) + _networkAccessManager(new QNetworkAccessManager), + _pendingCallbackMap() { qRegisterMetaType("OAuthAccessToken"); qRegisterMetaTypeStreamOperators("OAuthAccessToken"); @@ -53,9 +54,7 @@ AccountManager::AccountManager() : } void AccountManager::authenticatedRequest(const QString& path, QNetworkAccessManager::Operation operation, - const QObject *successReceiver, const char *successMethod, - const QByteArray& dataByteArray, - const QObject* errorReceiver, const char* errorMethod) { + const JSONCallbackParameters& callbackParams, const QByteArray& dataByteArray) { if (_networkAccessManager && hasValidAccessToken()) { QNetworkRequest authenticatedRequest; @@ -82,16 +81,57 @@ void AccountManager::authenticatedRequest(const QString& path, QNetworkAccessMan } if (networkReply) { - // if we ended up firing of a request, hook up to it now - connect(networkReply, SIGNAL(finished()), successReceiver, successMethod); - - if (errorReceiver && errorMethod) { - connect(networkReply, SIGNAL(error()), errorReceiver, errorMethod); + if (!callbackParams.isEmpty()) { + // if we have information for a callback, insert the callbackParams into our local map + _pendingCallbackMap.insert(networkReply, callbackParams); } + + // if we ended up firing of a request, hook up to it now + connect(networkReply, SIGNAL(finished()), this, SLOT(passSuccessToCallback())); + connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)), + this, SLOT(passErrorToCallback(QNetworkReply::NetworkError))); } } } +void AccountManager::passSuccessToCallback() { + QNetworkReply* requestReply = reinterpret_cast(sender()); + QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll()); + + JSONCallbackParameters callbackParams = _pendingCallbackMap.value(requestReply); + + if (callbackParams.jsonCallbackReceiver) { + // invoke the right method on the callback receiver + QMetaObject::invokeMethod(callbackParams.jsonCallbackReceiver, qPrintable(callbackParams.jsonCallbackMethod), + Q_ARG(const QJsonObject&, jsonResponse.object())); + + // remove the related reply-callback group from the map + _pendingCallbackMap.remove(requestReply); + + } else { + qDebug() << "Received JSON response from data-server that has no matching callback."; + qDebug() << jsonResponse; + } +} + +void AccountManager::passErrorToCallback(QNetworkReply::NetworkError errorCode) { + QNetworkReply* requestReply = reinterpret_cast(sender()); + JSONCallbackParameters callbackParams = _pendingCallbackMap.value(requestReply); + + if (callbackParams.errorCallbackReceiver) { + // invoke the right method on the callback receiver + QMetaObject::invokeMethod(callbackParams.errorCallbackReceiver, qPrintable(callbackParams.errorCallbackMethod), + Q_ARG(QNetworkReply::NetworkError, errorCode), + Q_ARG(const QString&, requestReply->errorString())); + + // remove the related reply-callback group from the map + _pendingCallbackMap.remove(requestReply); + } else { + qDebug() << "Received error response from data-server that has no matching callback."; + qDebug() << "Error" << errorCode << "-" << requestReply->errorString(); + } +} + bool AccountManager::hasValidAccessToken() { OAuthAccessToken accessToken = _accessTokens.value(_rootURL); diff --git a/libraries/shared/src/AccountManager.h b/libraries/shared/src/AccountManager.h index 65c4e7f52c..5da13b5560 100644 --- a/libraries/shared/src/AccountManager.h +++ b/libraries/shared/src/AccountManager.h @@ -17,6 +17,20 @@ #include "OAuthAccessToken.h" +class JSONCallbackParameters { +public: + JSONCallbackParameters() : + jsonCallbackReceiver(NULL), jsonCallbackMethod(), + errorCallbackReceiver(NULL), errorCallbackMethod() {}; + + bool isEmpty() const { return jsonCallbackReceiver == NULL && errorCallbackReceiver == NULL; } + + QObject* jsonCallbackReceiver; + QString jsonCallbackMethod; + QObject* errorCallbackReceiver; + QString errorCallbackMethod; +}; + class AccountManager : public QObject { Q_OBJECT public: @@ -25,9 +39,8 @@ public: void authenticatedRequest(const QString& path, QNetworkAccessManager::Operation operation, - const QObject* successReceiver, const char* successMethod, - const QByteArray& dataByteArray = QByteArray(), - const QObject* errorReceiver = 0, const char* errorMethod = NULL); + const JSONCallbackParameters& callbackParams = JSONCallbackParameters(), + const QByteArray& dataByteArray = QByteArray()); void setRootURL(const QUrl& rootURL) { _rootURL = rootURL; } @@ -45,6 +58,9 @@ public slots: signals: void authenticationRequired(); void receivedAccessToken(const QUrl& rootURL); +private slots: + void passSuccessToCallback(); + void passErrorToCallback(QNetworkReply::NetworkError errorCode); private: AccountManager(); AccountManager(AccountManager const& other); // not implemented @@ -53,6 +69,7 @@ private: QUrl _rootURL; QString _username; QNetworkAccessManager* _networkAccessManager; + QMap _pendingCallbackMap; static QMap _accessTokens; }; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index a83f72fba8..0d34f5a92a 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -581,18 +581,19 @@ int NodeList::processDomainServerList(const QByteArray& packet) { return readNodes; } -void NodeList::domainServerAuthReply() { - QNetworkReply* requestReply = reinterpret_cast(sender()); - QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll()); - - _domainInfo.parseAuthInformationFromJsonObject(jsonResponse.object()); +void NodeList::domainServerAuthReply(const QJsonObject& jsonObject) { + _domainInfo.parseAuthInformationFromJsonObject(jsonObject); } void NodeList::requestAuthForDomainServer() { + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "domainServerAuthReply"; + AccountManager::getInstance().authenticatedRequest("/api/v1/domains/" + uuidStringWithoutCurlyBraces(_domainInfo.getUUID()) + "/auth.json", QNetworkAccessManager::GetOperation, - this, SLOT(domainServerAuthReply())); + callbackParams); } void NodeList::processDomainServerAuthRequest(const QByteArray& packet) { diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index fb59e20ad6..855da13aa3 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -131,7 +131,7 @@ signals: void nodeAdded(SharedNodePointer); void nodeKilled(SharedNodePointer); private slots: - void domainServerAuthReply(); + void domainServerAuthReply(const QJsonObject& jsonObject); private: static NodeList* _sharedInstance;