Move host URI option to QGrpcHttp2Channel

The host URI is not an optional property of the QGrpcHttp2Channel and
has not relations to QGrpcChannelOptions. We should move it to the
QGrpcHttp2Channel and use it there directly instead of making the
assumption that any channel should be created using the host URI. This
also removes the requirement of having the options as mandatory
argument to construct the gRPC channels.

Task-number: QTBUG-123625
Change-Id: I6cd64bad6c379f8875dcd6794a95bf68b46da605
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Alexey Edelev 2024-05-07 20:00:38 +02:00
parent f84bd17c9c
commit 2625537aee
23 changed files with 201 additions and 172 deletions

View File

@ -45,14 +45,14 @@ void SimpleChatEngine::login(const QString &name, const QString &password)
QUrl url("http://localhost:65002");
// ![0]
QGrpcChannelOptions channelOptions(url);
QGrpcChannelOptions channelOptions;
QGrpcMetadata metadata = {
{ "user-name", { name.toUtf8() } },
{ "user-password", { password.toUtf8() } },
};
channelOptions.setMetadata(metadata);
std::shared_ptr<QAbstractGrpcChannel> channel = std::make_shared<QGrpcHttp2Channel>(
channelOptions);
std::shared_ptr<QAbstractGrpcChannel>
channel = std::make_shared<QGrpcHttp2Channel>(url, channelOptions);
// ![0]
m_client->attachChannel(channel);

View File

@ -21,8 +21,8 @@ void NaviThread::run()
{
if (!m_client) {
auto channel = std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) }));
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("http://localhost:50051",
QUrl::StrictMode)));
m_client = std::make_shared<qtgrpc::examples::NaviService::Client>();
m_client->attachChannel(channel);
}

View File

@ -22,8 +22,8 @@ void VehicleThread::run()
{
if (!m_client) {
auto channel = std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) }));
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("http://localhost:50051",
QUrl::StrictMode)));
m_client = std::make_shared<qtgrpc::examples::VehicleService::Client>();
m_client->attachChannel(channel);
}

View File

@ -101,6 +101,11 @@ deadlineForCall(const QGrpcChannelOptions &channelOptions, const QGrpcCallOption
return std::nullopt;
}
QAbstractGrpcChannel::QAbstractGrpcChannel()
: dPtr(std::make_unique<QAbstractGrpcChannelPrivate>(QGrpcChannelOptions{}))
{
}
QAbstractGrpcChannel::QAbstractGrpcChannel(const QGrpcChannelOptions &options)
: dPtr(std::make_unique<QAbstractGrpcChannelPrivate>(options))
{

View File

@ -60,6 +60,7 @@ protected:
[[nodiscard]] const QGrpcChannelOptions &channelOptions() const & noexcept;
friend class QGrpcClientBase;
QAbstractGrpcChannel();
explicit QAbstractGrpcChannel(const QGrpcChannelOptions &options);
private:

View File

@ -24,12 +24,8 @@ using namespace Qt::StringLiterals;
class QGrpcChannelOptionsPrivate
{
public:
QGrpcChannelOptionsPrivate(const QUrl &_host)
: host(_host), serializationFormat(QGrpcSerializationFormat::Format::Default)
{
}
QGrpcChannelOptionsPrivate() : serializationFormat(QGrpcSerializationFormat::Default) { }
QUrl host;
std::optional<QGrpcDuration> deadline;
QGrpcMetadata metadata;
QGrpcSerializationFormat serializationFormat;
@ -39,10 +35,9 @@ public:
};
/*!
Constructs an QGrpcChannelOptions object with \a host value.
Constructs a QGrpcChannelOptions.
*/
QGrpcChannelOptions::QGrpcChannelOptions(const QUrl &host)
: dPtr(std::make_unique<QGrpcChannelOptionsPrivate>(host))
QGrpcChannelOptions::QGrpcChannelOptions() : dPtr(std::make_unique<QGrpcChannelOptionsPrivate>())
{
}
@ -81,15 +76,6 @@ QGrpcChannelOptions &QGrpcChannelOptions::operator=(QGrpcChannelOptions &&other)
*/
QGrpcChannelOptions::~QGrpcChannelOptions() = default;
/*!
Sets host value with \a host and returns updated QGrpcChannelOptions object.
*/
QGrpcChannelOptions &QGrpcChannelOptions::setHost(const QUrl &host)
{
dPtr->host = host;
return *this;
}
/*!
Sets deadline value with \a deadline and returns updated QGrpcChannelOptions object.
*/
@ -148,14 +134,6 @@ std::optional<QGrpcDuration> QGrpcChannelOptions::deadline() const noexcept
return dPtr->deadline;
}
/*!
Returns host value for the channel.
*/
QUrl QGrpcChannelOptions::host() const noexcept
{
return dPtr->host;
}
/*!
\fn const QGrpcMetadata &QGrpcChannelOptions::metadata() const & noexcept
\fn QGrpcMetadata QGrpcChannelOptions::metadata() && noexcept
@ -224,8 +202,8 @@ QDebug operator<<(QDebug debug, const QGrpcChannelOptions &chOpts)
QDebugStateSaver save(debug);
debug.nospace();
debug.noquote();
debug << "QGrpcChannelOptions(host: " << chOpts.host()
<< ", deadline: " << chOpts.deadline() << ", metadata: " << chOpts.metadata()
debug << "QGrpcChannelOptions(deadline: " << chOpts.deadline()
<< ", metadata: " << chOpts.metadata()
<< ", serializationFormat: " << chOpts.serializationFormat().suffix()
<< ", sslConfiguration: ";
# if QT_CONFIG(ssl)

View File

@ -23,7 +23,7 @@ class QGrpcChannelOptionsPrivate;
class Q_GRPC_EXPORT QGrpcChannelOptions final
{
public:
explicit QGrpcChannelOptions(const QUrl &host);
QGrpcChannelOptions();
~QGrpcChannelOptions();
QGrpcChannelOptions(const QGrpcChannelOptions &other);
@ -31,13 +31,11 @@ public:
QGrpcChannelOptions(QGrpcChannelOptions &&other) noexcept;
QGrpcChannelOptions &operator=(QGrpcChannelOptions &&other) noexcept;
QGrpcChannelOptions &setHost(const QUrl &host);
QGrpcChannelOptions &setDeadline(QGrpcDuration deadline);
QGrpcChannelOptions &setMetadata(const QGrpcMetadata &metadata);
QGrpcChannelOptions &setMetadata(QGrpcMetadata &&metadata);
QGrpcChannelOptions &setSerializationFormat(const QGrpcSerializationFormat &format);
[[nodiscard]] QUrl host() const noexcept;
[[nodiscard]] std::optional<QGrpcDuration> deadline() const noexcept;
[[nodiscard]] const QGrpcMetadata &metadata() const & noexcept;
[[nodiscard]] QGrpcMetadata metadata() && noexcept;

View File

@ -61,7 +61,7 @@ using namespace Qt::StringLiterals;
\code
auto channelJson = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{ QUrl("http://localhost:50051", QUrl::StrictMode) }
.setMetadata({ { "content-type"_ba,
.withMetadata({ { "content-type"_ba,
"application/grpc+json"_ba } }));
\endcode
@ -72,7 +72,7 @@ using namespace Qt::StringLiterals;
...
};
auto channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{ QUrl("http://localhost:50051", QUrl::StrictMode) }
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode), QGrpcChannelOptions{}
.setSerializationFormat(QGrpcSerializationFormat{ "dummy",
std::make_shared<DummySerializer>() }));
\endcode
@ -117,12 +117,13 @@ struct QGrpcHttp2ChannelPrivate : public QObject
{
Q_OBJECT
public:
explicit QGrpcHttp2ChannelPrivate(const QGrpcChannelOptions &options);
explicit QGrpcHttp2ChannelPrivate(const QUrl &uri, const QGrpcChannelOptions &options);
~QGrpcHttp2ChannelPrivate() override;
void processOperation(const std::shared_ptr<QGrpcChannelOperation> &channelOperation,
bool endStream = false);
std::shared_ptr<QAbstractProtobufSerializer> serializer;
QUrl hostUri;
QGrpcChannelOptions channelOptions;
private:
@ -406,11 +407,11 @@ void QGrpcHttp2ChannelPrivate::Http2Handler::prepareInitialRequest(QGrpcChannelO
QByteArray service{ channelOperation->service().data(), channelOperation->service().size() };
QByteArray method{ channelOperation->method().data(), channelOperation->method().size() };
m_initialHeaders = HPack::HttpHeader{
{AuthorityHeader.toByteArray(), channelOptions.host().host().toLatin1() },
{AuthorityHeader.toByteArray(), channel->hostUri.host().toLatin1() },
{ MethodHeader.toByteArray(), "POST"_ba },
{ PathHeader.toByteArray(), QByteArray('/' + service + '/' + method)},
{ SchemeHeader.toByteArray(),
channel->m_isLocalSocket ? "http"_ba : channelOptions.host().scheme().toLatin1() },
channel->m_isLocalSocket ? "http"_ba : channel->hostUri.scheme().toLatin1() },
{ ContentTypeHeader.toByteArray(), channel->m_contentType },
{ GrpcServiceNameHeader.toByteArray(), { service } },
{ GrpcAcceptEncodingHeader.toByteArray(), "identity,deflate,gzip"_ba },
@ -540,8 +541,9 @@ void QGrpcHttp2ChannelPrivate::Http2Handler::finish()
const std::unordered_map<quint32, QGrpcStatus::StatusCode> QGrpcHttp2ChannelPrivate::StatusCodeMap;
QGrpcHttp2ChannelPrivate::QGrpcHttp2ChannelPrivate(const QGrpcChannelOptions &options)
: channelOptions(options)
QGrpcHttp2ChannelPrivate::QGrpcHttp2ChannelPrivate(const QUrl &uri,
const QGrpcChannelOptions &options)
: hostUri(uri), channelOptions(options)
{
// Populate the map on first use of this constructor.
[[maybe_unused]] static bool statusCodeMapInitialized = []() -> bool {
@ -629,30 +631,29 @@ QGrpcHttp2ChannelPrivate::QGrpcHttp2ChannelPrivate(const QGrpcChannelOptions &op
QString::fromLatin1(it->second));
}
QUrl url = channelOptions.host();
if (url.scheme() == "unix"_L1) {
if (hostUri.scheme() == "unix"_L1) {
auto *localSocket = initSocket<QLocalSocket>();
m_isLocalSocket = true;
QObject::connect(localSocket, &QLocalSocket::connected, this,
&QGrpcHttp2ChannelPrivate::createHttp2Connection);
QObject::connect(localSocket, &QLocalSocket::errorOccurred, this,
[this, url](QLocalSocket::LocalSocketError error) {
[this](QLocalSocket::LocalSocketError error) {
qGrpcDebug()
<< "Error occurred(" << error << "):"
<< static_cast<QLocalSocket *>(m_socket.get())->errorString()
<< url;
<< hostUri;
handleSocketError();
});
m_reconnectFunction = [localSocket, url] {
localSocket->connectToServer(url.host() + url.path());
m_reconnectFunction = [localSocket, this] {
localSocket->connectToServer(hostUri.host() + hostUri.path());
};
} else
#if QT_CONFIG(ssl)
if (url.scheme() == "https"_L1 || options.sslConfiguration()) {
if (hostUri.scheme() == "https"_L1 || options.sslConfiguration()) {
auto *sslSocket = initSocket<QSslSocket>();
if (url.port() < 0) {
url.setPort(443);
if (hostUri.port() < 0) {
hostUri.setPort(443);
}
if (options.sslConfiguration())
@ -661,36 +662,36 @@ QGrpcHttp2ChannelPrivate::QGrpcHttp2ChannelPrivate(const QGrpcChannelOptions &op
QObject::connect(sslSocket, &QSslSocket::encrypted, this,
&QGrpcHttp2ChannelPrivate::createHttp2Connection);
QObject::connect(sslSocket, &QAbstractSocket::errorOccurred, this,
[this, url](QAbstractSocket::SocketError error) {
[this](QAbstractSocket::SocketError error) {
qDebug()
<< "Error occurred(" << error << "):"
<< static_cast<QAbstractSocket *>(m_socket.get())->errorString()
<< url;
<< hostUri;
handleSocketError();
});
m_reconnectFunction = [sslSocket, url] {
sslSocket->connectToHostEncrypted(url.host(), static_cast<quint16>(url.port()));
m_reconnectFunction = [sslSocket, this] {
sslSocket->connectToHostEncrypted(hostUri.host(), static_cast<quint16>(hostUri.port()));
};
} else
#endif
{
auto *httpSocket = initSocket<QTcpSocket>();
if (url.port() < 0) {
url.setPort(80);
if (hostUri.port() < 0) {
hostUri.setPort(80);
}
QObject::connect(httpSocket, &QAbstractSocket::connected, this,
&QGrpcHttp2ChannelPrivate::createHttp2Connection);
QObject::connect(httpSocket, &QAbstractSocket::errorOccurred, this,
[this, url](QAbstractSocket::SocketError error) {
[this](QAbstractSocket::SocketError error) {
qGrpcDebug()
<< "Error occurred(" << error << "):"
<< static_cast<QAbstractSocket *>(m_socket.get())->errorString()
<< url;
<< hostUri;
handleSocketError();
});
m_reconnectFunction = [httpSocket, url] {
httpSocket->connectToHost(url.host(), static_cast<quint16>(url.port()));
m_reconnectFunction = [httpSocket, this] {
httpSocket->connectToHost(hostUri.host(), static_cast<quint16>(hostUri.port()));
};
}
m_reconnectFunction();
@ -809,10 +810,20 @@ void QGrpcHttp2ChannelPrivate::deleteHandler(Http2Handler *handler)
}
/*!
Constructs QGrpcHttp2Channel with \a options.
Constructs QGrpcHttp2Channel with \a hostUri.
*/
QGrpcHttp2Channel::QGrpcHttp2Channel(const QGrpcChannelOptions &options)
: QAbstractGrpcChannel(options), dPtr(std::make_unique<QGrpcHttp2ChannelPrivate>(options))
QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &hostUri)
: QAbstractGrpcChannel(),
dPtr(std::make_unique<QGrpcHttp2ChannelPrivate>(hostUri, QGrpcChannelOptions{}))
{
}
/*!
Constructs QGrpcHttp2Channel with \a hostUri and \a options.
*/
QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &hostUri, const QGrpcChannelOptions &options)
: QAbstractGrpcChannel(options),
dPtr(std::make_unique<QGrpcHttp2ChannelPrivate>(hostUri, options))
{
}
@ -821,6 +832,14 @@ QGrpcHttp2Channel::QGrpcHttp2Channel(const QGrpcChannelOptions &options)
*/
QGrpcHttp2Channel::~QGrpcHttp2Channel() = default;
/*!
Returns the host URI for this channel.
*/
QUrl QGrpcHttp2Channel::hostUri() const noexcept
{
return dPtr->hostUri;
}
/*!
\internal
Implementation of unary gRPC call based on \l QNetworkAccessManager.

View File

@ -17,9 +17,12 @@ struct QGrpcHttp2ChannelPrivate;
class Q_GRPC_EXPORT QGrpcHttp2Channel final : public QAbstractGrpcChannel
{
public:
explicit QGrpcHttp2Channel(const QGrpcChannelOptions &options);
explicit QGrpcHttp2Channel(const QUrl &hostUri);
explicit QGrpcHttp2Channel(const QUrl &hostUri, const QGrpcChannelOptions &options);
~QGrpcHttp2Channel() override;
[[nodiscard]] QUrl hostUri() const noexcept;
private:
void call(std::shared_ptr<QGrpcChannelOperation> channelOperation) override;
void startServerStream(std::shared_ptr<QGrpcChannelOperation> channelOperation) override;

View File

@ -74,13 +74,6 @@
\sa QGrpcChannelOptions::deadline
*/
/*!
\qmlproperty QUrl QQmlGrpcChannelOptions::host
Sets a host \c URL for the channel.
\note host is \c REQUIRED property. It must be set for object creation.
\sa QGrpcChannelOptions::host
*/
/*!
\qmlproperty enumeration QQmlGrpcChannelOptions::serializationFormat
Sets the serialization format for the channel.
@ -178,6 +171,13 @@
\sa QQmlAbstractGrpcChannel, QGrpcHttp2Channel
*/
/*!
\qmlproperty QUrl QQmlGrpcHttp2Channel::hostUri
Sets a host \c URL for the channel.
\note host is \c REQUIRED property. It must be set for object creation.
\sa QGrpcHttp2Channel::hostUri
*/
/*!
\qmlproperty QQmlGrpcChannelOptions QQmlGrpcHttp2Channel::options
Returns a pointer to the QQmlGrpcChannelOptions object.

View File

@ -24,7 +24,7 @@ public:
#endif // QT_CONFIG(ssl)
};
QQmlGrpcChannelOptionsPrivate::QQmlGrpcChannelOptionsPrivate() : QObjectPrivate(), m_options(QUrl())
QQmlGrpcChannelOptionsPrivate::QQmlGrpcChannelOptionsPrivate() : QObjectPrivate()
{
}
@ -33,18 +33,6 @@ QQmlGrpcChannelOptions::QQmlGrpcChannelOptions(QObject *parent)
{
}
QUrl QQmlGrpcChannelOptions::host() const
{
return d_func()->m_options.host();
}
void QQmlGrpcChannelOptions::setHost(const QUrl &newUrl)
{
Q_D(QQmlGrpcChannelOptions);
d->m_options.setHost(newUrl);
emit hostChanged();
}
qint64 QQmlGrpcChannelOptions::deadline() const
{
QGrpcDuration

View File

@ -35,7 +35,6 @@ class Q_GRPCQUICK_EXPORT QQmlGrpcChannelOptions : public QObject
QML_NAMED_ELEMENT(GrpcChannelOptions)
QML_ADDED_IN_VERSION(6, 7)
Q_PROPERTY(QUrl host READ host WRITE setHost NOTIFY hostChanged REQUIRED)
Q_PROPERTY(qint64 deadline READ deadline WRITE setDeadline NOTIFY deadlineChanged)
Q_PROPERTY(QQmlGrpcMetadata *metadata READ metadata WRITE setMetadata NOTIFY metadataChanged)
Q_PROPERTY(QQmlSerializationFormat::GrpcSerializationFormat serializationFormat
@ -50,8 +49,6 @@ public:
QQmlGrpcChannelOptions(QObject *parent = nullptr);
const QGrpcChannelOptions &options() const;
QUrl host() const;
void setHost(const QUrl &newUrl);
qint64 deadline() const;
void setDeadline(qint64 value);
QQmlGrpcMetadata *metadata() const;
@ -64,7 +61,6 @@ public:
#endif // QT_CONFIG(ssl)
Q_SIGNALS:
void hostChanged();
void deadlineChanged();
void metadataChanged();
void serializationFormatChanged();

View File

@ -32,12 +32,40 @@ void QQmlGrpcHttp2Channel::setOptions(QQmlGrpcChannelOptions *options)
void QQmlGrpcHttp2Channel::updateChannel()
{
if (m_channel && m_options)
if (m_hostUri.isEmpty())
return;
if (!m_hostUri.isValid()) {
qWarning() << "Unable to initialize the channel. The host URI is not valid.";
return;
}
if (m_channel)
m_channel.reset();
m_channel = std::make_shared<QGrpcHttp2Channel>(m_options->options());
if (m_hostUri.isValid()) {
m_channel = m_options ? std::make_shared<QGrpcHttp2Channel>(m_hostUri, m_options->options())
: std::make_shared<QGrpcHttp2Channel>(m_hostUri);
}
emit channelUpdated();
}
void QQmlGrpcHttp2Channel::setHostUri(const QUrl &hostUri)
{
if (hostUri == m_hostUri)
return;
if (m_channel) {
qWarning() << "Changing the host URI is not supported.";
return;
}
m_hostUri = hostUri;
emit hostUriChanged();
updateChannel();
}
QT_END_NAMESPACE
#include "moc_qqmlgrpchttp2channel_p.cpp"

View File

@ -28,8 +28,9 @@ class Q_GRPCQUICK_EXPORT QQmlGrpcHttp2Channel : public QQmlAbstractGrpcChannel
Q_OBJECT
QML_NAMED_ELEMENT(GrpcHttp2Channel)
QML_ADDED_IN_VERSION(6, 7)
Q_PROPERTY(QQmlGrpcChannelOptions *options READ options
WRITE setOptions NOTIFY optionsChanged REQUIRED)
Q_PROPERTY(QUrl hostUri READ hostUri WRITE setHostUri NOTIFY hostUriChanged REQUIRED)
Q_PROPERTY(QQmlGrpcChannelOptions *options READ options WRITE setOptions NOTIFY optionsChanged
REQUIRED)
Q_PROPERTY(std::shared_ptr<QAbstractGrpcChannel> channel READ getChannel NOTIFY channelUpdated)
public:
@ -39,14 +40,18 @@ public:
QQmlGrpcChannelOptions *options() const { return m_options; }
void setOptions(QQmlGrpcChannelOptions *options);
QUrl hostUri() const noexcept { return m_hostUri; }
void setHostUri(const QUrl &hostUri);
Q_SIGNALS:
void optionsChanged();
void channelUpdated();
void hostUriChanged();
private:
void updateChannel();
QQmlGrpcChannelOptions *m_options;
QUrl m_hostUri;
std::shared_ptr<QAbstractGrpcChannel> m_channel;
};

View File

@ -123,8 +123,9 @@ void QtGrpcClientClientStreamTest::sequentialSendWithDone()
void QtGrpcClientClientStreamTest::sequentialSendWithDoneWhenChannelNotReady()
{
auto channel = std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) }));
auto channel = std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("http://localhost:50051",
QUrl::StrictMode)));
auto client = std::make_shared<qtgrpc::tests::TestService::Client>();
client->attachChannel(std::move(channel));

View File

@ -16,14 +16,16 @@ void GrpcClientTestBase::initTestCase_data()
if (m_channels.testFlag(Channel::Qt)) {
QTest::newRow("Http2Client")
<< QFlags{ Channel::Qt }
<< std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) }));
<< QFlags{ Channel::Qt }
<< std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("http://localhost:50051",
QUrl::StrictMode)));
#ifndef Q_OS_WINDOWS
QTest::newRow("Http2ClientUnix")
<< QFlags{ Channel::Qt }
<< std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("unix:///tmp/qtgrpc_test.sock", QUrl::StrictMode) }));
<< std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("unix:///tmp/qtgrpc_test.sock",
QUrl::StrictMode)));
#endif
}
@ -32,15 +34,19 @@ void GrpcClientTestBase::initTestCase_data()
QGrpcMetadata md{ { "content-type"_ba, "application/grpc+json" } };
QTest::newRow("Http2ClientJson")
<< QFlags{ Channel::Qt }
<< std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) }
.setMetadata(md)));
<< std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("http://localhost:50051",
QUrl::StrictMode),
QGrpcChannelOptions{}
.setMetadata(md)));
QTest::newRow("Http2ClientJsonUnix")
<< QFlags{ Channel::Qt }
<< std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("unix:///tmp/qtgrpc_test.sock", QUrl::StrictMode) }
.setMetadata(md)));
<< std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("unix:///tmp/qtgrpc_test.sock",
QUrl::StrictMode),
QGrpcChannelOptions{}
.setMetadata(md)));
}
#endif
@ -55,21 +61,24 @@ void GrpcClientTestBase::initTestCase_data()
sslConfig.setAllowedNextProtocols({ QByteArray("h2") });
QTest::newRow("Http2ClientSSL")
<< QFlags{ Channel::Qt, Channel::Ssl }
<< std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(
QGrpcChannelOptions{ QUrl("https://localhost:50052", QUrl::StrictMode) }
.withSslConfiguration(sslConfig)));
<< std::shared_ptr<QAbstractGrpcChannel>(
new QGrpcHttp2Channel(QUrl("https://localhost:50052", QUrl::StrictMode),
QGrpcChannelOptions{}.withSslConfiguration(sslConfig)));
}
if (m_channels.testFlag(Channel::SslNoCredentials)) {
QSslConfiguration sslConfig;
sslConfig.setProtocol(QSsl::TlsV1_2);
sslConfig.setAllowedNextProtocols({ QByteArray("h2") });
QGrpcChannelOptions channelOptions(QUrl("https://localhost:50052", QUrl::StrictMode));
QGrpcChannelOptions channelOptions;
channelOptions.withSslConfiguration(sslConfig);
QTest::newRow("Http2ClientSSLNoCredentials")
<< QFlags{ Channel::Qt, Channel::SslNoCredentials }
<< std::shared_ptr<QAbstractGrpcChannel>(new QGrpcHttp2Channel(channelOptions));
<< std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("https://localhost:50052",
QUrl::StrictMode),
channelOptions));
}
#endif
@ -79,8 +88,9 @@ void GrpcClientTestBase::initTestCase_data()
QTest::newRow("Http2ClientDeadline")
<< QFlags{ Channel::Qt, Channel::WithChannelDeadline }
<< std::shared_ptr<
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) }
QAbstractGrpcChannel>(new QGrpcHttp2Channel(QUrl("http://localhost:50051",
QUrl::StrictMode),
QGrpcChannelOptions{}
.setDeadline(channelTimeout)));
}
}

View File

@ -75,8 +75,8 @@ void QGrpcHttp2ChannelTest::checkMethodsGeneration()
{
// Dummy compile time check of functions generation and interface compatibility
TestService::Client client;
QGrpcChannelOptions channelOptions{ QUrl() };
client.attachChannel(std::make_shared<QGrpcHttp2Channel>(channelOptions));
QGrpcChannelOptions channelOptions;
client.attachChannel(std::make_shared<QGrpcHttp2Channel>(QUrl(), channelOptions));
SimpleStringMessage request;
client.testMethod(request);
client.testMethod(request, &client, [](std::shared_ptr<QGrpcCallReply>) {});
@ -85,10 +85,10 @@ void QGrpcHttp2ChannelTest::checkMethodsGeneration()
void QGrpcHttp2ChannelTest::attachChannelThreadTest()
{
std::shared_ptr<QGrpcHttp2Channel> channel;
QGrpcChannelOptions channelOptions(QUrl("http://localhost:50051", QUrl::StrictMode));
std::shared_ptr<QThread> thread(QThread::create([&] {
channel = std::make_shared<QGrpcHttp2Channel>(channelOptions);
channel = std::make_shared<QGrpcHttp2Channel>(QUrl("http://localhost:50051",
QUrl::StrictMode));
}));
thread->start();
thread->wait();
@ -111,24 +111,25 @@ void QGrpcHttp2ChannelTest::attachChannelThreadTest()
void QGrpcHttp2ChannelTest::serializationFormat()
{
std::shared_ptr<QAbstractGrpcChannel>
channel = std::make_shared<QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode) });
channel = std::make_shared<QGrpcHttp2Channel>(QUrl("http://localhost:50051",
QUrl::StrictMode));
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{ QUrl("http://localhost:50051", QUrl::StrictMode) }
.setSerializationFormat(QGrpcSerializationFormat{
QGrpcSerializationFormat::Format::Json }));
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{}.setSerializationFormat(QGrpcSerializationFormat{
QGrpcSerializationFormat::Format::Json }));
QVERIFY(dynamic_cast<QProtobufJsonSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{ QUrl("http://localhost:50051", QUrl::StrictMode) }
.setSerializationFormat(QGrpcSerializationFormat{
QGrpcSerializationFormat::Format::Protobuf }));
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{}.setSerializationFormat(QGrpcSerializationFormat{
QGrpcSerializationFormat::Format::Protobuf }));
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{ QUrl("http://localhost:50051", QUrl::StrictMode) }
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{}
.setSerializationFormat({ "dummy",
std::make_shared<DummySerializer>() }));
QVERIFY(dynamic_cast<DummySerializer *>(channel->serializer().get()) != nullptr);
@ -137,31 +138,31 @@ void QGrpcHttp2ChannelTest::serializationFormat()
void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
{
std::shared_ptr<QAbstractGrpcChannel> channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc"_ba } }));
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
// Initialize with various content-type headers
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+json"_ba } }));
QVERIFY(dynamic_cast<QProtobufJsonSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba,
"application/grpc+proto"_ba } }));
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba,
"application/grpc+unknown"_ba } }));
@ -169,16 +170,16 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
// Initialize with the default content-type header and various serialization formats
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{}));
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{
@ -186,8 +187,8 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
QVERIFY(dynamic_cast<QProtobufJsonSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{
@ -195,8 +196,8 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc"_ba } })
.setSerializationFormat({ "dummy",
@ -205,8 +206,8 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
// Initialize with the content-type header incompatible with serialization format
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+json"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{
@ -214,16 +215,16 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+json"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{}));
QVERIFY(dynamic_cast<QProtobufJsonSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+json"_ba } })
.setSerializationFormat({ "dummy",
@ -232,8 +233,8 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
// Initialize with the content-type header matching the serialization format
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+proto"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{
@ -241,8 +242,8 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+json"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{
@ -250,16 +251,16 @@ void QGrpcHttp2ChannelTest::serializationFormatWithHeaders()
QVERIFY(dynamic_cast<QProtobufJsonSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc"_ba } })
.setSerializationFormat(QGrpcSerializationFormat{}));
QVERIFY(dynamic_cast<QProtobufSerializer *>(channel->serializer().get()) != nullptr);
channel = std::make_shared<
QGrpcHttp2Channel>(QGrpcChannelOptions{
QUrl("http://localhost:50051", QUrl::StrictMode)
QGrpcHttp2Channel>(QUrl("http://localhost:50051", QUrl::StrictMode),
QGrpcChannelOptions{
}
.setMetadata({ { "content-type"_ba, "application/grpc+dummy"_ba } })
.setSerializationFormat({ "dummy",

View File

@ -32,7 +32,6 @@ Item {
GrpcChannelOptions {
id: options
host: "http://localhost:50051"
deadline: { 1000 }
metadata: GrpcMetadata {
id: grpcData
@ -44,7 +43,6 @@ Item {
GrpcChannelOptions {
id: optionsWithChangedProperties
host: "http://localhost:50051"
metadata: GrpcMetadata {
data: ({ "user-name": "localhost",
"user-password": "qwerty"})
@ -109,8 +107,6 @@ Item {
function test_ChannelOptions_data() {
return [
{ tag: "options URL is set",
field: options.host, answer: "http://localhost:50051" },
{ tag: "options.metadata == grpcData",
field: options.metadata, answer: grpcData },
{ tag: "options.metadata.data == grpcData.data",

View File

@ -50,8 +50,8 @@ Item {
GrpcHttp2Channel {
id: httpChannel
hostUri: "http://localhost:50051"
options: GrpcChannelOptions {
host: "http://localhost:50051"
}
}

View File

@ -40,8 +40,8 @@ Item {
GrpcHttp2Channel {
id: httpChannel
hostUri: "http://localhost:50051"
options: GrpcChannelOptions {
host: "http://localhost:50051"
}
}

View File

@ -43,8 +43,8 @@ Item {
GrpcHttp2Channel {
id: httpChannel
hostUri: "http://localhost:50051"
options: GrpcChannelOptions {
host: "http://localhost:50051"
}
}

View File

@ -34,15 +34,15 @@ Item {
function createGrpcChannelItem() {
return Qt.createQmlObject("import QtQuick; import QtGrpc; GrpcHttp2Channel { \
hostUri: \"http://localhost:50051\"; \
options: GrpcChannelOptions { \
host: \"http://localhost:50051\"; \
deadline: { 2000 } } }", root)
}
function createGrpcChannelWithDeadlineItem() {
return Qt.createQmlObject("import QtQuick; import QtGrpc; GrpcHttp2Channel { \
hostUri: \"http://localhost:50051\"; \
options: GrpcChannelOptions { \
host: \"http://localhost:50051\"; \
deadline: { 1000 } } }", root)
}
@ -66,7 +66,7 @@ Item {
function test_ChannelOptions_data() {
return [
{ tag: "grpcChannelOptions URL is set",
field: grpcChannel.options.host, answer: "http://localhost:50051" },
field: grpcChannel.hostUri, answer: "http://localhost:50051" },
{ tag: "grpcChannelOptions deadline is set",
field: grpcChannelDeadline.options.deadline, answer: 1000 }
]

View File

@ -12,7 +12,6 @@ TestCase {
GrpcChannelOptions {
id: optionsVar
host: "http://localhost:50051"
deadline: { 1000 }
metadata: GrpcMetadata {
id: grpcData
@ -23,8 +22,8 @@ TestCase {
GrpcHttp2Channel {
id: channelId
hostUri: "http://localhost:50051"
options: GrpcChannelOptions {
host: "http://localhost:50051"
deadline: { 1000 }
metadata: grpcData
}
@ -32,6 +31,7 @@ TestCase {
GrpcHttp2Channel {
id: secondChannelId
hostUri: "http://localhost:50051"
options: optionsVar
}
@ -55,7 +55,7 @@ TestCase {
function test_3GrpcChannelValues_data() {
return [
{ tag: "channelId Host",
field: channelId.options.host, answer: "http://localhost:50051" },
field: channelId.hostUri, answer: "http://localhost:50051" },
{ tag: "channelId deadline",
field: channelId.options.deadline, answer: 1000 },
{ tag: "channelId metadata",
@ -63,7 +63,7 @@ TestCase {
{ tag: "secondChannelId deadline",
field: secondChannelId.options.deadline, answer: 1000 },
{ tag: "secondChannelId Host",
field: secondChannelId.options.host, answer: "http://localhost:50051" },
field: secondChannelId.hostUri, answer: "http://localhost:50051" },
{ tag: "secondChannelId metadata",
field: secondChannelId.options.metadata, answer: grpcData },
{ tag: "secondChannelId metadata == channelId metadata",