http streaming response unsupported message type: class org.jboss.netty.handler.stream.ChunkedStream - http

I am trying to write a netty based http server which takes text as input and returns an image as output. This image is generated on the fly based on the input text.
I copied the logic of org.jboss.netty.example.http.file.HttpStaticFileServerHandler into my own handler, and rather than writing a DefaultFileRegion as output in the channel,
final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0, fileLength);
writeFuture = ch.write(region);
I am doing the following in my own handler:
InputStream imageIOStream = imageGenerator.generateImage(inputText);
ChannelFuture writeFuture = ch.write(new ChunkedStream(imageIOStream));
But I get the following exception on the server when I try to write back to the client.
java.lang.IllegalArgumentException: unsupported message type: class org.jboss.netty.handler.stream.ChunkedStream
at org.jboss.netty.channel.socket.nio.SocketSendBufferPool.acquire(SocketSendBufferPool.java:56)
at org.jboss.netty.channel.socket.nio.NioWorker.write0(NioWorker.java:463)
at org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:390)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:137)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:76)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:68)
at org.jboss.netty.channel.Channels.write(Channels.java:611)
at org.jboss.netty.channel.Channels.write(Channels.java:578)
at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:251)
Can someone please help me.

In your pipeline, have you setup the following?
pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
See https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerPipelineFactory.java.

Related

Xamarin forms: Epubreader: System.AggregateException: 'One or more errors occurred

I am using epubreader (vers-one) NuGet package for parsing .epub files.
My Code:
string fileName = "SampleEPUB.epub";
var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{fileName}");
EpubBook epubBook = EpubReader.ReadBook(stream);
foreach (EpubNavigationItem chapter in epubBook.Navigation)
{
chapterDetails.Add(new ChapterDetails() { title = chapter.Title, htmlData = chapter.HtmlContentFile?.Content, subChapters = chapter.NestedItems });
}
For testing purposes, I have added the epub files on the project and parse the chapters like above. I need to change this implementation.
I am able to get the epub file links stored in our database. Now I need to parse the chapters of epub from the link. But when I use the link as the fileName in the above code I am getting the below exception:
System.AggregateException: 'One or more errors occurred. (Value cannot be null.Parameter name: stream)'
How can I solve this issue? One sample link is here. I have added a sample project here having .epub file links for the reference (epub file links are commented in the sample).
System.AggregateException: 'One or more errors occurred. (Value cannot be null.Parameter name: stream)'
The GetManifestResourceStream method is used to access the embedded file which should be placed in shared project for the Xamarin.Forms project. The code doesn't works for the file comes from a database. You could debug to get that the stream is null because the fileName doesn't exist in the project.
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{fileName}");
In your condition, it just needs to get the stream from the url. Try to use the following code to get the stream.
Stream stream;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)aRequest.GetResponse();
stream = response.GetResponseStream();

kafkatemplate is modifying message sent, need original message to be sent as it is

I have implemented custom kafkalistenererrorhandler. I want to send the message to retry topic if message fails in processing. For this purpose I have added some headers to it. For doing this I am using spring-meesage.
Issue is when I am sending message using kafkatemplate it adds "\" to the string message.
Following is the code what I am doing.
public Object handleError(Message<?> message, ListenerExecutionFailedException exception) {
logger.info("Enter handleError message");
int numberOfRetries = messageRetryCount(message);
MessageBuilder<?> messageBuilder = MessageBuilder.fromMessage(message).removeHeader(KafkaHeaders.TOPIC)
.removeHeader(KafkaHeaders.PARTITION_ID).removeHeader(KafkaHeaders.MESSAGE_KEY)
.setHeader(KafkaHeaders.TOPIC, numberOfRetries > 0 ? retryTopic : dlqTopic);
template.send(messageBuilder.build());
Internally spring-kafka converts message to producerRecord. which in output adds \ to the string.
2020-03-20 12:25:28.804 INFO 10936 --- [_consumer-0-C-1] c.h.kafkaretry.consumer.SimpleConsumer : in rety :: "\"testfail\""
Does anyone faced same issue ? any alternatives or solution ?
Looks like you use JsonSerializer while your data is just a plain string. Consider to use a StringSerializer or JsonDeserializer on the consumer side.

FHIR JSON to XML decoding in BizTalk

I am just starting out with FHIR and with json so my question may not be well asked.
I have built a BizTalk pipeline component to convert FHIR-json to FHIR-xml using this library, https://github.com/ewoutkramer/fhir-net-api , based on an example i found here, http://soapfault.com/blog/2016/08/hl7-fhir-json-decoding-in-biztalk/
Here is a code snippet from the pipeline component. It's almost identical to the example.
//Read the json message
using (TextReader tr = new StreamReader(originalDataStream))
{
json = tr.ReadToEnd();
}
//Use FHIR-NET-API to create a FHIR resource from the json
Hl7.Fhir.Serialization.ResourceReader resourceReader = new Hl7.Fhir.Serialization.ResourceReader(FhirJsonParser.CreateFhirReader(json), ParserSettings.Default);
//Use FHIR-NET-API to serialize the resource to XML
byte[] resourceXmlBytes = Hl7.Fhir.Serialization.FhirSerializer.SerializeToXmlBytes(resourceReader.Deserialize());
The pipeline component is able to decode any single json FHIR message that starts with
{
"resourceType": "ImagingStudy",
but I get a parsing error on the messages that start like this,
{
"resourceType" : "Bundle",
"entry" : [{
"resource" : {
"resourceType" : "ImagingStudy",
or
{
"entry": [
{
"fullUrl": "http://fhirtest.uhn.ca/baseDstu2/ImagingStudy/EXexample",
"resource": {
"resourceType": "ImagingStudy",
Here are a couple of the errors I have got,
There was a failure executing the receive pipeline: "LALALA.Imaging.Pipelines.FHIRJasonDecoderRP, LALALA.Imaging.Pipelines, Version=1.0.0.0, Culture=neutral, PublicKeyToken=19bb8b5ea64396aa" Source: "FHIRJsonDecoder" Receive Port: "RP_LA_Test_FILE" URI: "D:\Projects\LALALA.Imaging\In\*.json" Reason: Data at the root level is invalid. Line 1, position 1.
OR
Reason: At line 1, pos 1: Cannot determine type of resource to create from json input data: no member resourceType was found
For my solution the ultimate goal is to to be able parse bundles of FHIR image study messages into single fhir xml messages that will then be mapped to HL7 ORU messages.
Any help with the issue above or suggestions on how to achieve my end goal using BizTalk would be greatly appreciated.
It's generally not necessary to call the ResourceReader directly, nevertheless I tried to reproduce your error like this:
var json = #"{
""resourceType"" : ""Bundle"",
""entry"" : [{
""resource"" : {
""resourceType"" : ""ImagingStudy""
}}]}";
// SHORT VERSION: var b = new FhirJsonParser().Parse<Bundle>(json);
var b = new
Hl7.Fhir.Serialization.ResourceReader(
FhirJsonParser.CreateFhirReader(json),
ParserSettings.Default).Deserialize();
Assert.IsNotNull(b);
Both work fine, however. Maybe something goes wrong while reading the stream?
You could also try reading directly from the stream:
var b = new FhirJsonParser().Parse<Bundle>(new
Newtonsoft.Json.JsonTextReader(stream));

HTTP.call throws errors instead of returning response

I am working with the Facebook graph API and have run into trouble regarding handling failed requests.
I use this code to create a new post
SocialFacebook.createPosting = function(data) {
var options = {
params: {
access_token : data.tokens.accessToken,
message : data.text
}
};
var url = 'https://graph.facebook.com/' + data.graphId + '/feed';
var response = HTTP.call('POST', url, options).data;
return response;
}
But instead of returning a JS object with error information in the response, it throws an error on failed requests
Exception while invoking method 'createPosting' Error: failed [500] {"error":{"message":"Duplicate status message","type":"FacebookApiException","code":506,"error_subcode":1455006,"is_transient":false,"error_user_title":"Duplicate Status Update","error_user_msg":"This status update is identical to the last one you posted. Try posting something different, or delete your previous update."}}
Because it's wrapped in an Error, the otherwise JSON object is now a string with some other stuff appended to it, which makes it difficult to parse and extract the attributes
Any idea as to why it throws an error, instead of returning a JS object with error details like usually?
Much appreciated
According to the docs, about HTTP.call():
On the server, this function can be run either synchronously or asynchronously. If the callback is omitted, it runs synchronously and the results are returned once the request completes successfully. If the request was not successful, an error is thrown.
So there you have it: since you called HTTP.call() synchronously (without providing a callback), if it responds with an error (in your case, Code 500) the error is thrown and not included in the data.

How to safely handle raw (file) data in Java?

An image gets corrupted while being retrieved (through HTTP) and then sent (through HTTP) to a database. Image's raw data is handled in String form.
The service sends a GET for an image file, receives response with the raw image data (response's body) and the Content-Type. Then, a PUT request is sent with the aforementioned request's body and Content-Type header. (The PUT request is constructed by providing the body in String) This PUT request is sent to a RESTful database (CouchDB), creating an attachment (for those unfamiliar with CouchDB an attachment acts like a static file).
Now I have the original image, which my service GETs and PUTs to a database, and this 'copy' of the original image, that I can now GET from the database. If I then `curl --head -v "[copy's url]" it has the Content-Type of the original image, but Content-Length has changed, went from 200kb to about 400kb. If I GET the 'copy' image with a browser, it is not rendered, whereas, the original renders fine. It is corrupted.
What might be the cause? My guess is that while handling the raw data as a string, my framework guesses the encoding wrong and corrupts it. I have not been able to confirm or deny this. How could I handle this raw data/request body in a safe manner, or how could I properly handle the encoding (if that proves to be the problem)?
Details: Play2 Framework's HTTP client, Scala. Below a test to reproduce:
"able to copy an image" in {
def waitFor[T](future:Future[T]):T = { // to bypass futures
Await.result(future, Duration(10000, "millis"))
}
val originalImageUrl = "http://laughingsquid.com/wp-content/uploads/grumpy-cat.jpg"
val couchdbUrl = "http://admin:admin#localhost:5984/testdb"
val getOriginal:ws.Response = waitFor(WS.url(originalImageUrl).get)
getOriginal.status mustEqual 200
val rawImage:String = getOriginal.body
val originalContentType = getOriginal.header("Content-Type").get
// need an empty doc to have something to attach the attachment to
val emptyDocUrl = couchdbUrl + "/empty_doc"
val putEmptyDoc:ws.Response = waitFor(WS.url(emptyDocUrl).put("{}"))
putEmptyDoc.status mustEqual 201
//uploading an attachment will require the doc's revision
val emptyDocRev = (putEmptyDoc.json \ "rev").as[String]
// create actual attachment/static file
val attachmentUrl = emptyDocUrl + "/0"
val putAttachment:ws.Response = waitFor(WS.url(attachmentUrl)
.withHeaders(("If-Match", emptyDocRev), ("Content-Type", originalContentType))
.put(rawImage))
putAttachment.status mustEqual 201
// retrieve attachment
val getAttachment:ws.Response = waitFor(WS.url(attachmentUrl).get)
getAttachment.status mustEqual 200
val attachmentContentType = getAttachment.header("Content-Type").get
originalContentType mustEqual attachmentContentType
val originalAndCopyMatch = getOriginal.body == getAttachment.body
originalAndCopyMatch aka "original matches copy" must beTrue // << false
}
Fails at the last 'must':
[error] x able to copy an image
[error] original matches copy is false (ApplicationSpec.scala:112)
The conversion to String is definitely going to cause problems. You need to work with the bytes as Daniel mentioned.
Looking at the source it looks like ws.Response is just a wrapper. If you get to the underlying class then there are some methods that may help you. On the Java side, someone made a commit on GitHub to expose more ways of getting the response data other than a String.
I'm not familiar with scala but something like this may work:
getOriginal.getAHCResponse.getResponseBodyAsBytes
// instead of getOriginal.body
WS.scala
https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/libs/ws/WS.scala
WS.java
Here you can see that Response has some new methods, getBodyAsStream() and asByteArray.
https://github.com/playframework/playframework/blob/master/framework/src/play-java/src/main/java/play/libs/WS.java

Resources