So I have a netty4 socket route set up in Java DSL that looks like the following:
#Override
public void configure() throws Exception {
String dailyDataUri = "{{SOCKET.daily.file}}" + "&fileName=SocketData-${date:now:yyyyMMdd}.txt";
from(socketLocation).routeId("thisRoute")
.transform()
.simple("${in.body}\n")
.wireTap(dailyDataUri)
.to(destination)
;
Where both the wireTap and the destination are sending their data to two separate files. And the data collection in the destination file is separated by a \n (line break)... or at least it should be.
When viewing the files created, the \n is never added.
The equivalent idea in the Spring DSL worked before I switched to Java:
<transform>
<simple>${in.body}\n</simple>
</transform>
After using that and opening the files created during the route, the lines of data that came in through the socket would be separated by a newline.
What am I doing wrong in the Java DSL that doesn't allow the newline to be appended to the socket data as it comes in?
I feel like it's something obvious that I just don't see.
The data that is coming in is just a CSV-like line of text.
I found a solution, I'm never sure what can be translated almost word from word from Spring to Java. Apparently the transform/simple combination has some issue where it will not work for me in Java DSL.
So a possible solution (there may be more solutions) is to do this:
#Override
public void configure() throws Exception {
String dailyDataUri = "{{SOCKET.daily.file}}" + "&fileName=SocketData-${date:now:yyyyMMdd}.txt";
from(socketLocation).routeId("thisRoute")
.transform(body().append("\n"))
.wireTap(dailyDataUri)
.to(destination)
;
Where instead of using the Simple language to manipulate the body, I just call on the body and append a String of \n to it. And that solves my issue.
Update : Camel version 3.x and above File component provides features to append your desired character.
As you are writing file using file component (producer)
appendChars (producer)
Used to append characters (text) after writing files. This can for example be used to add new lines or other separators when writing and appending new files or existing files. To specify new-line (slash-n or slash-r) or tab (slash-t) characters then escape with an extra slash, eg slash-slash-n.
Related
We receive .csv files (both via ftp and email) each of which can be one of a few different formats (that can be determined by looking at the top line of the file). I am fairly new to Apache Camel but want to implement a content based router and unmarshal each to the relevant class.
My current solution is to break down the files to a lists of strings, manually use the first line to determine the type of file, and then use the rest of the strings to create relevant entity instances.
Are there a cleaner and better way?
You could use a POJO to implement the type check in whatever way works best for your files.
public String checkFileType(#Body File file) {
return determineFileType(file);
}
private String determineFileType(File file) {...}
Like this you can keep your route clean by separating the filetype check and any other part of processing. Because the filetype check is just metadata enrichment.
For example you could just set the return value as a message header by calling the bean)
.setHeader("fileType", method(fileTypeChecker))
Then you can route the files according to type easily by using the message header.
.choice()
.when(header("fileType").isEqualTo("foo"))
...
I'm going to process CSV files using Apache Camel. My files have multiple header lines. In Camel I only find skipFirstLine or skipHeaderRecord (which is not clear for me) but how to skip more than one line?
You can use tokenize method on your body before processing the body.
tokenize(String token, int group, boolean skipFirst)
Example:
`from("filePath").
split(body().tokenize("\n",1,true)).
streaming().
process(exchange -> {....}).
to("filePath");`
If the number of lines to skip is fixed, then you can use the simple language to skip X number. You likely need to covert the message to a String first,
.convertBodyTo(String.class)
.transform(simple("${skip(3)}")
See more about skip method at: http://camel.apache.org/simple
This requires Camel 2.19 onwards.
Using older releases you would need to build some custom code yourself to skip the lines.
As the title says, I am trying to get file extension using Camel's File Language to specify the correct route.
choice().
when().simple("${file:ext} in 'xml'").
unmarshal(coreIt("jaxb[Core]")).
beanRef(connectorName()+coreIt("[Core]ImportConnector"), "processXml").
when().simple("${file:ext} in 'zip,7z'").
beanRef(connectorName()+coreIt("[Core]ImportConnector"), "extractZip").
endChoice();
Problem is, client provides us with xml file that has a date in filename, separated by dots. For some reason camel treats everything after the first dot as an extension. If I do:
when().simple("${file:ext} in '09.16.xml'").
it works...
Is there any solution or workaround apart from creating a separate folder to import xml files? Thanks for your time.
Well its tough as some files may have dot in extension such as '.tar.gz' and so on. So they should ideally not use dot in the file name. To work around this you would need to use some other simple expression to check for this. You can use ends with
${file:name} ends with 'xml'
And then you can use or:
${file:name} ends with 'zip' || ${file:name} ends with '7z'
See more details at: http://camel.apache.org/simple
I am trying to write the name of a file into Accumulo. I am using accumulo-core-1.43.
For some reason, certain files seem to be written into Accumulo with trailing \x00 characters at the end of the name. The upload is coming through a Java servlet (using the jquery file upload plugin). In the servlet, I check the name of the file with a System.out.println and it looks normal, and I even tried unescaping the string with
org.apache.commons.lang.StringEscapeUtils.unescapeJava(...);
The actual writing to accumulo looks like this:
Mutation mut = new Mutation(new Text(checkSum));
Value val = new Value(new Text(filename).getBytes());
long timestamp = System.currentTimeMillis();
mut.put(new Text(colFam), new Text(EMPTY_BYTES), timestamp, val);
but nothing unusual showed up there (perhaps \x00 isn't escaped)? But then if I do a scan on my table in accumulo, there will be one or more \x00 in the file name.
The problem this seems to cause is that I return that string within XML when I retrieve a list of files (where it shows up) and pass that back to the browser, the the XSL that is supposed to render the information in the XML no longer works when there's these extra characters (not sure why that is the case either).
In chrome, for the response on these calls, I see that there's three red dots after the file name, and when I hover over it, \u0 pops up (which I think is a different representation of 0/null?).
Anyway, I'm just trying to figure out why this happens, or at the very least, how I can filter out \x00 characters before returning the file in Java. any ideas?
You are likely incorrectly using the Hadoop Text class -- this is not an error with Accumulo. Specifically, you make the mistake in your above example:
Value val = new Value(new Text(filename).getBytes());
You must adhere to the length of provided by the Text class. See the Text javadoc for more information. If you're using Hadoop-2.2.0, you can use the provided copyBytes method on Text. If you're on older version of Hadoop where this method doesn't yet exist, you can use something like the ByteBuffer class or the System.arraycopy method to get a copy of the byte[] with the proper limits enforced.
Hi
I want to write a program in J2SE that be able to read commands (with their parameters) from some file (Like an XML file)
And then do the corresponding procedure on some given data.
For example if the XML file be:
<cut>
<from>start</from>
<to>end</to>
</cut>
<reverse></reverse>
<cut>
<from>
<find pos="4">tt</find>
</from>
</cut>
My program must get the string then do this:
1. cut string from "start" to "end"
2. reverse sstring
3. cut again from where it finds "tt" after the 4th character to end of string
and then return this result.
Is There any framework or library to do this? or i should write by my own?
(the form if input file is not important for me i just want it be editable by humans)
Thanks
I think what you are looking for is Jelly.