Add serialization of EraseRequest with ProtocolAdmin
[platform/core/security/cynara.git] / src / common / protocol / ProtocolAdmin.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file        src/common/protocol/ProtocolAdmin.cpp
18  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
19  * @author      Adam Malinowski <a.malinowsk2@partner.samsung.com>
20  * @version     1.0
21  * @brief       This file implements protocol class for administration
22  */
23
24 #include <cinttypes>
25 #include <memory>
26
27 #include <exceptions/InvalidProtocolException.h>
28 #include <log/log.h>
29 #include <protocol/ProtocolFrame.h>
30 #include <protocol/ProtocolFrameSerializer.h>
31 #include <request/AdminCheckRequest.h>
32 #include <request/EraseRequest.h>
33 #include <request/InsertOrUpdateBucketRequest.h>
34 #include <request/ListRequest.h>
35 #include <request/RemoveBucketRequest.h>
36 #include <request/RequestContext.h>
37 #include <request/SetPoliciesRequest.h>
38 #include <response/AdminCheckResponse.h>
39 #include <response/CodeResponse.h>
40 #include <response/ListResponse.h>
41 #include <types/PolicyKey.h>
42
43 #include "ProtocolAdmin.h"
44
45 namespace Cynara {
46
47 ProtocolAdmin::ProtocolAdmin() {
48 }
49
50 ProtocolAdmin::~ProtocolAdmin() {
51 }
52
53 ProtocolPtr ProtocolAdmin::clone(void) {
54     return std::make_shared<ProtocolAdmin>();
55 }
56
57 RequestPtr ProtocolAdmin::deserializeAdminCheckRequest(void) {
58     std::string clientId, userId, privilegeId;
59     PolicyBucketId startBucket;
60     bool recursive;
61
62     ProtocolDeserialization::deserialize(m_frameHeader, clientId);
63     ProtocolDeserialization::deserialize(m_frameHeader, userId);
64     ProtocolDeserialization::deserialize(m_frameHeader, privilegeId);
65     ProtocolDeserialization::deserialize(m_frameHeader, startBucket);
66     ProtocolDeserialization::deserialize(m_frameHeader, recursive);
67
68     LOGD("Deserialized AdminCheckRequest: clientId <%s>, userId <%s>, privilegeId <%s>, "
69          "startBucket <%s>, recursive [%d]", clientId.c_str(), userId.c_str(),
70          privilegeId.c_str(), startBucket.c_str(), recursive);
71
72     return std::make_shared<AdminCheckRequest>(PolicyKey(clientId, userId, privilegeId),
73                                                startBucket, recursive,
74                                                m_frameHeader.sequenceNumber());
75 }
76
77 RequestPtr ProtocolAdmin::deserializeEraseRequest(void) {
78     PolicyBucketId startBucket;
79     bool recursive;
80     PolicyKeyFeature::ValueType client, user, privilege;
81
82     ProtocolDeserialization::deserialize(m_frameHeader, startBucket);
83     ProtocolDeserialization::deserialize(m_frameHeader, recursive);
84     ProtocolDeserialization::deserialize(m_frameHeader, client);
85     ProtocolDeserialization::deserialize(m_frameHeader, user);
86     ProtocolDeserialization::deserialize(m_frameHeader, privilege);
87
88     LOGD("Deserialized EraseRequest: startBucket <%s>, recursive [%d], filter client <%s> "
89          "filter user <%s>, filter privilege <%s>", startBucket.c_str(),
90          static_cast<int>(recursive), client.c_str(), user.c_str(), privilege.c_str());
91
92     return std::make_shared<EraseRequest>(startBucket, recursive,
93                                           PolicyKey(client, user, privilege),
94                                           m_frameHeader.sequenceNumber());
95 }
96
97 RequestPtr ProtocolAdmin::deserializeInsertOrUpdateBucketRequest(void) {
98     PolicyBucketId policyBucketId;
99     PolicyType policyType;
100     PolicyResult::PolicyMetadata policyMetaData;
101
102     ProtocolDeserialization::deserialize(m_frameHeader, policyBucketId);
103     ProtocolDeserialization::deserialize(m_frameHeader, policyType);
104     ProtocolDeserialization::deserialize(m_frameHeader, policyMetaData);
105
106     LOGD("Deserialized InsertOrUpdateBucketRequest: bucketId <%s>, "
107          "result.type [%" PRIu16 "], result.meta <%s>", policyBucketId.c_str(),
108          policyType, policyMetaData.c_str());
109
110     return std::make_shared<InsertOrUpdateBucketRequest>(policyBucketId,
111             PolicyResult(policyType, policyMetaData), m_frameHeader.sequenceNumber());
112 }
113
114 RequestPtr ProtocolAdmin::deserializeListRequest(void) {
115     PolicyBucketId bucketId;
116     PolicyKeyFeature::ValueType client, user, privilege;
117
118     ProtocolDeserialization::deserialize(m_frameHeader, bucketId);
119     ProtocolDeserialization::deserialize(m_frameHeader, client);
120     ProtocolDeserialization::deserialize(m_frameHeader, user);
121     ProtocolDeserialization::deserialize(m_frameHeader, privilege);
122
123     LOGD("Deserialized ListRequest: bucketId <%s>, filter client <%s> filter user <%s>, filter "
124          "privilege <%s>", bucketId.c_str(), client.c_str(), user.c_str(), privilege.c_str());
125
126     return std::make_shared<ListRequest>(bucketId, PolicyKey(client, user, privilege),
127                                          m_frameHeader.sequenceNumber());
128 }
129
130 RequestPtr ProtocolAdmin::deserializeRemoveBucketRequest(void) {
131     PolicyBucketId policyBucketId;
132
133     ProtocolDeserialization::deserialize(m_frameHeader, policyBucketId);
134
135     LOGD("Deserialized RemoveBucketRequest: bucketId <%s>", policyBucketId.c_str());
136
137     return std::make_shared<RemoveBucketRequest>(policyBucketId, m_frameHeader.sequenceNumber());
138 }
139
140 RequestPtr ProtocolAdmin::deserializeSetPoliciesRequest(void) {
141     ProtocolFrameFieldsCount toBeInsertedOrUpdatedCount, toBeRemovedCount;
142     ProtocolFrameFieldsCount policyCount;
143     PolicyKeyFeature::ValueType clientId, user, privilege;
144     PolicyType policyType;
145     PolicyResult::PolicyMetadata metadata;
146     std::map<PolicyBucketId, std::vector<Policy>> toBeInsertedOrUpdatedPolicies;
147     std::map<PolicyBucketId, std::vector<PolicyKey>> toBeRemovedPolicies;
148
149     ProtocolDeserialization::deserialize(m_frameHeader, toBeInsertedOrUpdatedCount);
150     for (ProtocolFrameFieldsCount b = 0; b < toBeInsertedOrUpdatedCount; ++b) {
151         PolicyBucketId policyBucketId;
152         ProtocolDeserialization::deserialize(m_frameHeader, policyBucketId);
153         ProtocolDeserialization::deserialize(m_frameHeader, policyCount);
154         for (ProtocolFrameFieldsCount p = 0; p < policyCount; ++p) {
155             // PolicyKey
156             ProtocolDeserialization::deserialize(m_frameHeader, clientId);
157             ProtocolDeserialization::deserialize(m_frameHeader, user);
158             ProtocolDeserialization::deserialize(m_frameHeader, privilege);
159             // PolicyResult
160             ProtocolDeserialization::deserialize(m_frameHeader, policyType);
161             ProtocolDeserialization::deserialize(m_frameHeader, metadata);
162
163             toBeInsertedOrUpdatedPolicies[policyBucketId].push_back(
164                     Policy(PolicyKey(clientId, user, privilege),
165                     PolicyResult(policyType, metadata)));
166         }
167     }
168
169     ProtocolDeserialization::deserialize(m_frameHeader, toBeRemovedCount);
170     for (ProtocolFrameFieldsCount b = 0; b < toBeRemovedCount; ++b) {
171         PolicyBucketId policyBucketId;
172         ProtocolDeserialization::deserialize(m_frameHeader, policyBucketId);
173         ProtocolDeserialization::deserialize(m_frameHeader, policyCount);
174         for (ProtocolFrameFieldsCount p = 0; p < policyCount; ++p) {
175             // PolicyKey
176             ProtocolDeserialization::deserialize(m_frameHeader, clientId);
177             ProtocolDeserialization::deserialize(m_frameHeader, user);
178             ProtocolDeserialization::deserialize(m_frameHeader, privilege);
179
180             toBeRemovedPolicies[policyBucketId].push_back(PolicyKey(clientId, user, privilege));
181         }
182     }
183
184     LOGD("Deserialized SetPoliciesRequestPtr: insertOrUpdate count [%" PRIu16 "], "
185          "remove count [%" PRIu16 "]", toBeInsertedOrUpdatedCount, toBeRemovedCount);
186
187     return std::make_shared<SetPoliciesRequest>(toBeInsertedOrUpdatedPolicies,
188                                                 toBeRemovedPolicies,
189                                                 m_frameHeader.sequenceNumber());
190 }
191
192 RequestPtr ProtocolAdmin::extractRequestFromBuffer(BinaryQueuePtr bufferQueue) {
193     ProtocolFrameSerializer::deserializeHeader(m_frameHeader, bufferQueue);
194
195     if (m_frameHeader.isFrameComplete()) {
196         ProtocolOpCode opCode;
197
198         m_frameHeader.resetState();
199         ProtocolDeserialization::deserialize(m_frameHeader, opCode);
200         LOGD("Deserialized opCode [%" PRIu8 "]", opCode);
201         switch (opCode) {
202         case OpAdminCheckRequest:
203             return deserializeAdminCheckRequest();
204         case OpEraseRequest:
205             return deserializeEraseRequest();
206         case OpInsertOrUpdateBucket:
207             return deserializeInsertOrUpdateBucketRequest();
208         case OpListRequest:
209             return deserializeListRequest();
210         case OpRemoveBucket:
211             return deserializeRemoveBucketRequest();
212         case OpSetPolicies:
213             return deserializeSetPoliciesRequest();
214         default:
215             throw InvalidProtocolException(InvalidProtocolException::WrongOpCode);
216             break;
217         }
218     }
219
220     return nullptr;
221 }
222
223 ResponsePtr ProtocolAdmin::deserializeAdminCheckResponse(void) {
224     PolicyType result;
225     PolicyResult::PolicyMetadata additionalInfo;
226     bool bucketValid;
227
228     ProtocolDeserialization::deserialize(m_frameHeader, result);
229     ProtocolDeserialization::deserialize(m_frameHeader, additionalInfo);
230     ProtocolDeserialization::deserialize(m_frameHeader, bucketValid);
231
232     const PolicyResult policyResult(result, additionalInfo);
233
234     LOGD("Deserialized AdminCheckResponse: result [%" PRIu16 "], metadata <%s>, bucketValid [%d]",
235          policyResult.policyType(), policyResult.metadata().c_str(), static_cast<int>(bucketValid));
236
237     return std::make_shared<AdminCheckResponse>(policyResult, bucketValid,
238                                                 m_frameHeader.sequenceNumber());
239 }
240
241 ResponsePtr ProtocolAdmin::deserializeCodeResponse(void) {
242     ProtocolResponseCode responseCode;
243     ProtocolDeserialization::deserialize(m_frameHeader, responseCode);
244
245     LOGD("Deserialized CodeResponse: code [%" PRIu16 "], ", responseCode);
246
247     return std::make_shared<CodeResponse>(static_cast<CodeResponse::Code>(responseCode),
248                                           m_frameHeader.sequenceNumber());
249 }
250
251 ResponsePtr ProtocolAdmin::deserializeListResponse(void) {
252     ProtocolFrameFieldsCount policiesCount;
253     PolicyKeyFeature::ValueType client, user, privilege;
254     PolicyType policyType;
255     PolicyResult::PolicyMetadata metadata;
256     std::vector<Policy> policies;
257
258     ProtocolDeserialization::deserialize(m_frameHeader, policiesCount);
259     policies.reserve(policiesCount);
260
261     for (ProtocolFrameFieldsCount p = 0; p < policiesCount; ++p) {
262         // PolicyKey
263         ProtocolDeserialization::deserialize(m_frameHeader, client);
264         ProtocolDeserialization::deserialize(m_frameHeader, user);
265         ProtocolDeserialization::deserialize(m_frameHeader, privilege);
266         // PolicyResult
267         ProtocolDeserialization::deserialize(m_frameHeader, policyType);
268         ProtocolDeserialization::deserialize(m_frameHeader, metadata);
269
270         policies.push_back(Policy(PolicyKey(client, user, privilege),
271                                         PolicyResult(policyType, metadata)));
272     }
273
274     bool isBucketValid;
275     ProtocolDeserialization::deserialize(m_frameHeader, isBucketValid);
276
277     LOGD("Deserialized ListResponse: number of policies [%" PRIu16 "], isBucketValid [%d]",
278          policiesCount, isBucketValid);
279
280     return std::make_shared<ListResponse>(policies, isBucketValid, m_frameHeader.sequenceNumber());
281 }
282
283 ResponsePtr ProtocolAdmin::extractResponseFromBuffer(BinaryQueuePtr bufferQueue) {
284     ProtocolFrameSerializer::deserializeHeader(m_frameHeader, bufferQueue);
285
286     if (m_frameHeader.isFrameComplete()) {
287         ProtocolOpCode opCode;
288
289         m_frameHeader.resetState();
290         ProtocolDeserialization::deserialize(m_frameHeader, opCode);
291         LOGD("Deserialized opCode [%" PRIu8 "]", opCode);
292         switch (opCode) {
293         case OpAdminCheckPolicyResponse:
294             return deserializeAdminCheckResponse();
295         case OpCodeResponse:
296             return deserializeCodeResponse();
297         case OpListResponse:
298             return deserializeListResponse();
299         default:
300             throw InvalidProtocolException(InvalidProtocolException::WrongOpCode);
301             break;
302         }
303     }
304
305     return nullptr;
306 }
307
308 void ProtocolAdmin::execute(RequestContextPtr context, AdminCheckRequestPtr request) {
309     LOGD("Serializing AdminCheckRequest: client <%s>, user <%s>, privilege <%s>, "
310          "startBucket <%s>, recursive [%d]", request->key().client().value().c_str(),
311          request->key().user().value().c_str(), request->key().privilege().value().c_str(),
312          request->startBucket().c_str(), request->recursive());
313
314     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
315
316     ProtocolSerialization::serialize(frame, OpAdminCheckRequest);
317     ProtocolSerialization::serialize(frame, request->key().client().value());
318     ProtocolSerialization::serialize(frame, request->key().user().value());
319     ProtocolSerialization::serialize(frame, request->key().privilege().value());
320     ProtocolSerialization::serialize(frame, request->startBucket());
321     ProtocolSerialization::serialize(frame, request->recursive());
322
323     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
324 }
325
326 void ProtocolAdmin::execute(RequestContextPtr context, EraseRequestPtr request) {
327     LOGD("Serializing EraseRequest: sequenceNumber [%" PRIu16 "], startBucket <%s>, "
328          "recursive [%d], filter client <%s> filter user <%s> filter privilege <%s>",
329          request->sequenceNumber(), request->startBucket().c_str(),
330          static_cast<int>(request->recursive()), request->filter().client().value().c_str(),
331          request->filter().user().value().c_str(), request->filter().privilege().value().c_str());
332
333     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
334
335     ProtocolSerialization::serialize(frame, OpEraseRequest);
336     ProtocolSerialization::serialize(frame, request->startBucket());
337     ProtocolSerialization::serialize(frame, request->recursive());
338     ProtocolSerialization::serialize(frame, request->filter().client().value());
339     ProtocolSerialization::serialize(frame, request->filter().user().value());
340     ProtocolSerialization::serialize(frame, request->filter().privilege().value());
341
342     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
343 }
344
345 void ProtocolAdmin::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) {
346     LOGD("Serializing InsertOrUpdateBucketRequest: sequenceNumber [%" PRIu16 "], bucketId <%s>, "
347          "result.type [%" PRIu16 "], result.meta <%s>", request->sequenceNumber(),
348          request->bucketId().c_str(), request->result().policyType(),
349          request->result().metadata().c_str());
350
351     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
352
353     ProtocolSerialization::serialize(frame, OpInsertOrUpdateBucket);
354     ProtocolSerialization::serialize(frame, request->bucketId());
355     ProtocolSerialization::serialize(frame, request->result().policyType());
356     ProtocolSerialization::serialize(frame, request->result().metadata());
357
358     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
359 }
360
361 void ProtocolAdmin::execute(RequestContextPtr context, ListRequestPtr request) {
362     LOGD("Serializing ListRequest: sequenceNumber [%" PRIu16 "], bucketId <%s>, "
363          "filter client <%s> filter user <%s> filter privilege <%s>", request->sequenceNumber(),
364          request->bucket().c_str(), request->filter().client().value().c_str(),
365          request->filter().user().value().c_str(), request->filter().privilege().value().c_str());
366
367     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
368
369     ProtocolSerialization::serialize(frame, OpListRequest);
370     ProtocolSerialization::serialize(frame, request->bucket());
371     ProtocolSerialization::serialize(frame, request->filter().client().value());
372     ProtocolSerialization::serialize(frame, request->filter().user().value());
373     ProtocolSerialization::serialize(frame, request->filter().privilege().value());
374
375     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
376 }
377
378 void ProtocolAdmin::execute(RequestContextPtr context, RemoveBucketRequestPtr request) {
379     LOGD("Serializing RemoveBucketRequest: sequenceNumber [%" PRIu16 "], bucketId <%s>",
380          request->sequenceNumber(), request->bucketId().c_str());
381
382     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
383
384     ProtocolSerialization::serialize(frame, OpRemoveBucket);
385     ProtocolSerialization::serialize(frame, request->bucketId());
386
387     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
388 }
389
390 void ProtocolAdmin::execute(RequestContextPtr context, SetPoliciesRequestPtr request) {
391     LOGD("Serializing SetPoliciesRequestPtr: sequenceNumber [%" PRIu16 "], "
392          "insertOrUpdate count [%zu], remove count [%zu]", request->sequenceNumber(),
393          request->policiesToBeInsertedOrUpdated().size(), request->policiesToBeRemoved().size());
394
395     ProtocolFrame frame =
396             ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
397
398     ProtocolSerialization::serialize(frame, OpSetPolicies);
399
400     ProtocolSerialization::serialize(frame,
401             static_cast<ProtocolFrameFieldsCount>(request->policiesToBeInsertedOrUpdated().size()));
402     for (auto policyBucket : request->policiesToBeInsertedOrUpdated()) {
403         ProtocolSerialization::serialize(frame, policyBucket.first);
404         ProtocolSerialization::serialize(frame,
405                     static_cast<ProtocolFrameFieldsCount>(policyBucket.second.size()));
406         for (auto policy : policyBucket.second) {
407             // PolicyKey
408             ProtocolSerialization::serialize(frame, policy.key().client().value());
409             ProtocolSerialization::serialize(frame, policy.key().user().value());
410             ProtocolSerialization::serialize(frame, policy.key().privilege().value());
411             // PolicyResult
412             ProtocolSerialization::serialize(frame, policy.result().policyType());
413             ProtocolSerialization::serialize(frame, policy.result().metadata());
414         }
415     }
416
417     ProtocolSerialization::serialize(frame,
418             static_cast<ProtocolFrameFieldsCount>(request->policiesToBeRemoved().size()));
419     for (auto policyBucket : request->policiesToBeRemoved()) {
420         ProtocolSerialization::serialize(frame, policyBucket.first);
421         ProtocolSerialization::serialize(frame,
422                     static_cast<ProtocolFrameFieldsCount>(policyBucket.second.size()));
423         for (auto policyKey : policyBucket.second) {
424             // PolicyKey
425             ProtocolSerialization::serialize(frame, policyKey.client().value());
426             ProtocolSerialization::serialize(frame, policyKey.user().value());
427             ProtocolSerialization::serialize(frame, policyKey.privilege().value());
428         }
429     }
430
431     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
432 }
433
434 void ProtocolAdmin::execute(RequestContextPtr context, AdminCheckResponsePtr response) {
435     LOGD("Serializing AdminCheckResponse: op [%" PRIu8 "], sequenceNumber [%" PRIu16 "], "
436          "policyType [%" PRIu16 "], metadata <%s>, bucketValid [%d]", OpAdminCheckPolicyResponse,
437          response->sequenceNumber(), response->result().policyType(),
438          response->result().metadata().c_str(), static_cast<int>(response->isBucketValid()));
439
440     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(
441             response->sequenceNumber());
442
443     ProtocolSerialization::serialize(frame, OpAdminCheckPolicyResponse);
444     ProtocolSerialization::serialize(frame, response->result().policyType());
445     ProtocolSerialization::serialize(frame, response->result().metadata());
446     ProtocolSerialization::serialize(frame, response->isBucketValid());
447
448     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
449 }
450
451 void ProtocolAdmin::execute(RequestContextPtr context, CodeResponsePtr response) {
452     LOGD("Serializing CodeResponse: op [%" PRIu8 "], sequenceNumber [%" PRIu16 "], "
453          "code [%" PRIu16 "]", OpCodeResponse, response->sequenceNumber(), response->m_code);
454
455     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(
456             response->sequenceNumber());
457
458     ProtocolSerialization::serialize(frame, OpCodeResponse);
459     ProtocolSerialization::serialize(frame, static_cast<ProtocolResponseCode>(response->m_code));
460
461     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
462 }
463
464 void ProtocolAdmin::execute(RequestContextPtr context, ListResponsePtr response) {
465     ProtocolFrameFieldsCount policiesSize
466         = static_cast<ProtocolFrameFieldsCount>(response->policies().size());
467
468     LOGD("Serializing ListResponse: op [%" PRIu8 "], sequenceNumber [%" PRIu16 "], "
469          "number of policies [%" PRIu16 "], isBucketValid [%d]", OpListResponse,
470          response->sequenceNumber(), policiesSize, response->isBucketValid());
471
472     ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(response->sequenceNumber());
473
474     ProtocolSerialization::serialize(frame, OpListResponse);
475     ProtocolSerialization::serialize(frame, policiesSize);
476     for (auto &policy : response->policies()) {
477         // PolicyKey
478         ProtocolSerialization::serialize(frame, policy.key().client().value());
479         ProtocolSerialization::serialize(frame, policy.key().user().value());
480         ProtocolSerialization::serialize(frame, policy.key().privilege().value());
481         // PolicyResult
482         ProtocolSerialization::serialize(frame, policy.result().policyType());
483         ProtocolSerialization::serialize(frame, policy.result().metadata());
484     }
485     ProtocolSerialization::serialize(frame, response->isBucketValid());
486
487     ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue()));
488 }
489
490 } // namespace Cynara