how to move file to error directory and rollback other move with apache camel? - apache-camel

First of all: i'm a camel newbie :-)
I want to transfer a file from an input directory to an output directory and do some java stuff.
If something goes wrong, i want to move the file to an error directory and rollback to move to the output directory.
This is my route in java dsl:
onException(Exception.class).handled(true).to("file://C:/temp/camel/error");
from("file://C:/temp/camel/in?delete=true").to("file://C:/temp/camel/out").bean(ServiceBean.class, "callWebservice");
If an error is thrown in the ServiceBean, the file is copied to the error folder, but it also stays in the out directory.
What is the best way to rollback?
Thanks

There is a moveFailed option. Just use that, then you dont need the onException etc.
http://camel.apache.org/file2
from("file://C:/temp/camel/in?delete=true&moveFailed=C:/temp/camel/error")
.to("file://C:/temp/camel/out")
.bean(ServiceBean.class, "callWebservice");
And instead of storing to out in the route, then just use the move option so it becomes
from("file://C:/temp/camel/in?move=/temp/camel/out&moveFailed=/temp/camel/error")
.bean(ServiceBean.class, "callWebservice");

I don't think you can easily 'rollback' filesystem operations. Perhaps you could redesign your flow to first copy file to some intermediary 'stage' directory, do the work you need and depending on the outcome of that work move file to either 'output' or 'error' directory.

Related

Apache Camel doneFileName with changing name

I'm currently creating some route and for one of them I have a problem.
Usually I have a data file and then a done file which have the same name prefixed by "ACK" and this works perfectly with camel and the doneFileName option.
But for one of my route I have to work with a different situation, I still receive two files but they have the same typology, it's like: MyFILE-{{timestamp}}. The data file contains the data, and the done file contains just "done".
So I need something to check the content of the file, and if it's juste "done" then process the other file.
Is there a way to handle this with camel?
The most pragmatic solution I see is to write an "adapter script" (bash or whatever you have at your disposal) that peeks into every file with a timestamp in its name.
If the file content is "done":
Lookup the other "MyFILE-{{timestamp}}" (the data file) and rename it to "MyFILE"
Rename the done file to "MyFILE.done"
Camel can then import the data file using the standard done-file-option. Because both files are renamed to something without a timestamp, the peek-script ignores them after renaming.

How to rename a file while using "move" in URL in apache camel

I have an URL like
url = "file:D:/inputFolder?move=D:/outputFolder". we are making this url dynamically.
I want to rename the file while moving, So I made it something like this
url = "file:D:/inputFolder?move=D:/outputFolder&fileName=abc.txt". But I think move and fileName do not work together, it is not renaming.
Is there any alternative to do it? Please remember I want with "move" only.
I cannot use .setHeader(..) also.
Thanks,
Hy,
as far as I understand you, your trying to move the file in one single uri.
That is not really how camel works.
The idea of camel is to have a "consumer" and a "producer", where the consumer loads data (e.g. your file) and the producer puts the data somewhere (e.g. save the file into a folder)
That being said, here is what worked for me with a java route:
from("file:/home/chris/temp/camel/in")
.to("file:/home/chris/temp/camel/out/?fileName=test.txt");
The from part configures the folder where camel looks for new files. A few notes on that:
The file component checks the folder each 0.5 sec for new files. This can be changed with the delay parameter
The option noop configures, if the file is being moved or copied. By default it is set to false, which means it is moved
In the to part you configure, where the file is supposed to be moved. Here you can use the fileName parameter to rename the file.
Be careful with this though, because setting an option in the uri directly does make it "static".
What I mean by that is, that the only way of changing the parameter is by completely reconfiguring the route or by restarting it, where neither is something you would want to do normally.
Note 1:
Moving all files that are put into one folder into the same file always overrides the previous file by default.
You could, for example, use the fileExists parameter to always just append the content of the file: fileExists=Append (See camel file docu for details)
Note 2:
There is an option in the file component to not "move" the file, but copy, rename and delete it, which sometimes is necessary, when you want to move it onto a different drive and a simple copy does not work.
Also see the docu for the camel file component for details on that.
Note 3:
You can have multiple to() statements in the same route to have the file moved to multiple locations. For example:
from("file:/home/chris/temp/camel/in")
.to("file:/home/chris/temp/camel/out/?fileName=test.txt")
.to("smtp:....");
Hope I could help you and answer you question.
Greets
Chris
Two possible ways to achieve your goal.
Use both "consumer" and "producer"
Using this way, you are free to control where and how your destination can be set and has great freedom to control filename with the use of a processor/bean.
from("file:D:/inputFolder")
.to("file:D:/outputFolder?fileName=abc.txt")
Use "consumer" only
Using this way, you are treating your work as source data control. This can be use when your file is going to move within same drive. The drawback is the filename rename pattern is limited (refer to camel file language)
from("file:D:/inputFolder?move=${file:parent}/../outputFolder/abc.txt")

How to get file name when file change is observed via watch_file

I am currently facing an issue which I don't know how to fix. I got the following Julia code:
while true
print(watch_file("test"))
end
So this should get me all the file changes in the directory named "test". At least on windows.
Now thats all well and good, and it kinda works, at least for creating a file or moving a file to that directory. This is an example of what I get:
("New Textfile.txt",Base.FileEvent(true,false,false))
But when I delete or rename that file, I don't get the filename of the file deleted or renamed.
("",Base.FileEvent(true,false,false))
Is there a different method/function I can get the filename with, even when the file is deleted or renamed? Or even better, a way that archives this and is cross-platform-compatible? Any help appreciated.
EDIT: If you could give me an alternative that supports recursive monitoring, that would be even better.
In Linux, Julia 0.4.5 and 0.4.3 watch_file returns file name always. It is a very platform-dependent feature (like in Node.js https://nodejs.org/api/fs.html#fs_caveats) and only manual polling can be truly platform-independent solution.

How can I load a Maya .MA file from MEL when it has an unresolved reference?

I am trying to use a MEL script to load ANIMATION.MA file that references CHARACTER_RIG.MA. The CHARACTER_RIG.MA and ANIMATION.MA files are produced by someone else and supplied to me. The ANIMATION.MA is looking for N:/Project/Maya//char/character/CHARACTER_RIG.MA
If I open ANIMATION.MA from Maya, or use the equivalent MEL command I always get prompted with:
"Reference File Not Found"
Reference File Not Found: N:/Project/Maya//char/character/CHARACTER_RIG.MA.
[Abort File Read] [Skip] [Browse...] [Retry]
If I tap browse, and select the CHARACTER_RIG.MA then it opens perfectly. I can see it created a reference in the Reference Editor that has the Unresolved Path (N:/...) , the Resolved Path (/my/path) and the namespace and the namespaceRN.
My question is, how do I do the equivalent of the "Browse..." from MEL? I tried pre-creating a reference, but it doesn't let me set the unresolved path, so when I load the ANIMATION.MA it keeps prompting in MAYA.
file -f -options "v=0" -typ "mayaAscii" -o "/Source/project/assets/anims/ANIMATION.MA"
If you know the directory where the file is, then you can use the dirmap command. The command dirmap allows you to remap directory structures if your disk configuration changes. So in this case it would look like:
dirmap -en true;
dirmap -m "N:/Project/Maya//char/character" "/my/path";
Possibly more manageable if you have lots of mappings to do especially when moving form a windows machine to a *nix one. However it is much more useful to define your project structure because then things just work when you move, tough this may not be the best of choice for shared assets.
I ended up finding several solutions:
Rename the RIG.MA file to match the filename in ANIM.MA (they were different in my case) and put it in one of the search or project folders that MAYA uses and it will automatically find it.
or
Programatically through code (or manually) edit the ANIM.MA file to remap the file/folder of the RIG.MA to where you want to load it from. Note: You
also need to remap any other files, such as textures. I did this with
perl -pi -e 's/\Qold-path\E/\Qnew-path\E/g' ANIMATION.MA
HTH someone else.
Quick and easy, File, Project, Set and select the folder where meshes or whatever it is.

Clearcase: how to copy/fork a file?

In Clearcase, I want to copy (fork, split) a file while preserving its history. Something like svn cp old.txt new.txt. How do I do it?
It isn't possible do fork a file in ClearCase.
If you refactor your code and split a file in two, one of them will appear as a new file and you will loose the information about who coded it. The annotate command will say the author of the lines are who splited it.
UCM or not, you cannot duplicate easily the full history of a file.
The best way to isolate an history is still to create a branch in order to make new versions to that file without impacting the same file in the original branch.
Thinking 'svn cp' should be available in ClearCase might come from the fact that, in SVN, branches are directories, and a tool like cc2svn will actually replicate ClearCase branches using 'svn cp'.
But since, with ClearCase, branches are first-class citizen, it is best to reason in term of branch than in term of copy/fork.
From the main page of cc2svn:
There is a difference in creating the branches in ClearCase and SVN:
SVN copies all files from parent branch to the target like: svn cp branches/main branches/dev_branch
ClearCase creates the actual branch for file upon checkout operation only.
Pretty simply done
Check out parent folder
Move element you wish to duplicate to appropriate location (not within the checked out parent folder)
Undo Checkout of parent folder
All the files get returned to the original folder with history and also the duplicate ones remain in the new location with the history too. Now each file can be checked out and changed individually

Resources