Remove empty message proto from another proto when using JsonFormat.Printer - protobuf-java

I'm trying to remove empty message proto from another proto after setting empty proto as we see here :
TestProto test = TestProto.newBuilder().setCertification(CompanyCertification.newBuilder().build()).build();
String output = JsonFormat.printer().print(test);
System.out.println(output);
the output is:
{
"certification": {
}
}
how can I get only {} without the empty certification proto?
the messages proto :
message TestProto{
CompanyCertification certification = 1;
}
message CompanyCertification{
bool certified = 1;
int64 certificationDate = 2;
}

Related

gRPC nodejs client can't send request to server because of serialization failure

I'm currently working on implementing a gRPC nodejs client that should communicate with a java/kotlin gRPC server to test out the cross language codegen.
However when I try to make a call from my nodejs code I get a serialization failure and I have no idea why this is happening.
I've added as much as I can share, if you need any other code snippets, just ask.
I don't use any proto-loader, but rather have a buf-build setup that generates the code in typescript and Java.
The exact error being displayed is:
Error: 13 INTERNAL: Request message serialization failure: Expected argument of type com.example.resources.chat.v1.GetActiveChatSessionsRequest
If anyone could point me into the right direction or can help me out, would be greatly appreciated
Proto definition
syntax = "proto3";
package com.example.resources.chat.v1;
option java_package = "com.example.resources.chat.v1";
import "google/protobuf/timestamp.proto";
message ChatRoomOverviewItem {
string support_ticket_id = 1;
string chat_room_id = 2;
int32 number_of_unread_messages = 3;
google.protobuf.Timestamp last_message_received = 4;
repeated string participants = 5;
}
message GetActiveChatSessionsRequest {
string participant_id = 1;
int32 page = 2;
int32 limit = 3;
}
message GetActiveChatSessionsResponse {
bool last = 1;
int32 total_elements = 2;
int32 total_pages = 3;
int32 number_of_elements = 4;
bool first = 5;
int32 number = 6;
bool empty = 7;
repeated ChatRoomOverviewItem content = 8;
}
gRPC definition
syntax = "proto3";
package com.example.resources.chat.v1;
option java_package = "com.example.resources.chat.v1";
import "com/example/resources/chat/v1/chat.proto";
service ChatApiService {
rpc GetActiveChatSessions (GetActiveChatSessionsRequest) returns (GetActiveChatSessionsResponse);
}
NodeJS - Client
export const chatService = new ChatApiServiceClient(
process.env.CHAT_GRPC_URI || 'http://localhost:6565', ChannelCredentials.createInsecure())
---
chatApiService.getActiveChatSessions(new GetActiveChatSessionsRequest()
.setParticipantId(userId)
.setPage(req.params.page ? parseInt(req.params.page) : 0)
.setLimit(req.params.limit ? parseInt(req.params.init) : 25),
async (error, response) => {
if (error) throw error
else {
/* handle logic */
}
})
Kotlin - Server
#GRpcService
class ChatApiService(
private val streamObserverHandler: GrpcStreamObserverHandler,
private val chatRoomService: ChatRoomService,
private val chatMessageService: ChatMessageService
) : ChatApiServiceImplBase() {
override fun getActiveChatSessions(
request: Chat.GetActiveChatSessionsRequest,
responseObserver: StreamObserver<Chat.GetActiveChatSessionsResponse>
) {
streamObserverHandler.accept(
chatRoomService.getActiveChatRoomsForUser(
UUID.fromString(request.participantId),
PageRequest.of(request.page, request.limit)
),
responseObserver
)
}

Member Variables in Class Get Blown Away When Using std::thread

I have defined a base class using std::thread. For the child class, I perform some initialization of member variables and then start the thread using m_thread.reset(new std::thread(&MyClass::ThreadMain, this)); where m_thread is a member of MyClass. The purpose of the class is to read data from a serial port and report to a parent. The posix message queue handle of the parent is passed to MyClass during initialization before the thread is created. On running I get exceptions and I see that member variables that were initialized before the thread started appear to be no longer valid using the watch in GDB.
It appears as if the first message on the serial port is received and passed validation in order to get to the SendToParent call. At this call, it appears that I lose the stack. I tried running cppcheck to see if I have any memory leaks or buffer overflows and found nothing.
void MyClass::ThreadMain(void)
{
ssize_t bytesRead = 0;
UINT8 buffer[256];
UINT8 message[256];
BOOL partialMessage = FALSE;
UINT8 messageIndex = 0;
UINT8 payloadLength = 0;
// read data from the UART
while(1)
{
// the UART is setup to pend until data is available
bytesRead = read(m_radioFileDescriptor, buffer, sizeof(buffer));
if (FAIL == bytesRead)
{
LOG_SYSTEM_INFO("UART Read interrupted by a system call");
}
else if (bytesRead > 0)
{
// build the message
for(ssize_t i = 0 ; i < bytesRead ; i++)
{
if (FALSE == partialMessage)
{
// have we found the start of the message?
if(START_BYTE == buffer[i])
{
// start of new message
messageIndex = 0;
message[messageIndex] = buffer[i];
partialMessage = TRUE;
messageIndex++;
}
}
else
{
// keep building the message until the expected length is reached
if(LENGTH_POSITION == messageIndex)
{
// capture the expected message length
message[messageIndex] = buffer[i];
messageIndex++;
payloadLength = buffer[i];
}
else
{
message[messageIndex] = buffer[i];
messageIndex++;
// check for expected length and end byte
if((messageIndex == payloadLength) && (END_BYTE == buffer[i]))
{
// this should be a valid message but need to confirm by checking for a valid checksum
UINT8 messageChecksum = message[messageIndex - CHKSUM_POS_FROM_END];
UINT8 calculatedChecksum = RadioProtocol::Instance().GenerateRadioChecksum(message, (payloadLength - CHKSUM_POS_FROM_END));
if (messageChecksum == calculatedChecksum)
{
SendToParent(message, payloadLength);
}
else
{
LOG_SYSTEM_ERROR("Checksum FAILURE");
}
// reset for the next message
partialMessage = FALSE;
messageIndex = 0;
}
else if((messageIndex == payloadLength) && (END_BYTE != buffer[i]))
{
// malformed message - throw out and look for start of next message
LOG_SYSTEM_ERROR("Bytes read exceeded expected message length");
partialMessage = FALSE;
messageIndex = 0;
}
}
}
} // end for loop of bytes read on the port
}
else
{
LOG_SYSTEM_INFO("Read returned 0 bytes which is unexpected");
}
}
}
void MyClass::SendToParent(UINT8* pMsg, UINT8 size)
{
if ((pMsg != NULL) && (m_parentQueueHandle > 0))
{
// message is valid - pass up for processing
MsgQueueMessage msgToSend;
msgToSend.m_msgHeader = UART_MESSASGE;
bzero(msgToSend.m_msgData, sizeof(msgToSend.m_msgData));
for (UINT8 i = 0; i < size; i++)
{
msgToSend.m_msgData[i] = pMsg[i];
}
if (FAIL == msgsnd(m_parentQueueHandle, &msgToSend, sizeof(msgToSend), IPC_NOWAIT))
{
LOG_SYSTEM_ERROR("FAILED to send message on queue");
}
}
}
This acts like I am performing a buffer overflow but I just can't see it. When I set a breakpoint at the line UINT8 messageChecksum = message[messageIndex - CHKSUM_POS_FROM_END]; all data in the watch window appear valid. If I step over to the next line then the data, m_parentQueueHandle as an example, gets blown away.
This is my first time working with c++11 threads and particularly with c++. Any help or insights would be appreciated.
I think I found the issue. I added a bunch of printfs and found that the destructor for the class was being called. Much further upstreamI had the parent object being created as a local variable and it was going out of scope. This caused the child to go out of scope but the threads were still running. I certainly need to clean up the threads in the destructor.

Pass proto field which has value only

I have a service to pass input array of object to server using protobuf and successfully receive it on the server. The problem is I got the response according to the response definition. Here is the response
[ { uuid: '',
quantity: 3,
procurement_detail_uuid: '',
distribution_officer_uuid: '',
substore_uuid: '2343423443423' },
{ uuid: '',
quantity: 3,
procurement_detail_uuid: '',
distribution_officer_uuid: '',
substore_uuid: '676767' } ]
and here is the definition of the input
message ProcurementStockDistributionUpsertReqInput {
string uuid = 1;
int32 quantity = 2;
string procurement_detail_uuid = 3;
string distribution_officer_uuid = 4;
string substore_uuid = 5;
}
as you can see some of the fields are empty. I thought about using oneof
If you have a message with many optional fields and where at most one
field will be set at the same time, you can enforce this behavior and
save memory by using the oneof feature.
I thought oneof is the right way to optionally pass fields which has value but hit the error. Then I rollback my code like this
service Procurement {
rpc distributeUpsert (ProcurementStockDistributionUpsertReq) returns (ProcurementStockDistributionRes) {}
}
message ProcurementStockDistributionUpsertReq {
message ProcurementStockDistributionUpsertReqInput {
string uuid = 1;
int32 quantity = 2;
string procurement_detail_uuid = 3;
string distribution_officer_uuid = 4;
string substore_uuid = 5;
}
repeated ProcurementStockDistributionUpsertReqInput stocks = 1;
}
How to pre-omit those empty fields in proto

Cannot assign value of type '[NORScannedPeripheral]' to type '[third]'

I have downloaded a source code from https://github.com/NordicSemiconductor/IOS-nRF-Toolbox and I have added this to my project. Then I have created another class named "scanclassone" in my project and copied the codes in NORScannedPeripheral
to scan scanclassone.
Then I have came with an error "Cannot assign value of type '[NORScannedPeripheral]' to type '[scanclassone]'
func centralManagerDidUpdateState(_ central: CBCentralManager) {
guard central.state == .poweredOn else {
print("Bluetooth is porewed off")
return
}
let connectedPeripherals = self.getConnectedPeripherals()
var newScannedPeripherals: [NORScannedPeripheral] = []
connectedPeripherals.forEach { (connectedPeripheral: CBPeripheral) in
let connected = connectedPeripheral.state == .connected
let scannedPeripheral = NORScannedPeripheral(withPeripheral: connectedPeripheral, andIsConnected: connected )
newScannedPeripherals.append(scannedPeripheral)
}
peripherals = newScannedPeripherals
let success = self.scanForPeripherals(true)
if !success {
print("Bluetooth is powered off!")
}
}
I'm using Swift 4

Validate if a string in NSTextField is a valid IP address OR domain name

I have an NSTextField where I am asking a user to input a string that is either in IPv4 format, or a domain name such as www.example.com. Currently, my code is:
#IBAction func verifyTarget(sender: NSTextFieldCell) {
var txtTarget: NSTextFieldCell = sender
var strRawTarget: String? = txtTarget.stringValue
println("Input: " + strRawTarget!)
var URLTarget: NSURL?
URLTarget = NSURL.URLWithString(strRawTarget)
if URLTarget {
println("URL \(URLTarget) is valid!")
}
else {
println("URL \(strRawTarget) is not valid!")
}
}
Some example output:
Input:
URL is valid!
Input: adsfasdf
URL adsfasdf is valid!
Input: afe12389hfs. . afopadsf
URL afe12389hfs. . afopadsf is not valid!
Input: 192.292.111.3
URL 192.292.111.3 is valid!
Input: 0.a.0.a
URL 0.a.0.a is valid!
Input: %2
URL %2 is not valid!
Input: %20
URL %20 is valid!
Am I doing something wrong?
Check if IP address is IPv4 or IPv6 in Swift
func validateIpAddress(ipToValidate: String) -> Bool {
var sin = sockaddr_in()
var sin6 = sockaddr_in6()
if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 {
// IPv6 peer.
return true
}
else if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 {
// IPv4 peer.
return true
}
return false;
}
NSURL.URLWithString evaluates the URL string you pass it based on the criteria for decoding a relative or absolute address as laid out in these not-all-that-readable documents: RFCs 2396, 1738, and 1808. That is to say, what you're hoping to validate is only a small subset of what NSURL can handle. You're better off using a RegEx or two, perhaps from this answer:
#IBAction func verifyTarget(sender: NSTextFieldCell) {
var txtTarget: NSTextFieldCell = sender
var strRawTarget: String? = txtTarget.stringValue
println("Input: " + strRawTarget!)
let validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
let validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
if strRawTarget == nil {
println("no input!")
} else if strRawTarget!.rangeOfString(validIpAddressRegex, options: .RegularExpressionSearch) {
println("\(strRawTarget) is a valid IP address")
} else if strRawTarget!.rangeOfString(validHostnameRegex, options: .RegularExpressionSearch) {
println("\(strRawTarget) is a valid hostname")
} else {
println("\(strRawTarget) is not valid")
}
}
The code from #Alin in a more compact form:
extension String {
func isIPv4() -> Bool {
var sin = sockaddr_in()
return self.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1
}
func isIPv6() -> Bool {
var sin6 = sockaddr_in6()
return self.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1
}
func isIpAddress() -> Bool { return self.isIPv6() || self.isIPv4() }
}
Usage:
let ipv6 = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329"
let ipv6Collapsed = "FE80::0202:B3FF:FE1E:8329"
let ipv4 = "19.117.63.126"
ipv6.isIpAddress() //true
ipv6.isIPv6() //true
ipv6.isIPv4() //false
ipv6Collapsed.isIpAddress() //true
ipv6Collapsed.isIPv6() //true
ipv6Collapsed.isIPv4() //false
ipv4.isIpAddress() //true
ipv4.isIPv6() //false
ipv4.isIPv4() //true
The new Network framework has failable initializers for struct IPv4Address and struct IPv6Address which handle the IP address portion very easily. Doing this in IPv6 with a regex is tough with all the shortening rules.
Unfortunately I can't address the domain name part.
Note that Network framework is recent, so it may force you to compile for recent OS versions.
import Network
let tests = ["192.168.4.4","fkjhwojfw","192.168.4.4.4","2620:3","2620::33"]
for test in tests {
if let _ = IPv4Address(test) {
debugPrint("\(test) is valid ipv4 address")
} else if let _ = IPv6Address(test) {
debugPrint("\(test) is valid ipv6 address")
} else {
debugPrint("\(test) is not a valid IP address")
}
}
output:
"192.168.4.4 is valid ipv4 address"
"fkjhwojfw is not a valid IP address"
"192.168.4.4.4 is not a valid IP address"
"2620:3 is not a valid IP address"
"2620::33 is valid ipv6 address"
Updated to Swift 5.1 based on #Nate Cook response.
#IBAction func verifyTarget(sender: NSTextFieldCell) {
guard let strRawTarget = sender.stringValue else { print("no input!"); return }
print("Input: " + strRawTarget)
if strRawTarget.isValidIpAddress {
print("\(strRawTarget) is a valid IP address")
} else if strRawTarget.isValidHostname {
print("\(strRawTarget) is a valid hostname")
} else {
print("\(strRawTarget) is not valid")
}
}
enum Regex {
static let ipAddress = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
static let hostname = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
}
extension String {
var isValidIpAddress: Bool {
return self.matches(pattern: Regex.ipAddress)
}
var isValidHostname: Bool {
return self.matches(pattern: Regex.hostname)
}
private func matches(pattern: String) -> Bool {
return self.range(of: pattern,
options: .regularExpression,
range: nil,
locale: nil) != nil
}
}
#IBAction func verifyTarget(sender: NSTextFieldCell) -> Bool {
let validIP = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
if ((sender.stringValue.count == 0) || (sender.stringValue!.range(of: validIP, options: .regularExpression) == nil)) {
return false
}
return true
}
Try something like:
private static func validate(ipAddress: String) -> Bool {
return ipAddress.withCString({ cstring in
var addressV6 = sockaddr_in6()
var address = sockaddr_in()
return inet_pton(AF_INET6, cstring, &addressV6.sin6_addr) == 1 // IPv6.
|| inet_pton(AF_INET, cstring, &address.sin_addr) == 1 // IPv4.
});
}
Simply checks if it's accepted by sockaddr_in function as an IPv4 address, or by sockaddr_in6 as IPv6 address.
I wanted to check whether the string is an IP address or not, I found the following solution and it worked fine.
extension String {
/// Property tells whether a string is a valid IP or not
var isValidIpAddress: Bool {
let validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
let predicate = NSPredicate.init(format: "SELF MATCHES %#", validIpAddressRegex)
let matches = predicate.evaluate(with: self)
return matches
}
}
Usage:
string.isValidIpAddress

Resources