File Lookup with effective error handling
Dear SCN members ,
Recently I have worked on a requirement of writing XML payload to a file using file look up and drafting a mail to application support/Business folks for any issue while connecting or writing to file server without disturbing main flow of the interface .
Generally we don’t prefer file look up because it needs robust code or effective error handling in order to convince the business .
There are couple of wiki’s or blogs already available in scn on file look up ,but I’m not happy on error handling part which is very vital in real time critical projects .So I want to share a blog which will focus more on Error handling and robust java code for these kind of requirements.
Main Flow:RFC<–>PI<–>SOAP
Prerequisites:
For connecting to different source file servers ,I have used the Apache open source API .It is free to use 🙂 .
You can download the jar file from the below link.
Apache Commons Net – Download Commons Net
For drafting mail from UDF ,I have used java-mail-1.4.4.jar, javax.activation.jar .These are free to download Oracle open source API’s.You can easily get from from Google/Oracle site.
UDF code:
Import parameters
com.sap.aii.mapping.api.*
com.sap.aii.mapping.lookup.*
com.sap.aii.mappingtool.tf7.rt.*
java.io.*
java.lang.reflect.*
java.util.*
org.apache.commons.net.ftp.FTPClientConfig
org.apache.commons.net.ftp.FTPClient
java.io.BufferedWriter
java.io.File
java.io.FileInputStream
java.io.FileWriter
java.io.IOException
javax.mail.Message
javax.mail.MessagingException
javax.mail.Session
javax.mail.Transport
javax.mail.internet.InternetAddress
javax.mail.internet.MimeMessage
public String FilesUpload(String Input, String ReturnFieldName, String Dateformat, String Host, String Username, String Pwd, String Folderpath, int TimeOut, String FileName, String FieldName, String Mail_Host, String Mail_From, String Mail_To, String Mail_Subject, Container container) throws StreamTransformationException{
int TIMEOUT =TimeOut * 1000; //Variable to store Connection TimeOut
AbstractTrace trace = container.getTrace();
FileInputStream fis = null;
FTPClient client = new FTPClient(); //Creating a FTPClient instance
try{
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
conf.setDefaultDateFormatStr(Dateformat);
client.configure(conf);
try{
client.setConnectTimeout(TIMEOUT); //Setting connection timeout
client.connect(Host);// connecting to ftp server
if(!client.login(Username, Pwd)){ throw new StreamTransformationException("Authorization failed.");} //Giving credentials to login
trace.addInfo("Successfully connected to server"+client.getReplyString());
if(!client.changeWorkingDirectory(Folderpath)){ throw new StreamTransformationException("Exception occurred while changing folder path to Interface specific path.");} //Changing the current directory to required folder path
}
catch(Exception c){
throw new StreamTransformationException("Exception occured while connecting to server :" + c);
}//close brace for catch
// Create an InputStream of the file to be uploaded
String srcFilename = FileName+"_Temp"+new Date().getTime();
String targetfilename = FileName+"_"+new Date().getTime();
File Sourcefile =new File(srcFilename);
//If file doesn't exists, then create it
if(!Sourcefile.exists()){ Sourcefile.createNewFile();}
FileWriter fileWritter = new FileWriter(Sourcefile.getName(),true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
bufferWritter.write(Input); //Writing the Input payload to file
bufferWritter.close();
fis = new FileInputStream(Sourcefile);
boolean done = client.storeFile(targetfilename, fis); //Store file to server
fis.close();
if (done) {
trace.addInfo("!!!----File is uploaded successfully----!!!");
} else {
trace.addWarning("Upload Failed");
throw new StreamTransformationException("Failed to upload file :Please cross check..:");
} //close brace for else
client.logout();
}catch(Exception e){
try{
Properties properties = System.getProperties(); // Get system properties
properties.setProperty("mail.smtp.host",Mail_Host); // Setup mail server
//Session session = Session.getDefaultInstance(properties); // Get the default Session object.
Session session = Session.getInstance(properties); // if you get Unknown Host exception in JAVA
//Sending mail to app support folks
MimeMessage message = new MimeMessage(session); // Create a default MimeMessage object.
message.setFrom(new InternetAddress(Mail_From)); // Set From: header field of the header.
String recipients[] =Mail_To.split(";");
InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
message.setRecipients(Message.RecipientType.TO, addressTo);
//message.addRecipient(Message.RecipientType.TO,new InternetAddress(Mail_To)); // Set To: header field of the header.
message.setSubject(Mail_Subject); // Set Subject: header field
message.setText(e.getMessage()+"."+" Failed message is having field value of "+FieldName+" is "+ReturnFieldName); // Now set the actual message
Transport.send(message); // Send message
trace.addInfo("Sent alert mail to app support folks successfully");
}catch(Exception mex){
trace.addWarning("Failed to send alert mail : "+mex);
}//close brace for catch
} //close brace for catch
finally {
try {
if (fis != null) {
fis.close();
}
client.disconnect();
} catch (IOException k) {trace.addWarning("Exception while closing filestream and diconnecting"+k); }
} //close brace for finally
return "File placed successfully";
}
In the above code ,for the below line we need to provide input based on file server that we are going to connect .
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
UNIX –>For connecting to Unix based ftp server. (Use this for Windows-NT servers which has been configured to use a unix-style listing format )
NT –>For connecting to WindowsNT based ftp server
AS400 –>For connecting to AS/400 based ftp server
VMS–>For connecting to VMS based ftp server
OS2–>For connecting to OS/2 based ftp server
L8–>Some servers return an “UNKNOWN Type: L8” message in response to the SYST command. We set this to be a Unix-type system
NETWARE–>For connecting to Netware based ftp server
MACOS_PETER –>For connecting to Mac pre OS-X based ftp server
MVS –>For connecting to MVS based ftp server
OS400 –>For connecting to OS/400 based ftp server
We are providing input values to the below parameters in runtime (From ID)
- DateFormat –> File server OS level Date format
- FieldName –> Field value of unique field to identify the message when udf failed to place file in PI local server . Ex: Exception occured while connecting to server :com.sap.aii.mapping.api.StreamTransformationException: Authorization failed.. Failed message is having field value of CALENDAR is 20140521101010
- FileName –> Filename Ex: FileName+”_”+current time stamp in milli secs
- Folderpath –> Folderpath
- Host –> Hostname of PI file server
- Mail_From :Mail From
- Mail_Host : Mail server Host name
- Mail_Subject :Subject in Mail
- Mail_To :Mail To
- Pwd : Password to login to PI file server
- TimeOut (secs):Connection timeout
- Username : Username to login to PI file server
In the below cases alert mail will be sent to concern parties .Main mapping will not get disturbed because of the exceptions in UDF.
1)Unable to connect to given file server host
Ex: Exception occurred while connecting to server :java.net.UnknownHostException: XYZ .Failed message is having field value of CALENDAR is 20140521101010
2)When credentials are not working .
Ex: Exception occurred while connecting to server :com.sap.aii.mapping.api.StreamTransformationException: Authorization failed.. Failed message is having field value of CALENDAR is 20140521101010
3)When timeout:
Ex: Exception occurred while connecting to server : java.net.SocketTimeoutException: connect timed out. Failed message is having field value of CALENDAR is 20140521101010
4)Exception occurred while changing the folder path to interface specific path
Ex: Exception occurred while connecting to server : java.lang.Exception: Exception occurred while changing folder path to Interface specific path . Failed message is having field value of CALENDAR is 20140521101010
5)Exception occurred while writing file to file server.
Ex: Failed to upload file :Please cross check..:. Failed message is having field value of CALENDAR is 20140521101010
Performance and Re-usability:
1)We can reuse the UDF across in all mappings which have similar requirement.
2)As per our User acceptance testing in almost all cases it took less than a sec.
Regards
Venkat
Excellent work... But why you don't use Component Based Alerting? Maybe is not enough strong at least to decided the email receiver... But i think that you can monitories directly the adapters...
Regards
Hi ,
Here my requirement is to throw alert based on some conditions without disturbing the main mapping .CBMA alerts doesn't suits to my requirement .
Regards
Venkat