Binary file corruption over http using Apache Camel - apache-camel

I'm trying to read a binary file from a local filesystem, send it over HTTP, then in a different application I need to receive the file and write it out to the local file system, all using Apache Camel.
My (simplified) client code looks like this:
from("file:<path_to_local_directory>")
.setHeader(Exchange.HTTP_PATH, header("CamelFileNameOnly"))
.setHeader(Exchange.CONTENT_TYPE, constant("application/octet-stream"))
.to("http4:localhost:9095");
And my server code is:
restConfiguration()
.component("spark-rest")
.port(9095);
rest("/{fileName}")
.post()
.consumes("application/octet-stream")
.to("file:<path_to_output_dir>?fileName=${header.fileName}");
As you can see, I'm using the Camel HTTP4 Component to send the file and the Spark-Rest component to receive it.
When I run this, and drop a file into the local directory, both the client and server applications work and the file is transmitted, received and written out again. The problem I'm seeing is that the original file is 5860kb, but the received file is 9932kb. As it's a binary file it's not really readable, but when I open it in a text editor I can easily see that it has changed and many characters are different.
It feels like it's being treated as a text file and it's being received and written out in a different character set to that in which it is written. As a binary file, I don't want it to be treated as a text file which is why I'm handling it as application/octet-stream, but this doesn't seem to be honoured. Or maybe it's not a character set problem and could be something else? Plain text files are transmitted and received correctly, with no corruption, which leads me to think that it is the special characters in the binary file that are causing the problem.
I'd like to resolve this so that the received file is identical to the sent file, so any help would be appreciated.

I got the same issue. By default, Camel will serialize it as a String when producing to the http endoint.
You should explicitly convert the GenericFile to byte[] by doing a simple : .convertBodyTo(byte[].class) before your .to("http4:..")

Related

JMeter: How to decode alphanumeric characters fetched in JMETER response to its valid value?

I have a JMeter test plan which basically downloads a file by breaking it into multiple parts.
However, these parts are received in encoded alphanumeric character format.
For instance, we have a .txt file which is broken down into 2 parts. Each part has an encoded set of characters. I have been successful so far in appending these characters into another file.
Is there a way of restoring the contents of this file ( holding alphanumeric characters) into the original .txt file with its valid contents back again?
e.g. JMeter response: <data> aWJiZWFuLFBhbmFtYSxDb3NtZXRpY </data>
Can someone please suggest the steps to achieve this?
It looks like it is Base64-encoded, you can use __base64Decode() function (can be installed as a part of Custom JMeter Functions bundle using JMeter Plugins Manager)
${__base64Decode(aWJiZWFuLFBhbmFtYSxDb3NtZXRpY,)}
If you don't have possibility or unwilling to use JMeter Plugins you can achieve the same using JMeter's built-in __groovy() function:
${__groovy(new String('aWJiZWFuLFBhbmFtYSxDb3NtZXRpY'.decodeBase64()),)}

Apache Camel File Append Not Working in Windows

I have a simple route where I write some string to an output file and then trying to append the contents of the original file. But it ignores and it overwrites the file.
from("file://inputFolder")
.routeId("InputFolderToTestSedaRoute")
.setProperty("myFileConsumedBody", simple("${body}"))
.setBody(constant("FIRST LINE!"))
.to("file://{{outputFolder}}")
.setBody(simple("${exchangeProperty.myFileConsumedBody}"))
.log("*** STEP 100: ${headers} :***")
.delay(10000)
.to("file://outputFolder?fileExist=Append")
;
I added delay to observe what happens.
If there is an input file named myFile.txt, Camel picks that file as expected.
It keeps the file to an custome exchange property as in the code.
It opens a file named myFile.txt and writes the content "FIRST LINE!" in it and waits for the delay to expire.
I can open and verify the contents, everything looks good.
Once delay expires, Camel overwrites the file myFile.txt with the original content it picked from input folder (even though I have asked Camel to append).
Am I doing any mistake here? Not sure if this is specific to Windows 10. I am using Camel version 2.24.1. Thanks for your time.
This is bug CAMEL-14127 fixed in version 2.24.3. You can upgrade, or use workaroud with charset option.
.to("file://outputFolder?fileExist=Append&charset=utf-8")

Sending multiple files over tcp golang - simple protocol

I'm trying to build a simple protocol to send files over TCP in golang. After reading some stuff I decided to use GOB package to send a header with information about file being sent and then file in using raw socket. Between messages I'm using a delimiter ("/r/n")
So the sendflow looks like that:
Client(sends a file)(C)
Server(S)
(C)Reading file metadata(filesize, filename, etc)
(C)Encoding file metadata into struct
(C)Intialize connection with server
(C)Send encoded gob
(S)Receive a gob and decode
(C)Send a delimiter
(S)Receive a delimiter
(C)Start sending file using buffer (1024)
(S)Start receiving file and saving to created file until size from header message will be exceeded.
(C)Send a delimiter
(S)Receive a delimiter
(C)Close connection
Hopefully I explained it well. A problem is that in my unittests when I'm checking checksums of file being transfered sometimes I have wrong files it looks like sometimes the delimiter is added also. My question is if my simple protocol does make sense, if not could someone give my some advices how to build it to be robust and reliable.
Thanks in advance!

Camel reads the file from FTP endppoint before the complete file is copied to the location

Hi I have a very simple route which reads a file from an FTP location. When I deploy into a service mix(Jboss Fuse) it reads the files as expected.
When I have a large file it reads this file before it has finished copying to the location.
How could I tackle this?
If the problem is that you read the file before the sender has finished sending it, you need to use the 'readlock' parameter with the 'rename' value. That's the only value for that parameter that works over FTP.
If the problem is that someone reads the file before you are finished sending it you need to use the 'tempPrefix' parameter. This will prefix the filename while still copying its content (so that consumers ignore it at that stage), and only rename to the final filename after the file is completely transfered.
The FTP component is an extention of the File component. You'll find more information about the 'tempPrefix' parameter here: http://camel.apache.org/file2.html

how to send a txt file from server to client using http in java

I have a problem in my grails application which reads a txt file stored in the disk and then sends the file to the client.
Now I am achieving this by reading the file line by line and storing them in a String array.
After reading all lines from the file, the String array is sent to the client as JSON.
In my gsp's javascript I get that array and display the array contents in a text area as
textarea.value = arr.join("\n\n");
This operation happens recursively for every 1 minute which is achieved using ajax.
My problem is, the txt which the server is reading consists of about 10,000 to 20,000 lines.
So reading all those 10,000+ lines and sending them as array creates problem in my IE8 which gets hung-up and finally crashes.
Is there any other easy way of sending the whole file through http and displaying it in browser?
Any help would be greatly appreciated.
Thanks in advance.
EDIT:
On Googling I found that, file input/output streaming is a better way to display the file contents in a browser but I couldn't find an example on how to do it.
Can anyone share some example on how to do it?

Resources