1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com> |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #include <QtGrpc/private/qabstractgrpcchannel_p.h> |
6 | #include <QtGrpc/qabstractgrpcchannel.h> |
7 | #include <QtGrpc/qgrpccalloptions.h> |
8 | #include <QtGrpc/qgrpccallreply.h> |
9 | #include <QtGrpc/qgrpcoperationcontext.h> |
10 | #include <QtGrpc/qgrpcstream.h> |
11 | |
12 | #include <QtCore/qbytearrayview.h> |
13 | #include <QtCore/qlatin1stringview.h> |
14 | |
15 | QT_BEGIN_NAMESPACE |
16 | |
17 | /*! |
18 | \class QAbstractGrpcChannel |
19 | \inmodule QtGrpc |
20 | \brief The QAbstractGrpcChannel class provides an interface for |
21 | implementing the transport layer of \gRPC operations. |
22 | |
23 | Implement this interface to create a custom channel for \gRPC |
24 | transportation. The QGrpcHttp2Channel class is provided as a fully featured |
25 | implementation of QAbstractGrpcChannel for HTTP/2 communication. |
26 | |
27 | \sa QGrpcChannelOptions, QGrpcHttp2Channel |
28 | */ |
29 | |
30 | /*! |
31 | \fn virtual std::shared_ptr<QAbstractProtobufSerializer> QAbstractGrpcChannel::serializer() const = 0 |
32 | |
33 | This pure virtual function retrieves the QAbstractProtobufSerializer used |
34 | for the serialization and deserialization of messages. |
35 | */ |
36 | |
37 | /*! |
38 | \fn virtual void QAbstractGrpcChannel::call(std::shared_ptr<QGrpcOperationContext> operationContext) = 0 |
39 | \since 6.7 |
40 | |
41 | //! [abstract-rpc-desc] |
42 | This pure virtual function is called when a user starts a new RPC through |
43 | the generated client interface. The \a operationContext should be used to |
44 | communicate with the corresponding RPC handler, which is a derived type of |
45 | the QGrpcOperation object. |
46 | |
47 | This function should start the corresponding RPC on the channel side. The |
48 | implementation must be asynchronous and must not block the calling thread. |
49 | |
50 | \note It is the channel's responsibility to support and restrict the subset |
51 | of features that its RPC type allows. |
52 | //! [abstract-rpc-desc] |
53 | */ |
54 | |
55 | /*! |
56 | \fn virtual void QAbstractGrpcChannel::serverStream(std::shared_ptr<QGrpcOperationContext> operationContext) = 0 |
57 | \since 6.7 |
58 | |
59 | \include qabstractgrpcchannel.cpp abstract-rpc-desc |
60 | */ |
61 | |
62 | /*! |
63 | \fn virtual void QAbstractGrpcChannel::clientStream(std::shared_ptr<QGrpcOperationContext> operationContext) = 0 |
64 | \since 6.7 |
65 | |
66 | \include qabstractgrpcchannel.cpp abstract-rpc-desc |
67 | */ |
68 | |
69 | /*! |
70 | \fn virtual void QAbstractGrpcChannel::bidiStream(std::shared_ptr<QGrpcOperationContext> operationContext) = 0 |
71 | \since 6.7 |
72 | |
73 | \include qabstractgrpcchannel.cpp abstract-rpc-desc |
74 | */ |
75 | |
76 | /*! |
77 | Default-constructs the QAbstractGrpcChannel. |
78 | */ |
79 | QAbstractGrpcChannel::QAbstractGrpcChannel() |
80 | : d_ptr(std::make_unique<QAbstractGrpcChannelPrivate>(args: QGrpcChannelOptions{})) |
81 | { |
82 | } |
83 | |
84 | /*! |
85 | \since 6.8 |
86 | \internal |
87 | |
88 | Constructs the QAbstractGrpcChannel using the Private implementation to |
89 | reuse the d_ptr. |
90 | */ |
91 | QAbstractGrpcChannel::QAbstractGrpcChannel(QAbstractGrpcChannelPrivate &dd) : d_ptr(&dd) |
92 | { |
93 | } |
94 | |
95 | /*! |
96 | Constructs the QAbstractGrpcChannel using the specified \a options. |
97 | */ |
98 | QAbstractGrpcChannel::QAbstractGrpcChannel(const QGrpcChannelOptions &options) |
99 | : d_ptr(std::make_unique<QAbstractGrpcChannelPrivate>(args: options)) |
100 | { |
101 | } |
102 | |
103 | /*! |
104 | Destroys the QAbstractGrpcChannel. |
105 | */ |
106 | QAbstractGrpcChannel::~QAbstractGrpcChannel() = default; |
107 | |
108 | /*! |
109 | Returns the options utilized by the channel. |
110 | |
111 | \sa setChannelOptions |
112 | */ |
113 | const QGrpcChannelOptions &QAbstractGrpcChannel::channelOptions() const & noexcept |
114 | { |
115 | Q_D(const QAbstractGrpcChannel); |
116 | return d->channelOptions; |
117 | } |
118 | |
119 | /*! |
120 | \fn void QAbstractGrpcChannel::setChannelOptions(const QGrpcChannelOptions &options) noexcept |
121 | \fn void QAbstractGrpcChannel::setChannelOptions(QGrpcChannelOptions &&options) noexcept |
122 | \since 6.8 |
123 | |
124 | Sets the channel \a options. |
125 | |
126 | \note The updated channel options do not affect currently active calls or streams. |
127 | The revised options will apply only to new RPCs made through this channel. |
128 | |
129 | \sa channelOptions |
130 | */ |
131 | void QAbstractGrpcChannel::setChannelOptions(const QGrpcChannelOptions &options) |
132 | { |
133 | Q_D(QAbstractGrpcChannel); |
134 | d->channelOptions = options; |
135 | } |
136 | |
137 | void QAbstractGrpcChannel::setChannelOptions(QGrpcChannelOptions &&options) |
138 | { |
139 | Q_D(QAbstractGrpcChannel); |
140 | d->channelOptions = std::move(options); |
141 | } |
142 | |
143 | /*! |
144 | \internal |
145 | |
146 | //! [private-rpc-desc] |
147 | This function is called when a user initiates a new RPC through the |
148 | generated client interface via QGrpcClientBase. It creates the |
149 | QGrpcOperationContext and the corresponding RPC handler, establishing the |
150 | required connections between the two. |
151 | //! [private-rpc-desc] |
152 | */ |
153 | std::unique_ptr<QGrpcCallReply> QAbstractGrpcChannel::call(QLatin1StringView method, |
154 | QLatin1StringView service, |
155 | QByteArrayView arg, |
156 | const QGrpcCallOptions &options) |
157 | { |
158 | auto operationContext = std::make_shared< |
159 | QGrpcOperationContext>(args&: method, args&: service, args&: arg, args: options, args: serializer(), |
160 | args: QGrpcOperationContext::PrivateConstructor()); |
161 | |
162 | QObject::connect(sender: operationContext.get(), signal: &QGrpcOperationContext::writeMessageRequested, |
163 | context: operationContext.get(), slot: []() { |
164 | Q_ASSERT_X(false, "QAbstractGrpcChannel::call" , |
165 | "QAbstractGrpcChannel::call disallows the " |
166 | "'writeMessageRequested' signal from " |
167 | "QGrpcOperationContext" ); |
168 | }); |
169 | |
170 | auto reply = std::make_unique<QGrpcCallReply>(args&: operationContext); |
171 | call(operationContext); |
172 | |
173 | return reply; |
174 | } |
175 | |
176 | /*! |
177 | \internal |
178 | \include qabstractgrpcchannel.cpp private-rpc-desc |
179 | */ |
180 | std::unique_ptr<QGrpcServerStream> |
181 | QAbstractGrpcChannel::serverStream(QLatin1StringView method, QLatin1StringView service, |
182 | QByteArrayView arg, const QGrpcCallOptions &options) |
183 | { |
184 | auto operationContext = std::make_shared< |
185 | QGrpcOperationContext>(args&: method, args&: service, args&: arg, args: options, args: serializer(), |
186 | args: QGrpcOperationContext::PrivateConstructor()); |
187 | |
188 | QObject::connect(sender: operationContext.get(), signal: &QGrpcOperationContext::writeMessageRequested, |
189 | context: operationContext.get(), slot: []() { |
190 | Q_ASSERT_X(false, "QAbstractGrpcChannel::serverStream" , |
191 | "QAbstractGrpcChannel::serverStream disallows " |
192 | "the 'writeMessageRequested' signal from " |
193 | "QGrpcOperationContext" ); |
194 | }); |
195 | |
196 | auto stream = std::make_unique<QGrpcServerStream>(args&: operationContext); |
197 | serverStream(operationContext); |
198 | |
199 | return stream; |
200 | } |
201 | |
202 | /*! |
203 | \internal |
204 | \include qabstractgrpcchannel.cpp private-rpc-desc |
205 | */ |
206 | std::unique_ptr<QGrpcClientStream> |
207 | QAbstractGrpcChannel::clientStream(QLatin1StringView method, QLatin1StringView service, |
208 | QByteArrayView arg, const QGrpcCallOptions &options) |
209 | { |
210 | auto operationContext = std::make_shared< |
211 | QGrpcOperationContext>(args&: method, args&: service, args&: arg, args: options, args: serializer(), |
212 | args: QGrpcOperationContext::PrivateConstructor()); |
213 | |
214 | auto stream = std::make_unique<QGrpcClientStream>(args&: operationContext); |
215 | clientStream(operationContext); |
216 | |
217 | return stream; |
218 | } |
219 | |
220 | /*! |
221 | \internal |
222 | \include qabstractgrpcchannel.cpp private-rpc-desc |
223 | */ |
224 | std::unique_ptr<QGrpcBidiStream> QAbstractGrpcChannel::bidiStream(QLatin1StringView method, |
225 | QLatin1StringView service, |
226 | QByteArrayView arg, |
227 | const QGrpcCallOptions &options) |
228 | { |
229 | auto operationContext = std::make_shared< |
230 | QGrpcOperationContext>(args&: method, args&: service, args&: arg, args: options, args: serializer(), |
231 | args: QGrpcOperationContext::PrivateConstructor()); |
232 | |
233 | auto stream = std::make_unique<QGrpcBidiStream>(args&: operationContext); |
234 | bidiStream(operationContext); |
235 | |
236 | return stream; |
237 | } |
238 | |
239 | QT_END_NAMESPACE |
240 | |