protobufjs load from string - node.js

I get a .proto definition as a string input, can I load it into a Root object straight from the string, for example the string might look like this
let protoStr = `syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}`
And I want to be able to load it
let searchRequest = protobuf.loadFromStr(protoStr)

Yes you can use protobuf.parse see https://github.com/protobufjs/protobuf.js/blob/master/examples/custom-get-set.js#L7-L12

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
)
}

Add Parameter in object

I am initialize object in node js
let obj = {};
let count = 0;
now adding in object
obj[count].Id = ID;
It will give me error that Id not defined
Solution is
let obj = [{}];
now it is working fine for me
I suppose you want to add Id property to "obj".
You can simply add it like :
obj["Id"] = ID;

Haxe Int to String

It seems AS3 has a toString() for the Number class. Is there an equivalent in Haxe? The only solution I could come up with for converting an Int to a String is a function like:
public function IntToString(i:Int):String {
var strbuf:StringBuf = new StringBuf();
strbuf.add(i);
return strbuf.toString();
}
Is there a better method that I'm overlooking?
You don't usually need to manually convert an int to a string because the conversion is automatic.
var i = 1;
var s = "" + i; // s is now "1"
The "formal" way to convert any value to a string is to use Std.string():
var s = Std.string(i);
You could also use string interpolation:
var s = '$i';
The function your wrote is fine but definitely overkilling.

ftp .net getdirectory size

hi i write method which must to know that is size of specified directory i get response from server which contains flags of file name size and other info and on the different ftp servers format of answer is different how to know format of answer?
unsigned long long GetFtpDirSize(String^ ftpDir) {
unsigned long long size = 0;
int j = 0;
StringBuilder^ result = gcnew StringBuilder();
StreamReader^ reader;
FtpWebRequest^ reqFTP;
reqFTP = (FtpWebRequest^)FtpWebRequest::Create(gcnew Uri(ftpDir));
reqFTP->UseBinary = true;
reqFTP->Credentials = gcnew NetworkCredential("anonymous", "123");
reqFTP->Method = WebRequestMethods::Ftp::ListDirectoryDetails;
reqFTP->KeepAlive = false;
reqFTP->UsePassive = false;
try {
WebResponse^ resp = reqFTP->GetResponse();
Encoding^ code;
code = Encoding::GetEncoding(1251);
reader = gcnew StreamReader(resp->GetResponseStream(), code);
String^ line = reader->ReadToEnd();
array<Char>^delimiters = gcnew array<Char>{
'\r', '\n'
};
array<Char>^delimiters2 = gcnew array<Char>{
' '
};
array<String^>^words = line->Split(delimiters, StringSplitOptions::RemoveEmptyEntries);
array<String^>^DetPr;
System::Collections::IEnumerator^ myEnum = words->GetEnumerator();
while ( myEnum->MoveNext() ) {
String^ word = safe_cast<String^>(myEnum->Current);
DetPr = word->Split(delimiters2);
}
}
Basically, you can't. You are interpreting the raw result and there is no defined format for this data (or is there any requirement that this data be returned at all in the response). And the FTP protocol does not define any other way of getting this.
What that leaves you with is a collection of parsing patterns for the server types you know about and working through them looking for valid data. Not entirely easy.

Using binary type of a UserProperty

For some reason I need to save some big strings into user profiles. Because a property with type string has a limit to 400 caracters I decited to try with binary type (PropertyDataType.Binary) that allow a length of 7500. My ideea is to convert the string that I have into binary and save to property.
I create the property using the code :
context = ServerContext.GetContext(elevatedSite);
profileManager = new UserProfileManager(context);
profile = profileManager.GetUserProfile(userLoginName);
Property newProperty = profileManager.Properties.Create(false);
newProperty.Name = "aaa";
newProperty.DisplayName = "aaa";
newProperty.Type = PropertyDataType.Binary;
newProperty.Length = 7500;
newProperty.PrivacyPolicy = PrivacyPolicy.OptIn;
newProperty.DefaultPrivacy = Privacy.Organization;
profileManager.Properties.Add(newProperty);
myProperty = profile["aaa"];
profile.Commit();
The problem is that when I try to provide the value of byte[] type to the property I receive the error "Unable to cast object of type 'System.Byte' to type 'System.String'.". If I try to provide a string value I receive "Invalid Binary Value: Input must match binary byte[] data type."
Then my question is how to use this binary type ?
The code that I have :
SPUser user = elevatedWeb.CurrentUser;
ServerContext context = ServerContext.GetContext(HttpContext.Current);
UserProfileManager profileManager = new UserProfileManager(context);
UserProfile profile = GetUserProfile(elevatedSite, currentUserLoginName);
UserProfileValueCollection myProperty= profile[PropertyName];
myProperty.Value = StringToBinary(GenerateBigString());
and the functions for test :
private static string GenerateBigString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 750; i++) sb.Append("0123456789");
return sb.ToString();
}
private static byte[] StringToBinary(string theSource)
{
byte[] thebytes = new byte[7500];
thebytes = System.Text.Encoding.ASCII.GetBytes(theSource);
return thebytes;
}
Have you tried with smaller strings? Going max on the first test might hide other behaviors. When you inspect the generated string in the debugger, it fits the requirements? (7500 byte[])
For those, who are looking for answer. You must use Add method instead:
var context = ServerContext.GetContext(elevatedSite);
var profileManager = new UserProfileManager(context);
var profile = profileManager.GetUserProfile(userLoginName);
profile["MyPropertyName"].Add(StringToBinary("your cool string"));
profile.Commit();

Resources