Browse Source

Qtfy abstract client

- Rename AbstractClient class
- Add few doxy comments
- Add extra error handling in AbstractClient
Alexey Edelev 5 years ago
parent
commit
f9274527c3

+ 2 - 2
src/generator/clientgenerator.cpp

@@ -48,7 +48,7 @@ ClientGenerator::ClientGenerator(const ServiceDescriptor *service, std::unique_p
 
 void ClientGenerator::printClientClass()
 {
-    mPrinter.Print({{"classname", mClassName}, {"parent_class", "qtprotobuf::AbstractClient"}}, Templates::ClassDefinitionTemplate);
+    mPrinter.Print({{"classname", mClassName}, {"parent_class", "qtprotobuf::QAbstractGrpcClient"}}, Templates::ClassDefinitionTemplate);
     mPrinter.Print(Templates::QObjectMacro);
 }
 
@@ -64,7 +64,7 @@ void ClientGenerator::printClientIncludes()
     printIncludes();
 
     std::unordered_set<std::string> includeSet;
-    includeSet.insert("abstractclient");
+    includeSet.insert("qabstractgrpcclient");
     includeSet.insert("asyncreply");
     for (auto type : includeSet) {
         mPrinter.Print({{"include", type}}, Templates::InternalIncludeTemplate);

+ 1 - 1
src/generator/clientsourcegenerator.cpp

@@ -62,6 +62,6 @@ void ClientSourceGenerator::printMethods()
 void ClientSourceGenerator::printConstructor()
 {
     mPrinter.Print({ {"classname", mClassName},
-                     {"parent_class", "AbstractClient"},
+                     {"parent_class", "QAbstractGrpcClient"},
                      {"service_name", mService->full_name()} }, Templates::ConstructorDefinitionSyncTemplate);
 }

+ 2 - 2
src/grpc/CMakeLists.txt

@@ -15,7 +15,7 @@ include(${CMAKE_SOURCE_DIR}/cmake/Coverage.cmake)
 file(GLOB SOURCES asyncreply.cpp
     qabstractgrpcchannel.cpp
     qgrpchttp2channel.cpp
-    abstractclient.cpp
+    qabstractgrpcclient.cpp
     abstractcredentials.cpp
     sslcredentials.cpp
     insecurecredentials.cpp)
@@ -23,7 +23,7 @@ file(GLOB SOURCES asyncreply.cpp
 file(GLOB HEADERS asyncreply.h
     qabstractgrpcchannel.h
     qgrpchttp2channel.h
-    abstractclient.h
+    qabstractgrpcclient.h
     abstractcredentials.h
     sslcredentials.h
     insecurecredentials.h

+ 0 - 138
src/grpc/abstractclient.h

@@ -1,138 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
- *
- * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this
- * software and associated documentation files (the "Software"), to deal in the Software
- * without restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies
- * or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#pragma once
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-
-#include <QObject>
-#include <QByteArray>
-
-#include <qtprotobuflogging.h>
-
-#include "qabstractgrpcchannel.h"
-#include "asyncreply.h"
-
-#include "qtgrpcglobal.h"
-
-namespace qtprotobuf {
-class QAbstractGrpcChannel;
-
-/*!
- * \ingroup QtGrpc
- * \brief The AbstractClient class
- */
-class Q_GRPC_EXPORT AbstractClient : public QObject
-{
-    Q_OBJECT
-public:
-    void attachChannel(const std::shared_ptr<QAbstractGrpcChannel> &channel);
-
-signals:
-    void error(QAbstractGrpcChannel::StatusCode code, const QString &errorText);
-
-protected:
-    AbstractClient(const QString &service, QObject *parent = nullptr);
-    virtual ~AbstractClient();
-
-    /*!
-     * \brief A template of a sync RPC call
-     *
-     * \param method Name of the method to be called
-     * \param arg Arguments (proto-message) passed to the method called
-     * \param ret A pointer to memory with proto-message to write an RPC reply to
-     */
-    template<typename A, typename R>
-    bool call(const QString &method, const A &arg, const QPointer<R> &ret) {
-        if (ret.isNull()) {
-            qProtoCritical() << "Unable to call method: " << method << ". Pointer to return data is null";
-            return false;
-        }
-
-        QByteArray retData;
-        if (QAbstractGrpcChannel::StatusCode::Ok == call(method, arg.serialize(), retData)) {
-            try {
-                ret->deserialize(retData);
-            } catch (std::invalid_argument &) {
-                qProtoCritical() << "Response deserialization failed invalid field found";
-                return false;
-            } catch (std::out_of_range &) {
-                qProtoCritical() << "Invalid size of received buffer";
-                return false;
-            } catch (...) {
-                throw;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    template<typename A>
-    AsyncReply *call(const QString &method, const A &arg) {
-        return call(method, arg.serialize());
-    }
-
-    template<typename A, typename R, typename C,
-             typename std::enable_if_t<std::is_base_of<AbstractClient, C>::value, int> = 0>
-    void subscribe(const QString &method, const A &arg, void(C::*signal)(const R &)) {
-        subscribe_p(method, arg.serialize(), [this, signal](const QByteArray &data) {
-            R ret;
-            ret.deserialize(data);
-            C *client = static_cast<C *>(this);
-            (client->*signal)(ret);
-        });
-    }
-
-    template<typename A, typename R>
-    void subscribe(const QString &method, const A &arg, const QPointer<R> &ret) {
-        if (ret.isNull()) {
-            qProtoCritical() << "Unable to subscribe method: " << method << ". Pointer to return data is null";
-            return;
-        }
-
-        subscribe_p(method, arg.serialize(), [ret](const QByteArray &data) {
-            if (!ret.isNull()) {
-                ret->deserialize(data);
-            } else {
-                qProtoCritical() << "Pointer to return data is null while subscription update received";
-            }
-        });
-    }
-
-private:
-    QAbstractGrpcChannel::StatusCode call(const QString &method, const QByteArray &arg, QByteArray &ret);
-    AsyncReply *call(const QString &method, const QByteArray &arg);
-    void subscribe_p(const QString &method, const QByteArray &arg, const std::function<void(const QByteArray &)> &handler);
-
-    Q_DISABLE_COPY(AbstractClient)
-    AbstractClient(AbstractClient &&) = delete;
-    AbstractClient &operator =(AbstractClient &&) = delete;
-
-    // PIMPL
-    class AbstractClientPrivate *d;
-};
-}

+ 1 - 1
src/grpc/asyncreply.h

@@ -72,7 +72,7 @@ private:
     AsyncReply(AsyncReply &&) = delete;
     AsyncReply &operator =(AsyncReply &&) = delete;
 
-    friend class AbstractClient;
+    friend class QAbstractGrpcClient;
 
     std::shared_ptr<QAbstractGrpcChannel> m_channel;
     QByteArray m_data;

+ 3 - 3
src/grpc/qabstractgrpcchannel.h

@@ -34,7 +34,7 @@
 namespace qtprotobuf {
 
 class AsyncReply;
-class AbstractClient;
+class QAbstractGrpcClient;
 /*!
  * \ingroup QtGrpc
  * \brief The QAbstractGrpcChannel class is interface that represents common gRPC channel functionality.
@@ -88,7 +88,7 @@ public:
      * \param[in] service service identified in URL path format
      * \param[in] args serialized argument message
      * \param[out] ret AsyncReply that will be returned to end-point user to read data once call complete.
-     *            AsyncReply lifecycle is managed by AbstractClient only.
+     *            AsyncReply lifecycle is managed by QAbstractGrpcClient only.
      *            \see AsyncReply for details
      */
     virtual void call(const QString &method, const QString &service, const QByteArray &args, qtprotobuf::AsyncReply *ret) = 0;
@@ -100,7 +100,7 @@ public:
      * \param[in] args serialized argument message
      * \param[in] handler callback that will be called when message recevied from the server-stream
      */
-    virtual void subscribe(const QString &method, const QString &service, const QByteArray &args, AbstractClient *client, const std::function<void(const QByteArray &)> &handler) = 0;
+    virtual void subscribe(const QString &method, const QString &service, const QByteArray &args, QAbstractGrpcClient *client, const std::function<void(const QByteArray &)> &handler) = 0;
 protected:
     QAbstractGrpcChannel() = default;
     virtual ~QAbstractGrpcChannel() = default;

+ 14 - 14
src/grpc/abstractclient.cpp → src/grpc/qabstractgrpcclient.cpp

@@ -23,14 +23,14 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "abstractclient.h"
+#include "qabstractgrpcclient.h"
 
 #include <QTimer>
 
 namespace qtprotobuf {
-class AbstractClientPrivate final {
+class QAbstractGrpcClientPrivate final {
 public:
-    AbstractClientPrivate(const QString &service) : service(service) {}
+    QAbstractGrpcClientPrivate(const QString &service) : service(service) {}
 
     std::shared_ptr<QAbstractGrpcChannel> channel;
     const QString service;
@@ -39,41 +39,41 @@ public:
 
 using namespace qtprotobuf;
 
-AbstractClient::AbstractClient(const QString &service, QObject *parent) : QObject(parent)
-  , d(new AbstractClientPrivate(service))
+QAbstractGrpcClient::QAbstractGrpcClient(const QString &service, QObject *parent) : QObject(parent)
+  , d(new QAbstractGrpcClientPrivate(service))
 {
 }
 
-AbstractClient::~AbstractClient()
+QAbstractGrpcClient::~QAbstractGrpcClient()
 {
     delete d;
 }
 
-void AbstractClient::attachChannel(const std::shared_ptr<QAbstractGrpcChannel> &channel)
+void QAbstractGrpcClient::attachChannel(const std::shared_ptr<QAbstractGrpcChannel> &channel)
 {
     d->channel = channel;
 }
 
-QAbstractGrpcChannel::StatusCode AbstractClient::call(const QString &method, const QByteArray &arg, QByteArray &ret)
+QAbstractGrpcChannel::StatusCode QAbstractGrpcClient::call(const QString &method, const QByteArray &arg, QByteArray &ret)
 {
     QAbstractGrpcChannel::StatusCode callStatus = QAbstractGrpcChannel::Unknown;
     if (d->channel) {
         callStatus = d->channel->call(method, d->service, arg, ret);
     } else {
-        emit error(callStatus, QLatin1String("No channel(s) attached."));
+        error(callStatus, QLatin1String("No channel(s) attached."));
     }
 
     return callStatus;
 }
 
-AsyncReply *AbstractClient::call(const QString &method, const QByteArray &arg)
+AsyncReply *QAbstractGrpcClient::call(const QString &method, const QByteArray &arg)
 {
     AsyncReply *reply = nullptr;
     if (d->channel) {
         reply = new AsyncReply(d->channel, this);
 
         connect(reply, &AsyncReply::error, this, [this, reply](QAbstractGrpcChannel::StatusCode statusCode) {
-            emit error(statusCode, QLatin1String("Connection has been aborted."));
+            error(statusCode, QLatin1String("Connection has been aborted."));
             reply->deleteLater();
         });
 
@@ -83,17 +83,17 @@ AsyncReply *AbstractClient::call(const QString &method, const QByteArray &arg)
 
         d->channel->call(method, d->service, arg, reply);
     } else {
-        emit error(QAbstractGrpcChannel::Unknown, QLatin1String("No channel(s) attached."));
+        error(QAbstractGrpcChannel::Unknown, QLatin1String("No channel(s) attached."));
     }
 
     return reply;
 }
 
-void AbstractClient::subscribe_p(const QString &method, const QByteArray &arg, const std::function<void(const QByteArray&)> &handler)
+void QAbstractGrpcClient::subscribe(const QString &method, const QByteArray &arg, const std::function<void(const QByteArray&)> &handler)
 {
     if (d->channel) {
         d->channel->subscribe(method, d->service, arg, this, handler);
     } else {
-        emit error(QAbstractGrpcChannel::Unknown, QLatin1String("No channel(s) attached."));
+        error(QAbstractGrpcChannel::Unknown, QLatin1String("No channel(s) attached."));
     }
 }

+ 205 - 0
src/grpc/qabstractgrpcclient.h

@@ -0,0 +1,205 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <memory>
+#include <functional>
+#include <type_traits>
+
+#include <QObject>
+#include <QByteArray>
+
+#include <qtprotobuflogging.h>
+
+#include "qabstractgrpcchannel.h"
+#include "asyncreply.h"
+
+#include "qtgrpcglobal.h"
+
+namespace qtprotobuf {
+class QAbstractGrpcChannel;
+
+/*!
+ * \ingroup QtGrpc
+ * \brief The QAbstractGrpcClient class is bridge between gRPC clients and channels. QAbstractGrpcClient provides set of
+ *        bridge functions for client classes generated out of protobuf services.
+ */
+class Q_GRPC_EXPORT QAbstractGrpcClient : public QObject
+{
+    Q_OBJECT
+public:
+    /*!
+     * \brief Attaches \a channel to client as transport layer for gRPC. Parameters and return values will be serialized
+     *        to supported by channel format.
+     * \see QAbstractGrcpChannel
+     * \param channel Shared pointer to channel will be used as transport layer for gRPC
+     */
+    void attachChannel(const std::shared_ptr<QAbstractGrpcChannel> &channel);
+
+signals:
+    /*!
+     * \brief error signal is emited by client when error occured in channel or while serialization/deserialization
+     * \param[out] code gRPC channel StatusCode
+     * \param[out] errorText Error description from channel or from QGrpc
+     */
+    void error(QAbstractGrpcChannel::StatusCode code, const QString &errorText);
+
+protected:
+    QAbstractGrpcClient(const QString &service, QObject *parent = nullptr);
+    virtual ~QAbstractGrpcClient();
+
+    /*!
+     * \private
+     * \brief Calls \p method of service client synchronously
+     * \param[in] method Name of the method to be called
+     * \param[in] arg Protobuf message argument for \p method
+     * \param[out] ret A pointer to memory with protobuf message to write an gRPC reply to
+     */
+    template<typename A, typename R>
+    bool call(const QString &method, const A &arg, const QPointer<R> &ret) {
+        if (ret.isNull()) {
+            static const QString errorString("Unable to call method: %1. Pointer to return data is null");
+            error(QAbstractGrpcChannel::InvalidArgument, errorString.arg(method));
+            qProtoCritical() << errorString.arg(method);
+            return false;
+        }
+
+        QByteArray retData;
+        if (QAbstractGrpcChannel::StatusCode::Ok == call(method, arg.serialize(), retData)) {
+            return tryDeserialize(*ret, retData);
+        }
+        return false;
+    }
+
+    /*!
+     * \private
+     * \brief Calls \p method of service client asynchronously and returns pointer to assigned to call AsyncReply
+     * \param[in] method Name of the method to be called
+     * \param[in] arg Protobuf message argument for \p method
+     */
+    template<typename A>
+    AsyncReply *call(const QString &method, const A &arg) {
+        return call(method, arg.serialize());
+    }
+
+    /*!
+     * \private
+     * \brief Subscribes to message notifications from server-stream with given message argument \a arg
+     * \param[in] method Name of the method to be called
+     * \param[in] arg Protobuf message argument for \p method
+     * \param[out] signal Callback with return-message as input parameter that will be called each time message
+     *             update recevied from server-stream
+     */
+    template<typename A, typename R, typename C,
+             typename std::enable_if_t<std::is_base_of<QAbstractGrpcClient, C>::value, int> = 0>
+    void subscribe(const QString &method, const A &arg, void(C::*signal)(const R &)) {
+        subscribe(method, arg.serialize(), [this, signal](const QByteArray &data) {
+            R ret;
+            tryDeserialize(ret, data);
+            C *client = static_cast<C *>(this);
+            (client->*signal)(ret);
+        });
+    }
+
+    /*!
+     * \private
+     * \brief Subscribes to message notifications from server-stream with given message argument \a arg
+     * \param[in] method Name of the method to be called
+     * \param[in] arg Protobuf message argument for \p method
+     * \param[out] ret Pointer to preallocated return-message structure. \p ret Structure fields will be update each
+     *        time message update recevied from server-stream.
+     * \note If \p ret is used as property-fiels in other object, property NOTIFY signal won't be called in case of
+     *       updated message recevied from server-stream
+     */
+    template<typename A, typename R>
+    void subscribe(const QString &method, const A &arg, const QPointer<R> &ret) {
+        if (ret.isNull()) {
+            static const QString nullPointerError("Unable to subscribe method: %1. Pointer to return data is null");
+            error(QAbstractGrpcChannel::InvalidArgument, nullPointerError.arg(method));
+            qProtoCritical() << nullPointerError.arg(method);
+            return;
+        }
+
+        subscribe(method, arg.serialize(), [ret, this](const QByteArray &data) {
+            if (!ret.isNull()) {
+                tryDeserialize(*ret, data);
+            } else {
+                static const QLatin1String nullPointerError("Pointer to return data is null while subscription update received");
+                error(QAbstractGrpcChannel::InvalidArgument, nullPointerError);
+                qProtoCritical() << nullPointerError;
+            }
+        });
+    }
+
+private:
+    /*!
+     * \private
+     */
+    QAbstractGrpcChannel::StatusCode call(const QString &method, const QByteArray &arg, QByteArray &ret);
+
+    /*!
+     * \private
+     */
+    AsyncReply *call(const QString &method, const QByteArray &arg);
+
+    /*!
+     * \private
+     */
+    void subscribe(const QString &method, const QByteArray &arg, const std::function<void(const QByteArray &)> &handler);
+
+    /*!
+     * \private
+     * \brief Deserialization helper
+     */
+    template<typename R>
+    bool tryDeserialize(R &ret, const QByteArray &retData) {
+        try {
+            ret.deserialize(retData);
+        } catch (std::invalid_argument &) {
+            static const QLatin1String invalidArgumentErrorMessage("Response deserialization failed invalid field found");
+            error(QAbstractGrpcChannel::InvalidArgument, invalidArgumentErrorMessage);
+            qProtoCritical() << invalidArgumentErrorMessage;
+            return false;
+        } catch (std::out_of_range &) {
+            static const QLatin1String outOfRangeErrorMessage("Invalid size of received buffer");
+            error(QAbstractGrpcChannel::OutOfRange, outOfRangeErrorMessage);
+            qProtoCritical() << outOfRangeErrorMessage;
+            return false;
+        } catch (...) {
+            error(QAbstractGrpcChannel::OutOfRange, QLatin1String("Unknown exception caught during deserialization"));
+            return false;
+        }
+        return true;
+    }
+
+    Q_DISABLE_COPY(QAbstractGrpcClient)
+    QAbstractGrpcClient(QAbstractGrpcClient &&) = delete;
+    QAbstractGrpcClient &operator =(QAbstractGrpcClient &&) = delete;
+
+    // PIMPL
+    class QAbstractGrpcClientPrivate *d;
+};
+}

+ 14 - 14
src/grpc/qgrpchttp2channel.cpp

@@ -34,7 +34,7 @@
 #include <QtEndian>
 
 #include "asyncreply.h"
-#include "abstractclient.h"
+#include "qabstractgrpcclient.h"
 #include "abstractcredentials.h"
 
 #include <unordered_map>
@@ -92,7 +92,7 @@ const char *GrpcStatusHeader = "grpc-status";
 
 namespace qtprotobuf {
 
-struct Http2ChannelPrivate {
+struct QGrpcHttp2ChannelPrivate {
     struct ExpectedData {
         int expectedSize;
         QByteArray container;
@@ -133,13 +133,13 @@ struct Http2ChannelPrivate {
            qProtoCritical() << errors;
            // TODO: filter out noncritical SSL handshake errors
            // FIXME: error due to ssl failure is not transferred to the client: last error will be Operation canceled
-           Http2ChannelPrivate::abortNetworkReply(networkReply);
+           QGrpcHttp2ChannelPrivate::abortNetworkReply(networkReply);
         });
 
         if (!stream) {
             //TODO: Add configurable timeout logic
             QTimer::singleShot(6000, networkReply, [networkReply]() {
-                Http2ChannelPrivate::abortNetworkReply(networkReply);
+                QGrpcHttp2ChannelPrivate::abortNetworkReply(networkReply);
             });
         }
         return networkReply;
@@ -168,7 +168,7 @@ struct Http2ChannelPrivate {
         return networkReply->readAll().mid(5);
     }
 
-    Http2ChannelPrivate(const QUrl &_url, const AbstractCredentials &_credentials)
+    QGrpcHttp2ChannelPrivate(const QUrl &_url, const AbstractCredentials &_credentials)
         : url(_url)
         , credentials(_credentials)
     {
@@ -186,7 +186,7 @@ struct Http2ChannelPrivate {
 }
 
 QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &url, const AbstractCredentials &credentials) : QAbstractGrpcChannel()
-  , d(new Http2ChannelPrivate(url, credentials))
+  , d(new QGrpcHttp2ChannelPrivate(url, credentials))
 {
 }
 
@@ -220,7 +220,7 @@ void QGrpcHttp2Channel::call(const QString &method, const QString &service, cons
 
     auto connection = QObject::connect(networkReply, &QNetworkReply::finished, reply, [reply, networkReply]() {
         StatusCode grpcStatus = StatusCode::Unknown;
-        QByteArray data = Http2ChannelPrivate::processReply(networkReply, grpcStatus);
+        QByteArray data = QGrpcHttp2ChannelPrivate::processReply(networkReply, grpcStatus);
 
         qProtoDebug() << "RECV: " << data;
         if (StatusCode::Ok == grpcStatus ) {
@@ -234,11 +234,11 @@ void QGrpcHttp2Channel::call(const QString &method, const QString &service, cons
 
     QObject::connect(reply, &AsyncReply::error, networkReply, [networkReply, connection](QAbstractGrpcChannel::StatusCode code) {
         QObject::disconnect(connection);
-        Http2ChannelPrivate::abortNetworkReply(networkReply);
+        QGrpcHttp2ChannelPrivate::abortNetworkReply(networkReply);
     });
 }
 
-void QGrpcHttp2Channel::subscribe(const QString &method, const QString &service, const QByteArray &args, AbstractClient *client, const std::function<void (const QByteArray &)> &handler)
+void QGrpcHttp2Channel::subscribe(const QString &method, const QString &service, const QByteArray &args, QAbstractGrpcClient *client, const std::function<void (const QByteArray &)> &handler)
 {
     QNetworkReply *networkReply = d->post(method, service, args, true);
 
@@ -258,12 +258,12 @@ void QGrpcHttp2Channel::subscribe(const QString &method, const QString &service,
                 return;
             }
 
-            Http2ChannelPrivate::ExpectedData dataContainer{expectedDataSize, QByteArray{}};
+            QGrpcHttp2ChannelPrivate::ExpectedData dataContainer{expectedDataSize, QByteArray{}};
             d->activeStreamReplies.insert({networkReply, dataContainer});
             replyIt = d->activeStreamReplies.find(networkReply);
         }
 
-        Http2ChannelPrivate::ExpectedData &dataContainer = replyIt->second;
+        QGrpcHttp2ChannelPrivate::ExpectedData &dataContainer = replyIt->second;
         dataContainer.container.append(data);
 
         qProtoDebug() << "Proceed chunk: " << data.size() << " dataContainer: " << dataContainer.container.size() << " capacity: " << dataContainer.expectedSize;
@@ -274,10 +274,10 @@ void QGrpcHttp2Channel::subscribe(const QString &method, const QString &service,
         }
     });
 
-    QObject::connect(client, &AbstractClient::destroyed, networkReply, [networkReply, connection, this](){
+    QObject::connect(client, &QAbstractGrpcClient::destroyed, networkReply, [networkReply, connection, this](){
         d->activeStreamReplies.erase(networkReply);
         QObject::disconnect(connection);
-        Http2ChannelPrivate::abortNetworkReply(networkReply);
+        QGrpcHttp2ChannelPrivate::abortNetworkReply(networkReply);
     });
 
     //TODO: seems this connection might be invalid in case if this destroyed.
@@ -285,7 +285,7 @@ void QGrpcHttp2Channel::subscribe(const QString &method, const QString &service,
     QObject::connect(networkReply, &QNetworkReply::finished, [networkReply, this]() {
         d->activeStreamReplies.erase(networkReply);
         //TODO: implement error handling and subscription recovery here
-        Http2ChannelPrivate::abortNetworkReply(networkReply);
+        QGrpcHttp2ChannelPrivate::abortNetworkReply(networkReply);
     });
 }
 

+ 2 - 2
src/grpc/qgrpchttp2channel.h

@@ -45,7 +45,7 @@ public:
 
     StatusCode call(const QString &method, const QString &service, const QByteArray &args, QByteArray &ret) override;
     void call(const QString &method, const QString &service, const QByteArray &args, qtprotobuf::AsyncReply *reply) override;
-    void subscribe(const QString &method, const QString &service, const QByteArray &args, AbstractClient *client, const std::function<void (const QByteArray &)> &handler) override;
+    void subscribe(const QString &method, const QString &service, const QByteArray &args, QAbstractGrpcClient *client, const std::function<void (const QByteArray &)> &handler) override;
 
 protected:
     void abort(AsyncReply *reply) override;
@@ -54,6 +54,6 @@ private:
     Q_DISABLE_COPY(QGrpcHttp2Channel)
 
     // PIMPL
-    struct Http2ChannelPrivate *d;
+    struct QGrpcHttp2ChannelPrivate *d;
 };
 }