Protobuf and Pipeline questions - protocol-buffers

Is there any way to set more than one protobufEncoder/protobufDecoder?
Let me explain my problem.I have a command which will be send from the
client to the server,The server get the command and do some work according
to the command.Now the response ("answer") of the server could be:
for the length of string or is for the integer square (order not sure)
My question is now:what can I do that the client can receive at least two
different responses from the server? Both are "encoded" with Protobuf.And
in turn,what I need to do that the server can send at least two different
responses?Also both are "encoded" with Protobuf.both are "decoder" with protobuf.
ProtobufDecoder of netty to set two different protobufEncoder/Decoder is not possible.
Let us see below netty example, decoder can only receive a decoder object
LocalTimeServerPipelineFactory:
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline p = pipeline();
p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());
p.addLast("protobufDecoder", new ProtobufDecoder(LocalTimeProtocol.Locations.getDefaultInstance()));
p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());
p.addLast("protobufEncoder", new ProtobufEncoder());
p.addLast("handler", new LocalTimeServerHandler());
return p;
}
thanks in advance and best regards.
quartz

You can adjust the ChannelPipeline on the fly. This should help you there. Just add/remove the right one when you need it.

Related

gRPC client-side streaming with initial arguments

I'm creating client side streaming method which proto file definition should be looking similar to this:
service DataService {
rpc Send(stream SendRequest) returns (SendResponse) {}
}
message SendRequest {
string id = 1;
bytes data = 2;
}
message SendResponse {
}
The problem here is that ID is sent with each streaming message even it is needed only once. What's your recommendation and most optimal way for such a use cases?
One hacky approach would be to set ID only once within first message and after that left if blank. But this API is supposed to be used by third party and method definition like above doesn't explaining that well.
I don't think something like this is supported either:
service DataService {
rpc Send(InitialSendRequest, stream DataOnlyRequest) returns (SendResponse) {}
}
I'm currently considering SendRequest message to be something like this, but will have to check how optimal is this compared to the first case considering proto marshaling:
message SendRequest {
oneof request{
string id = 1;
bytes data = 2;
}
}
Your approach of using a oneof with the fields clearly documented saying id is expected only in the first message on the stream and that server implementations will terminate the stream if id is set on subsequent messages on the stream sounds good to me.
The following is a usage of the above described pattern in grpc-lb-v1. Even though the grpc team is moving away from grpc-lb-v1, the above mentioned pattern is a commonly used one.
I'm not very sure about its implications with respect to proto marshaling. That might be a question for the protobuf team.
Hope this helps.

Aws integration spring: Extend Visibility Timeout

Is it possible to extend the visibility time out of a message that is in flight.
See:
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html.
Section: Changing a Message's Visibility Timeout.
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sqs/AmazonSQSClient.html#changeMessageVisibility-com.amazonaws.services.sqs.model.ChangeMessageVisibilityRequest-
In summary I want to be able to extend the first set visibility timeout for a given message that is in flight.
Example if 15secs have passed I then want to extend the timeout by another 20secs. Better example in java docs above.
From my understanding in the links above you can do this on the amazon side.
Below are my current settings;
SqsMessageDrivenChannelAdapter adapter =
new SqsMessageDrivenChannelAdapter(queue);
adapter.setMessageDeletionPolicy(SqsMessageDeletionPolicy.ON_SUCCESS);
adapter.setMaxNumberOfMessages(1);
adapter.setSendTimeout(2000);
adapter.setVisibilityTimeout(200);
adapter.setWaitTimeOut(20);
Is it possible to extend this timeout?
Spring Cloud AWS supports this starting with Version 2.0. Injecting a Visiblity parameter in your SQS listener method does the trick:
#SqsListener(value = "my-sqs-queue")
void onMessageReceived(#Payload String payload, Visibility visibility) {
...
var extension = visibility.extend(20);
...
}
Note, that extend will work asynchronously and will return a Future. So if you want to be sure further down the processing, that the visibility of the message is really extended at the AWS side of things, either block on the Future using extension.get() or query the Future with extension.isDone()
OK. Looks like I see your point.
We can change visibility for particular message using API:
AmazonSQS.changeMessageVisibility(String queueUrl, String receiptHandle, Integer visibilityTimeout)
For this purpose in downstream flow you have to get access to (inject) AmazonSQS bean and extract special headers from the Message:
#Autowired
AmazonSQS amazonSqs;
#Autowired
ResourceIdResolver resourceIdResolver;
...
MessageHeaders headers = message.getHeaders();
DestinationResolver destinationResolver = new DynamicQueueUrlDestinationResolver(this.amazonSqs, this.resourceIdResolver);
String queueUrl = destinationResolver.resolveDestination(headers.get(AwsHeaders.QUEUE));
String receiptHandle = headers.get(AwsHeaders.RECEIPT_HANDLE);
amazonSqs.changeMessageVisibility(queueUrl, receiptHandle, YOUR_DESIRED_VISIBILITY_TIMEOUT);
But eh, I agree that we should provide something on the matter as out-of-the-box feature. That may be even something similar to QueueMessageAcknowledgment as a new header. Or even just one more changeMessageVisibility method to this one.
Please, raise a GH issue for Spring Cloud AWS project on the matter with link to this SO topic.

How to send a list of objects in Haxe between client and server?

I am trying to write an online message board in Haxe (OpenFL). There are lots of server/client examples online. But I am new to this area and I do not understand any of them. What is the easiest way to send a list of objects between server and client? Could you guys give an example?
You could use JSON
You can put this in your openFL project (client):
var myData = [1,2,3,4,5];
var http = new haxe.Http("server.php");
http.addParameter("myData", haxe.Json.stringify(myData));
http.onData = function(resultData) {
trace('the data is send to server, this is the response:' + resultData);
}
http.request(true);
If you have a server.php file, you can access the data like this:
$myData = json_decode($_POST["myData"]);
If the server returns Json data which needs to be read in the client, then in Haxe you need to do haxe.Json.parse(resultData);
EDIT: I'm not still sure if the user's problem is really about sending "a list of objects"; see comment to the question...
The easiest way is to use Haxe Serialization, either with Haxe Remoting or with your own protocol on top of TCP/UDP. The choice of protocol depends whether you already have something built and whether you will be calling functions or simply getting/posting data.
In either case, haxe.Serializer/Unserializer will give you a format to transmit most (if not all) Haxe objects from client to server with minimal code.
See the following minimal example (from the manual) on how to use the serialization APIs. The format is string based and specified.
import haxe.Serializer;
import haxe.Unserializer;
class Main {
static function main() {
var serializer = new Serializer();
serializer.serialize("foo");
serializer.serialize(12);
var s = serializer.toString();
trace(s); // y3:fooi12
var unserializer = new Unserializer(s);
trace(unserializer.unserialize()); // foo
trace(unserializer.unserialize()); // 12
}
}
Finally, you could also use other serialization formats like JSON (with haxe.Json.stringify/parse) or XML, but they wouldn't be so convenient if you're dealing with enums, class instances or other data not fully supported by these formats.

YouTube Data API - Number of Results - Maven

I am trying to get videos from youtube in two different ways
a) First using youtube-google-api client library following the guidelines and sample code from here https://developers.google.com/youtube/v3/code_samples/java#search_by_keyword
Nevertheless, since I am implementing in a mavenized project Ihave difficulty in finding the dependency for 'com.google.api.services.samples.youtube.cmdline.Auth" which is required for the following block of code:
try {
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
}
}).setApplicationName("youtube-cmdline-search-sample").build();
b)Second I simply send a GET request to YouTube like this:
https://www.googleapis.com/youtube/v3/search?part=snippet&q=madonna&type=video&key={API_KEY}
but I am able to receive only 5 results, although I've read in several Stackoverflow related questions that I can receive up to 50 videos.This is not feasible even if I set the "max-results" parameter.
Could anyone help me to deal with these issues? Thank you in advance.
In your second way Write maxResults=50 as a parameter instead of max-results=50.
Use YouTube Data Api v3 api explorer to understand parameters very well.
https://developers.google.com/apis-explorer/#s/youtube/v3/
https://www.googleapis.com/youtube/v3/search?part=snippet&q=madonna&maxResults=50&type=video&key={API_KEY}

MQRFH2.usr coming in the main message body

Using WMQ7.0 with WMB 6.1
I have one flow where I am transforming a message and using MQRFH2.usr for holding some data.
But, I am facing the issue where the MQRFH2.usr is coming in the main message body.
I have deployed the same code in different environments, but I am getting this issue only in one environment.
So, it doesn't seems to be a code issue. It has something to do with configurations.
Kindly, suggest what could be the possible cause.
Check the queue's PROPCTL setting. If this is set to NONE then the behavior is as follows:
If the application does not create a message handle, all the message
properties are removed from the MQRFH2. Name/value pairs in the MQRFH2
headers are left in the message.
Be sure to read the doc page through a couple of times and maybe test with different settings to understand fully how PROPCTL modifies the message content your app receives.
The MQRFH2 headers, if present, always come in the payload part of the message (that's the way webpshere organizes it). You can receive one or more MQRFH2 headers (structures).
Perhaps you are expecting only one and are receiving two? This would explain your message data being left with gibberish.
I use the following code to handler these heards upon receiving a message
MQRFH2 header = null;
// Find and store message length
int msglen = replyMessage.getMessageLength();
MQHeaderList list = new MQHeaderList(replyMessage);
int indexOf = list.indexOf("MQRFH2");
if (indexOf >= 0) {
header = (MQRFH2) list.get(indexOf);
msglen = msglen - header.size();
}
String msgText = replyMessage.readStringOfCharLength(msglen);
Hope it helps.
Martins

Resources