void Session::queryOnResult(InboundPkt &inboundPkt, qint64 msgId) { qCDebug(TG_CORE_SESSION) << "result for query" << QString::number(msgId, 16); qint32 op = inboundPkt.prefetchInt(); qint32 *inPtr = 0; qint32 *inEnd = 0; if (op == (qint32)TL_GZipPacked) { inboundPkt.fetchInt(); qint32 l = inboundPkt.prefetchStrlen(); char *s = inboundPkt.fetchStr(l); static qint32 packedBuffer[MAX_PACKED_SIZE / 4]; qint32 totalOut = Utils::tinflate (s, l, packedBuffer, MAX_PACKED_SIZE); inPtr = inboundPkt.inPtr(); inEnd = inboundPkt.inEnd(); inboundPkt.setInPtr(packedBuffer); inboundPkt.setInEnd(inboundPkt.inPtr() + totalOut / 4); qCDebug(TG_CORE_SESSION) << "unzipped data"; } Query *q = m_pendingQueries.take(msgId); if (!q) { qCWarning(TG_CORE_SESSION) << "No such query"; inboundPkt.setInPtr(inboundPkt.inEnd()); } else { qCDebug(TG_CORE_SESSION) << "acked query with msgId" << QString::number(msgId, 16) << ",pendingQueries:" << m_pendingQueries.size(); q->setAcked(true); Q_EMIT resultReceived(q, inboundPkt); } if (inPtr) { inboundPkt.setInPtr(inPtr); inboundPkt.setInEnd(inEnd); } }
// -------------------------------------------------------------------------- QList<QVariantMap> qMidasAPI::synchronousQuery( bool &ok, const QString& midasUrl,const QString& method, const ParametersType& parameters, int maxWaitingTimeInMSecs) { qMidasAPI midasAPI; midasAPI.setMidasUrl(midasUrl); midasAPI.setTimeOut(maxWaitingTimeInMSecs); midasAPI.query(method, parameters); qMidasAPIResult queryResult; QObject::connect(&midasAPI, SIGNAL(resultReceived(QUuid,QList<QVariantMap>)), &queryResult, SLOT(setResult(QUuid,QList<QVariantMap>))); QObject::connect(&midasAPI, SIGNAL(errorReceived(QString)), &queryResult, SLOT(setError(QString))); QEventLoop eventLoop; QObject::connect(&midasAPI, SIGNAL(resultReceived(QUuid,QList<QVariantMap>)), &eventLoop, SLOT(quit())); // Time out will fire an error which will quit the event loop. QObject::connect(&midasAPI, SIGNAL(errorReceived(QString)), &eventLoop, SLOT(quit())); eventLoop.exec(); ok = queryResult.Error.isNull(); if (!ok) { QVariantMap map; map["queryError"] = queryResult.Error; queryResult.Result.push_front(map); } if (queryResult.Result.count() == 0) { // \tbd Q_ASSERT(queryResult.Result.count()); QVariantMap map; map["queryError"] = tr("Unknown error"); queryResult.Result.push_front(map); } return queryResult.Result; }
bool Client::connectToServer(const QString &serverName) { if (!m_jsonRpcClient) { m_jsonRpcClient = new JsonRpcClient(this); connect(m_jsonRpcClient, SIGNAL(resultReceived(QJsonObject)), SLOT(processResult(QJsonObject))); connect(m_jsonRpcClient, SIGNAL(notificationReceived(QJsonObject)), SLOT(processNotification(QJsonObject))); connect(m_jsonRpcClient, SIGNAL(errorReceived(QJsonObject)), SLOT(processError(QJsonObject))); connect(m_jsonRpcClient, SIGNAL(connectionStateChanged()), SIGNAL(connectionStateChanged())); } return m_jsonRpcClient->connectToServer(serverName); }
bool RpcHandlerStrategy::openFile(const QString &fileName, const QString &workDir) { Q_UNUSED(workDir); m_error.clear(); QEventLoop loop; JsonRpcClient client; if (!client.connectToServer(m_rpcServer)) { m_error = Logger::tr("Unable to connect to RPC server at '%1'.") .arg(m_rpcServer); return false; } QObject::connect(&client, SIGNAL(resultReceived(QJsonObject)), &loop, SLOT(quit())); QTimer timer; timer.setSingleShot(true); QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); QJsonObject req(client.emptyRequest()); req["method"] = m_rpcMethod; QJsonObject params; params["fileName"] = fileName; req["params"] = params; if (!client.sendRequest(req)) { m_error = Logger::tr("Cannot send request to RPC server at '%1'") .arg(m_rpcServer); return false; } timer.start(3000); loop.exec(); if (!timer.isActive()) { m_error = Logger::tr("Timeout waiting for a reply from RPC server '%1'") .arg(m_rpcServer); return false; } return true; }
// -------------------------------------------------------------------------- void qMidasAPIPrivate::processReply(QNetworkReply* reply) { Q_Q(qMidasAPI); QUuid uuid(reply->property("uuid").toString()); if (reply->error() != QNetworkReply::NoError) { q->emit errorReceived(uuid.toString() + ": " + reply->error() + ": " + reply->errorString()); } QScriptValue scriptResult = this->ScriptEngine.evaluate("(" + QString(reply->readAll()) + ")"); q->emit infoReceived(QString("Parse results for ") + uuid); QList<QVariantMap> result = this->parseResult(scriptResult); q->emit infoReceived(QString("Results for ") + uuid.toString() + ": " + q->qVariantMapListToString(result)); q->emit resultReceived(uuid, result); reply->close(); reply->deleteLater(); }
// -------------------------------------------------------------------------- int qMidasAPITest(int argc, char* argv[]) { QCoreApplication app(argc, argv); bool ok = false; QList<QVariantMap> result; // -------------------------------------------------------------------------- // Check that query associated with local file release file handle // -------------------------------------------------------------------------- QDir tmp = QDir::temp(); QString temporaryDirName = QString("qMidasAPITest1-queryFile.%1").arg(QTime::currentTime().toString("hhmmsszzz")); tmp.mkdir(temporaryDirName); tmp.cd(temporaryDirName); tmp.mkdir("api"); tmp.cd("api"); QFile fileReply(tmp.filePath("json")); if (!fileReply.open(QFile::WriteOnly)) { std::cerr << "Line " << __LINE__ << " - Failed to create temporary file." << qPrintable(tmp.filePath("json")) << std::endl; return EXIT_FAILURE; } fileReply.write( QString("{\"stat\":\"ok\",\"code\":\"0\",\"message\":\"\",\"data\":{" "\"quote\":\"If a day goes past and you do not learn anything, it is a waste of a day.\"," "\"author\" : \"Mike Horn\"}}").toLatin1()); fileReply.close(); ok = false; result = qMidasAPI::synchronousQuery(ok, QUrl::fromLocalFile(QDir::temp().filePath(temporaryDirName)).toString(), "midas.quote.of.the.day"); std::cout << "result: " << qPrintable(qMidasAPI::qVariantMapListToString(result)) << std::endl; if (!ok || result.size() == 0) { std::cout << "Failed to query 'midas.quote.of.the.day'." << std::endl; return EXIT_FAILURE; } // Attempt to delete 'queryFile' if (!QFile::remove(tmp.filePath("json"))) { std::cout << "Failed to remove queryFile. [" << qPrintable(tmp.filePath("json")) << "]" << std::endl; return EXIT_FAILURE; } // -------------------------------------------------------------------------- QString midasUrl("http://slicer.kitware.com/midas3"); qMidasAPI midasAPI; midasAPI.setMidasUrl(midasUrl); if (midasAPI.midasUrl() != midasUrl) { std::cout << "Failed to set Midas Url" << std::endl; return EXIT_FAILURE; } // -------------------------------------------------------------------------- // Successfull query: midas.version // -------------------------------------------------------------------------- QSignalSpy errorSpy(&midasAPI, SIGNAL(errorReceived(QUuid,QString))); QSignalSpy receivedSpy(&midasAPI, SIGNAL(resultReceived(QUuid,QList<QVariantMap>))); QUuid queryUuid = midasAPI.get("midas.version"); // Give 5 seconds for the server to answer wait(5000); if (queryUuid.isNull() || errorSpy.count() > 0|| receivedSpy.count() != 1) { std::cerr << "Failed to query 'midas.version': " << errorSpy.count() << " errors," << receivedSpy.count() << " results." << std::endl; return EXIT_FAILURE; } errorSpy.clear(); receivedSpy.clear(); // -------------------------------------------------------------------------- // Fail query: midas.notafunction // -------------------------------------------------------------------------- queryUuid = midasAPI.get("midas.notafunction"); // Give 5 seconds for the server to answer wait(5000); /// Even if errors are received, an empty result is sent if (queryUuid.isNull() || errorSpy.count() == 0 || receivedSpy.count() != 1) { std::cerr << "Failed to query 'midas.notafunction': " << errorSpy.count() << " errors," << receivedSpy.count() << " results." << std::endl; return EXIT_FAILURE; } // -------------------------------------------------------------------------- // Synchronous query: midas.info // -------------------------------------------------------------------------- ok = false; result = qMidasAPI::synchronousQuery(ok, midasUrl, "midas.info"); std::cout << "result: " << qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl; if (!ok || result.size() == 0) { std::cout << "Failed to query 'midas.info'." << std::endl; return EXIT_FAILURE; } // -------------------------------------------------------------------------- // Synchronous fail query: midas.notafunction // -------------------------------------------------------------------------- result= qMidasAPI::synchronousQuery(ok, midasUrl,"midas.notafunction"); std::cout << "result: " << qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl; if (ok || result.size() != 1 || result.at(0)["queryError"].isNull()) { std::cout << "Failed to query 'midas.info'." << result.size() << " results." << std::endl; return EXIT_FAILURE; } // -------------------------------------------------------------------------- // Synchronous fail query: midas.login (wrong credentials) // -------------------------------------------------------------------------- qMidasAPI::ParametersType wrongParameters; wrongParameters["appname"] = "qMidasAPITest"; wrongParameters["email"] = "*****@*****.**"; wrongParameters["apikey"] = "123456789"; result= qMidasAPI::synchronousQuery(ok, midasUrl,"midas.login", wrongParameters); std::cout << "result: " << qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl; if (ok || result.size() != 1 || result.at(0)["queryError"].isNull()) { std::cout << "Failed to query 'midas.login'." << result.size() << " results." << std::endl; return EXIT_FAILURE; } // -------------------------------------------------------------------------- // Synchronous query: midas.community.list (return array of data) // -------------------------------------------------------------------------- result= qMidasAPI::synchronousQuery(ok, midasUrl,"midas.community.list"); std::cout << "result: " << qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl; if (!ok || result.size() == 0) { std::cout << "Failed to query 'midas.community.list'." << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }