forked from qt-creator/qt-creator
Axivion: Begin to use QNetworkAccessManager instead of curl for HTTP
Change-Id: I2fd7ba2a72e749bdc5407d222057cb66ff341b04 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -13,4 +13,5 @@ add_qtc_plugin(Axivion
|
||||
axiviontr.h
|
||||
dashboard/dto.cpp dashboard/dto.h
|
||||
dashboard/concat.cpp dashboard/concat.h
|
||||
dashboard/dashboardclient.cpp dashboard/dashboardclient.h
|
||||
)
|
||||
|
@@ -26,6 +26,8 @@ QtcPlugin {
|
||||
"axivionsettings.cpp",
|
||||
"axivionsettings.h",
|
||||
"axiviontr.h",
|
||||
"dashboard/dashboardclient.cpp",
|
||||
"dashboard/dashboardclient.h",
|
||||
]
|
||||
|
||||
cpp.includePaths: base.concat(["."]) // needed for the generated stuff below
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "axivionquery.h"
|
||||
#include "axivionresultparser.h"
|
||||
#include "axiviontr.h"
|
||||
#include "dashboard/dashboardclient.h"
|
||||
#include "dashboard/dto.h"
|
||||
|
||||
#include <coreplugin/editormanager/documentmodel.h>
|
||||
@@ -26,10 +27,12 @@
|
||||
#include <texteditor/textmark.h>
|
||||
|
||||
#include <utils/expected.h>
|
||||
#include <utils/networkaccessmanager.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QFutureWatcher>
|
||||
#include <QTimer>
|
||||
|
||||
#include <exception>
|
||||
@@ -44,7 +47,7 @@ class AxivionPluginPrivate : public QObject
|
||||
public:
|
||||
void onStartupProjectChanged();
|
||||
void fetchProjectInfo(const QString &projectName);
|
||||
void handleProjectInfo(const QByteArray &result);
|
||||
void handleProjectInfo(Utils::expected_str<Dto::ProjectInfoDto> rawInfo);
|
||||
void handleOpenedDocs(ProjectExplorer::Project *project);
|
||||
void onDocumentOpened(Core::IDocument *doc);
|
||||
void onDocumentClosed(Core::IDocument * doc);
|
||||
@@ -52,6 +55,7 @@ public:
|
||||
void handleIssuesForFile(const IssuesList &issues);
|
||||
void fetchRuleInfo(const QString &id);
|
||||
|
||||
Utils::NetworkAccessManager *m_networkAccessManager = Utils::NetworkAccessManager::instance();
|
||||
AxivionOutputPane m_axivionOutputPane;
|
||||
std::shared_ptr<const Dto::ProjectInfoDto> m_currentProjectInfo;
|
||||
bool m_runningQuery = false;
|
||||
@@ -151,14 +155,16 @@ void AxivionPluginPrivate::fetchProjectInfo(const QString &projectName)
|
||||
return;
|
||||
}
|
||||
m_runningQuery = true;
|
||||
|
||||
AxivionQuery query(AxivionQuery::ProjectInfo, {projectName});
|
||||
AxivionQueryRunner *runner = new AxivionQueryRunner(query, this);
|
||||
connect(runner, &AxivionQueryRunner::resultRetrieved, this, [this](const QByteArray &result){
|
||||
handleProjectInfo(result);
|
||||
});
|
||||
connect(runner, &AxivionQueryRunner::finished, [runner]{ runner->deleteLater(); });
|
||||
runner->start();
|
||||
DashboardClient client { *this->m_networkAccessManager };
|
||||
QFuture<DashboardClient::RawProjectInfo> response = client.fetchProjectInfo(projectName);
|
||||
auto responseWatcher = std::make_shared<QFutureWatcher<DashboardClient::RawProjectInfo>>();
|
||||
connect(responseWatcher.get(),
|
||||
&QFutureWatcher<DashboardClient::RawProjectInfo>::finished,
|
||||
this,
|
||||
[this, responseWatcher]() {
|
||||
handleProjectInfo(responseWatcher->result());
|
||||
});
|
||||
responseWatcher->setFuture(response);
|
||||
}
|
||||
|
||||
void AxivionPluginPrivate::fetchRuleInfo(const QString &id)
|
||||
@@ -201,15 +207,14 @@ void AxivionPluginPrivate::clearAllMarks()
|
||||
onDocumentClosed(doc);
|
||||
}
|
||||
|
||||
void AxivionPluginPrivate::handleProjectInfo(const QByteArray &result)
|
||||
void AxivionPluginPrivate::handleProjectInfo(Utils::expected_str<Dto::ProjectInfoDto> rawInfo)
|
||||
{
|
||||
Utils::expected_str<Dto::ProjectInfoDto> raw_info = ResultParser::parseProjectInfo(result);
|
||||
m_runningQuery = false;
|
||||
if (!raw_info) {
|
||||
Core::MessageManager::writeFlashing(QStringLiteral(u"Axivion: ") + raw_info.error());
|
||||
if (!rawInfo) {
|
||||
Core::MessageManager::writeFlashing(QStringLiteral(u"Axivion: ") + rawInfo.error());
|
||||
return;
|
||||
}
|
||||
m_currentProjectInfo = std::make_shared<const Dto::ProjectInfoDto>(std::move(raw_info.value()));
|
||||
m_currentProjectInfo = std::make_shared<const Dto::ProjectInfoDto>(std::move(rawInfo.value()));
|
||||
m_axivionOutputPane.updateDashboard();
|
||||
// handle already opened documents
|
||||
if (auto buildSystem = ProjectExplorer::ProjectManager::startupBuildSystem();
|
||||
|
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "axivionresultparser.h"
|
||||
#include "dashboard/dto.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -120,20 +119,6 @@ DashboardInfo parseDashboardInfo(const QByteArray &input)
|
||||
return result;
|
||||
}
|
||||
|
||||
Utils::expected_str<Dto::ProjectInfoDto> parseProjectInfo(const QByteArray &input)
|
||||
{
|
||||
auto [header, body] = splitHeaderAndBody(input);
|
||||
auto [error, doc] = prehandleHeaderAndBody(header, body);
|
||||
if (!error.error.isEmpty())
|
||||
return tl::make_unexpected(std::move(error.error));
|
||||
try
|
||||
{
|
||||
return { Dto::ProjectInfoDto::deserialize(body) };
|
||||
} catch (const Dto::invalid_dto_exception &e) {
|
||||
return tl::make_unexpected(QString::fromUtf8(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
static QRegularExpression issueCsvLineRegex(const QByteArray &firstCsvLine)
|
||||
{
|
||||
QString pattern = "^";
|
||||
|
88
src/plugins/axivion/dashboard/dashboardclient.cpp
Normal file
88
src/plugins/axivion/dashboard/dashboardclient.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2022-current by Axivion GmbH
|
||||
* https://www.axivion.com/
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
*/
|
||||
|
||||
#include "dashboardclient.h"
|
||||
|
||||
#include "axivionsettings.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCoreApplication>
|
||||
#include <QLatin1String>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Axivion::Internal
|
||||
{
|
||||
|
||||
DashboardClient::DashboardClient(Utils::NetworkAccessManager &networkAccessManager)
|
||||
: m_networkAccessManager(networkAccessManager)
|
||||
{
|
||||
}
|
||||
|
||||
static void deleteLater(QObject *obj)
|
||||
{
|
||||
obj->deleteLater();
|
||||
}
|
||||
|
||||
using RawBody = Utils::expected_str<QByteArray>;
|
||||
|
||||
class RawBodyReader final
|
||||
{
|
||||
public:
|
||||
RawBodyReader(std::shared_ptr<QNetworkReply> reply)
|
||||
: m_reply(std::move(reply))
|
||||
{ }
|
||||
|
||||
~RawBodyReader() { }
|
||||
|
||||
RawBody operator()()
|
||||
{
|
||||
QNetworkReply::NetworkError error = m_reply->error();
|
||||
if (error != QNetworkReply::NetworkError::NoError)
|
||||
return tl::make_unexpected(QString::number(error)
|
||||
+ QLatin1String(": ")
|
||||
+ m_reply->errorString());
|
||||
return m_reply->readAll();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<QNetworkReply> m_reply;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static Utils::expected_str<T> RawBodyParser(RawBody rawBody)
|
||||
{
|
||||
if (!rawBody)
|
||||
return tl::make_unexpected(std::move(rawBody.error()));
|
||||
try {
|
||||
return { T::deserialize(rawBody.value()) };
|
||||
} catch (const Dto::invalid_dto_exception &e) {
|
||||
return tl::make_unexpected(QString::fromUtf8(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
QFuture<DashboardClient::RawProjectInfo> DashboardClient::fetchProjectInfo(const QString &projectName)
|
||||
{
|
||||
const AxivionServer &server = settings().server;
|
||||
QUrl url { server.dashboard + QStringLiteral(u"/api/projects/") + QUrl::toPercentEncoding(projectName) };
|
||||
QNetworkRequest request{ url };
|
||||
request.setRawHeader(QByteArrayLiteral(u8"Authorization"),
|
||||
QByteArrayLiteral(u8"AxToken ") + server.token.toUtf8());
|
||||
QByteArray ua = QByteArrayLiteral(u8"Axivion")
|
||||
+ QCoreApplication::applicationName().toUtf8()
|
||||
+ QByteArrayLiteral(u8"Plugin/")
|
||||
+ QCoreApplication::applicationVersion().toUtf8();
|
||||
request.setRawHeader(QByteArrayLiteral(u8"X-Axivion-User-Agent"), ua);
|
||||
std::shared_ptr<QNetworkReply> reply{ this->m_networkAccessManager.get(request), deleteLater };
|
||||
return QtFuture::connect(reply.get(), &QNetworkReply::finished)
|
||||
.then(RawBodyReader(reply))
|
||||
.then(QtFuture::Launch::Async, &RawBodyParser<Dto::ProjectInfoDto>);
|
||||
}
|
||||
|
||||
}
|
33
src/plugins/axivion/dashboard/dashboardclient.h
Normal file
33
src/plugins/axivion/dashboard/dashboardclient.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022-current by Axivion GmbH
|
||||
* https://www.axivion.com/
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
*/
|
||||
|
||||
#include "dashboard/dto.h"
|
||||
|
||||
#include <utils/expected.h>
|
||||
#include <utils/networkaccessmanager.h>
|
||||
|
||||
#include <QFuture>
|
||||
|
||||
namespace Axivion::Internal
|
||||
{
|
||||
|
||||
class DashboardClient
|
||||
{
|
||||
public:
|
||||
using RawProjectInfo = Utils::expected_str<Dto::ProjectInfoDto>;
|
||||
|
||||
DashboardClient(Utils::NetworkAccessManager &networkAccessManager);
|
||||
|
||||
QFuture<RawProjectInfo> fetchProjectInfo(const QString &projectName);
|
||||
|
||||
private:
|
||||
Utils::NetworkAccessManager &m_networkAccessManager;
|
||||
};
|
||||
|
||||
} // namespace Axivion::Internal
|
Reference in New Issue
Block a user