Skip to content

Commit 6477839

Browse files
LOGBROKER-8891: fix inability to parse json into protobuf map in http_proxy
1 parent 9e4a92a commit 6477839

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

ydb/core/http_proxy/json_proto_conversion.h

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ inline void AddJsonObjectToProtoAsMap(
147147
const google::protobuf::Reflection* reflection,
148148
grpc::protobuf::Message* message,
149149
const JSON& jsonObject,
150+
ui32 depth,
150151
std::function<const MAP(const JSON&)> extractMap,
151-
std::function<const TString(const JSON&)> valueToString
152+
std::function<const TString(const JSON&)> valueToString,
153+
std::function<void(const JSON&, grpc::protobuf::Message*, ui32)> jsonObjectToMessage
152154
) {
153155
const auto& protoMap = reflection->GetMutableRepeatedFieldRef<google::protobuf::Message>(message, fieldDescriptor);
154156
for (const auto& [key, value] : extractMap(jsonObject)) {
@@ -160,46 +162,64 @@ inline void AddJsonObjectToProtoAsMap(
160162
stringStringEntry
161163
->GetReflection()
162164
->SetString(stringStringEntry.get(), fieldDescriptor->message_type()->field(0), key);
163-
stringStringEntry
164-
->GetReflection()
165-
->SetString(stringStringEntry.get(), fieldDescriptor->message_type()->field(1), valueToString(value));
165+
166+
if (fieldDescriptor->message_type()->field(1)->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
167+
auto *msg = stringStringEntry->GetReflection()->MutableMessage(stringStringEntry.get(), fieldDescriptor->message_type()->field(1));
168+
jsonObjectToMessage(value, msg, depth);
169+
} else if (fieldDescriptor->message_type()->field(1)->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_STRING) {
170+
stringStringEntry
171+
->GetReflection()
172+
->SetString(stringStringEntry.get(), fieldDescriptor->message_type()->field(1), valueToString(value));
173+
} else {
174+
throw NKikimr::NSQS::TSQSException(NKikimr::NSQS::NErrors::INVALID_PARAMETER_VALUE)
175+
<< "Only String and Object can be converted to protobuf map";
176+
}
166177
protoMap.Add(*stringStringEntry);
167178
}
168179
}
169180

181+
void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth = 0);
182+
170183
inline void AddJsonObjectToProtoAsMap(
171184
const google::protobuf::FieldDescriptor* fieldDescriptor,
172185
const google::protobuf::Reflection* reflection,
173186
grpc::protobuf::Message* message,
174-
const NJson::TJsonValue& jsonObject
187+
const NJson::TJsonValue& jsonObject,
188+
ui32 depth
175189
) {
176190
AddJsonObjectToProtoAsMap<NJson::TJsonValue, NJson::TJsonValue::TMapType>(
177191
fieldDescriptor,
178192
reflection,
179193
message,
180194
jsonObject,
195+
depth,
181196
[](auto& json) { return json.GetMap(); },
182-
[](auto& value) -> const TString { return value.GetString(); }
197+
[](auto& value) -> const TString { return value.GetString(); },
198+
[](auto& json, auto message, auto depth) { JsonToProto(json, message, depth); }
183199
);
184200
}
201+
void NlohmannJsonToProto(const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth = 0);
185202

186203
inline void AddJsonObjectToProtoAsMap(
187204
const google::protobuf::FieldDescriptor* fieldDescriptor,
188205
const google::protobuf::Reflection* reflection,
189206
grpc::protobuf::Message* message,
190-
const nlohmann::basic_json<>& jsonObject
207+
const nlohmann::basic_json<>& jsonObject,
208+
ui32 depth
191209
) {
192210
AddJsonObjectToProtoAsMap<nlohmann::basic_json<>, std::map<TString, nlohmann::basic_json<>>>(
193211
fieldDescriptor,
194212
reflection,
195213
message,
196214
jsonObject,
215+
depth,
197216
[](auto& json) { return json.template get<std::map<TString, nlohmann::basic_json<>>>(); },
198-
[](auto& value) -> const TString { return value.template get<TString>(); }
217+
[](auto& value) -> const TString { return value.template get<TString>(); },
218+
[](auto& json, auto message, auto depth) { NlohmannJsonToProto(json, message, depth); }
199219
);
200220
}
201221

202-
inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth = 0) {
222+
inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth) {
203223
Y_ENSURE(depth < 101, "Json depth is > 100");
204224
Y_ENSURE_EX(
205225
!jsonValue.IsNull(),
@@ -348,7 +368,7 @@ inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message*
348368
break;
349369
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
350370
if (fieldDescriptor->is_map()) {
351-
AddJsonObjectToProtoAsMap(fieldDescriptor, reflection, message, value);
371+
AddJsonObjectToProtoAsMap(fieldDescriptor, reflection, message, value, depth);
352372
} else {
353373
auto *msg = reflection->MutableMessage(message, fieldDescriptor);
354374
JsonToProto(value, msg, depth + 1);
@@ -366,7 +386,7 @@ inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message*
366386
}
367387
}
368388

369-
inline void NlohmannJsonToProto(const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth = 0) {
389+
inline void NlohmannJsonToProto(const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth) {
370390
Y_ENSURE(depth < 101, "Json depth is > 100");
371391
Y_ENSURE_EX(
372392
!jsonValue.is_null(),
@@ -518,7 +538,7 @@ inline void NlohmannJsonToProto(const nlohmann::json& jsonValue, NProtoBuf::Mess
518538
break;
519539
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
520540
if (fieldDescriptor->is_map()) {
521-
AddJsonObjectToProtoAsMap(fieldDescriptor, reflection, message, value);
541+
AddJsonObjectToProtoAsMap(fieldDescriptor, reflection, message, value, depth);
522542
} else {
523543
auto *msg = reflection->MutableMessage(message, fieldDescriptor);
524544
NlohmannJsonToProto(value, msg, depth + 1);

ydb/core/http_proxy/ut/http_proxy_ut.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,15 @@ Y_UNIT_TEST_SUITE(TestHttpProxy) {
18861886
message0["MessageBody"] = "MessageBody-0";
18871887
message0["MessageDeduplicationId"] = "MessageDeduplicationId-0";
18881888

1889+
NJson::TJsonValue delaySeconds;
1890+
delaySeconds["StringValue"] = "1";
1891+
delaySeconds["DataType"] = "String";
1892+
1893+
NJson::TJsonValue attributes;
1894+
attributes["DelaySeconds"] = delaySeconds;
1895+
1896+
message0["MessageAttributes"] = attributes;
1897+
18891898
NJson::TJsonValue message1;
18901899
message1["Id"] = "Id-1";
18911900
message1["MessageBody"] = "MessageBody-1";
@@ -1903,6 +1912,7 @@ Y_UNIT_TEST_SUITE(TestHttpProxy) {
19031912
UNIT_ASSERT(json["Successful"].GetArray().size() == 2);
19041913
auto succesful0 = json["Successful"][0];
19051914
UNIT_ASSERT(succesful0["Id"] == "Id-0");
1915+
UNIT_ASSERT(!GetByPath<TString>(succesful0, "Md5OfMessageAttributes").empty());
19061916
UNIT_ASSERT(!GetByPath<TString>(succesful0, "Md5OfMessageBody").empty());
19071917
UNIT_ASSERT(!GetByPath<TString>(succesful0, "MessageId").empty());
19081918
}

ydb/services/ymq/ymq_proxy.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ namespace NKikimr::NYmq::V1 {
764764
} else {
765765
auto currentSuccessful = result.Addsuccessful();
766766
currentSuccessful->Setid(entry.GetId());
767+
currentSuccessful->Setmd5_of_message_attributes(entry.GetMD5OfMessageAttributes());
767768
currentSuccessful->Setmd5_of_message_body(entry.GetMD5OfMessageBody());
768769
currentSuccessful->Setmessage_id(entry.GetMessageId());
769770
currentSuccessful->Setsequence_number(std::to_string(entry.GetSequenceNumber()));

0 commit comments

Comments
 (0)