I know there is a way to serialize a message in protobuf. But is there a easy way to print out the values in a protobuf message? Something like a toString() method in Java?
Thanks.
protocol buffer basics -- Java
quoted from the link, check the standard message methods:
Standard Message Methods
Each message and builder class also contains a number of other methods that let you check or manipulate the entire message, including:
isInitialized(): checks if all the required fields have been set.
toString(): returns a human-readable representation of the message, particularly useful for debugging.
mergeFrom(Message other): (builder only) merges the contents of other into this message, overwriting singular fields and concatenating repeated ones.
clear(): (builder only) clears all the fields back to the empty state.
Related
Consider the following protobuf:
message SendRequest {
/** The raw text of the message that the caller wishes to send. */
optional string message = 1;
}
Note that the string message is being used as a field name. The protobuf compilers seems to be fine with this, even though message is the protobuf keyword.
Is this usage kosher in the sense that keywords are defined by some standard to be ignored in field names, or could this break my application in the future?
Yes, it is possible because in runtime a proto field is identified by their id (in your case 1) and not with their name.
I'm building a microservice system with multiple disconnected components, and I'm currently trying to find out how to implement knowing which fields on an object should be updated based on the protobuf data provided.
The flow is this:
The client sends a JSON-request to an API.
The API translates the JSON-data into a protobuf struct, which is then sent along to the microservice responsible for handling it.
The microservice receives the data from the API and performs any action on it, in this case, I'm trying to change a single value in a MySQL table, such as a client's email address.
Now, the problem I have is that since protobuf (understandably) doesn't allow pointers, the protobuf object will contain zero-values for everything not provided. This means that if a customer wants to update their email address, I can't know if they also set IncludeInMailLists to false - or if it was simply not provided (having its zero-value) and shouldn't change.
The question is: how will I - from the protobuf object - know if a value is expressively set to 0, or just not provided?
My current solution is pretty much having a special UpdateCustomer-object which also has an array of Fields specifying which fields the microservice should care about, but it feels like bad solution.
Someone must have solved this better already. How should I implement it?
Protobufs field masks are one way.
https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.FieldMask
https://github.com/golang/protobuf/issues/225
But if you are using grpc then there's a (sort of) built in way.
Grpc wrappers
Since proto3 (protobufs v3) there's been no distinction between a primitive that is not set, and a primitive that's been set to the "zero value" (false, 0, "", etc).
Instead you can use objects or in protobufs language a "message", as objects can be nil / null. You've not mentioned what language you are working in but hopefully these examples make sense.
Given an RPC service such as:
import "google/protobuf/wrappers.proto";
service Users {
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse)
}
message UpdateUserRequest {
int32 user_id = 1;
google.protobuf.StringValue email = 2;
}
message UpdateUserResponse {}
Note the import "google/protobuf/wrappers.proto"; is important.
It given you access to the google protobufs wrappers source code here. These are not objects that have methods that allow you to test for presence.
Grpc generated code in java gives you methods such as .hasEmail() which returns true if the value is present. The getter on an unset value will still return you the zero value. I think the golang version uses pointers that you can test for nil instead of an explicit hasX() method.
More info / discussion in this github issue
I am in reference to the following method from BindingResult:
BindingResult.html#resolveMessageCodes(java.lang.String, java.lang.String)
I am trying to figure out the difference between an error code and a message code. Can someone please provide an example, especially one that would illustrate why there could be several message codes for a given error code?
Because web applications are internationalized, when you reject an object and want to have a message displayed for it, you don't use a hardcoded text because that will show the same no matter the language.
Instead, you specify an error code that later server as a key to retrieving the proper message from the bundles (and now the error code is a message code from the point of view of the method that must find the proper message text).
Your error code resolves to more message codes because Spring (based on the implementation) adds some additional ones for you. Here is a snippet from the Spring documentation:
[...] What error codes it registers is determined by the MessageCodesResolver that is used. By default, the DefaultMessageCodesResolver is used, which for example not only registers a message with the code you gave, but also messages that include the field name you passed to the reject method. So in case you reject a field using rejectValue("age", "too.darn.old"), apart from the too.darn.old code, Spring will also register too.darn.old.age and too.darn.old.age.int (so the first will include the field name and the second will include the type of the field); this is done as a convenience to aid developers in targeting error messages and suchlike. [...]
The last statement is the reason there are more message codes, to have control on the message that is displayed to the user, from a generic one (e.g. "Value required") to a more specific one given the context (e.g. "A value is required for field XXX").
The javadoc for DefaultMessageCodesResolver explains it further and gives an example:
For example, in case of code "typeMismatch", object name "user", field "age":
try "typeMismatch.user.age"
try "typeMismatch.age"
try "typeMismatch.int"
try "typeMismatch"
This resolution algorithm thus can be leveraged for example to show specific messages for binding errors like "required" and "typeMismatch":
at the object + field level ("age" field, but only on "user");
at the field level (all "age" fields, no matter which object name);
or at the general level (all fields, on any object).
In on_message() method of SockJS-Tornado library, I want to send JSON messages to clients: sometimes to specific clients using send() method, and sometimes to a group of clients using broadcast() method.
I wonder whether I need to use something like simplejson to encode string-keyed dictionary object myself before sending the message, i.e.
on_message(self, message):
...
data = {'type': 1, 'body': 'blah'}
msg = json.dump(data)
# self.send(msg) or self.broadcast(conns, msg)
Or the encoding part is already taken care of by SockJS-Tornado? In addition, is it true that message argument in on_message() method is always also a JSON object?
SockJS is websocket emulation layer. Websockets don't support anything except of text and binary data.
So, while you can send arbitrary python object over the wire (sockjs-tornado will do internal json serialization and does not enforce strings), this is discouraged for compatibility reasons.
Yes, double encoding will happen if json is used as a application protocol. However, if you're going to have broadcast functionality - use optimized broadcast() method, it will do json-encoding only once for all recipients.
There was related discussion in mailing list as well: https://groups.google.com/forum/?fromgroups#!topic/sockjs/vsFvHqppq5g
I'm trying to find a good way to do field validation in a WebObjects app. If I have a text field and I tie a number formatter to it, it seems that the default behavior is to parse out the number IF the user enters in a valid number, or, if the user enters an invalid number, it seems to just ignore the value entered by the user. I can't do the validation in a save method or an action method because WO will have already ignored the non-number input by the time it reaches the action method. Is there a standard/recommended way, in a WebObjects app, of validating user input such that the user can be alerted of invalid input, rather than just ignoring the invalid input?
This page: http://en.wikibooks.org/wiki/WebObjects/EOF/Using_EOF/Validation claims that WO and EOF have "an incredible array of validation mechanisms" and even hints that there is a built-in way to prevent the user from entering inappropriate data, but I haven't been able to find any documentation or examples of how to do that (if there is, in fact, a built-in way). Coming up with a custom javascript validator to prevent inappropriate data seems like it would be a nightmare - finding a way to make the JS recognize and handle all of the same edge cases that the backend formatters/parsers handle. It would be nice if WO really did have a built-in way to propagate the formatter edge cases over to JS validation.
The above link also says there is a validationFailedWithException method in WOComponent that gets called "when an EO or formatter failed validation during an assignment", but how can I make a formatter fail validation in the non-number example case above? I've tried having the formatter throw an exception in the parse method if a non-number is entered, but that exception doesn't get passed to the validationFailedWithException method. Does anyone know how I can trigger an exception in a formatter that will trigger a call to validationFailedWithException()? And is that even the best/recommended way? Does anyone know of a better way?
I'm pretty sure, that validationFailedWithException is getting called for every formatting error. You should receive there an NSValidationException that wraps a ParseException. The method is usually called on the component containing the binding. It may get skipped on caret (^) bindings.
All the standard number formatter already throw a ParseException (see Format.parse(String)).
The validation handling in WebObjects can get quite complex, it really depends on your needs. But it was designed without JavaScript or Ajax in mind. Newer approaches in Wonder may incorporate the client side, but I have no experience with it.
The normal validation sequence is:
if needed convert the input into the target type with a formatter
call a validateAttributeName method on the target object, where AttributeName is the attribute name to receive the value
When something fails in this sequence validationFailedWithException is called.
While saving an enterprise object "validateFor..." is called on the objects. An exception at this point has to be caught in your action method.
So you have two points to handle validation errors. The "syntactical" errors have to be handled in validationFailedWithException. After this point you have valid inputs. You may manually further check those or greater object structures in your action method or in validateFor... (e.g. validateForSave).