Search code examples
javaglobal-variablesetltalend

How to dynamically pass filename to tFTPRename in Talend?


I currently have a job that works like this:

tPrejob-->tOracleConnection1--->tOracleConnection2--->tSetGlobalVar1(timestamp)--->tRunjob(runs prejob to gather file from FTP)

Then there is a tPostjob that is supposed to rename the processed file on the FTP server.

tPostjob--->tFTPRename

It should be renaming the file with "File Processed On " + ((String)globalMap.get("timestamp")) + "This is where I would put the orginal file name"

If I put a standard filename into the Filemask then it will run correctly, however if I try to make the filemask dynamic by passing the filename into it through globalMap.get then I get the Error:

"Exception in component tFTPRename_1 java.lang.NullPointerException"

I've tried several methods for passing the file name into the tFTPRename component, but none are working.

I'm currently capturing the file name in the subjob and outputting it to a txt file and then using tFileInputFullRow on the main job to create that variable. I tried passing this into a tSetGlobalVar and then adding it into the filemask as ((String)globalMap.get("FileName")), but had no luck.

I also tried several methods on the internet, but none of them worked, so I wasn't sure if it was me or if it has something to do with tFTPRename capabilities.

Main Job: Main Job PreJob: PreJob tFTPRename Component: tFTPRename Component tFileInputFullRow: File Name Read


Solution

  • It sounds like you're using the globalMap wrong at some point which would certainly explain the null pointer exception as the globalMap variable doesn't appear to have been set.

    Typically the tSetGlobalVar component is for setting static or run time generated variables into the globalMap and I don't think you can actually pass data into it that it can then directly use and push to the globalMap. Your datetime stamp is a good use of the component but you'll need to either use a tFlowToIterate component or use a tJava(Row) component to force the data into the globalMap using something like:

    globalMap.put("fileName",inputrow.fileName);
    

    Looking at your previous question then you should have the name of the file from the FTP in the job you are calling in your pre job. Typically here you would be able to then run that as part of the main flow into a tBufferOutput component and then read the data directly into the parent job (simply connect a main flow connector from the tRunJob component to the next component you want to process the data flow and don't forget to give the tRunJob component the same schema as your child job's tBufferOutput).

    However, you have a complication here in that you have already used the buffer to capture all of the iterables from the tFTPList component so you're right in the fact that you need to go to a temporary flat file or database to push the state back to the parent job.

    From here though you should be able to read in the flat file or database table that contains the field name in your parent job and then run for ease you can just connect this to a tFlowToIterate component which will then store that data in the globalMap (you should have 1 row and 1 column of data here so it's a single variable).

    Here's a basic example of running some hard coded data in a tFixedFlowInput to a tFlowToIterate to get it into the globalMap and then retrieve it again with another tFixedFlowInput component:

    Job layout showing data being put into the globalMap by the tFlowToIterate component

    Once the data is in the tFlowToIterate component then you can easily call it with globalMap.get(rowName.schemaColumnName) or by hitting ctrl+space and selecting it under the tFlowToIterate component:

    Retrieving the data from the globalMap