|  
    
package com.cv.sftp.service;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
 import java.net.URL;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Properties;
 import java.util.Timer;
 import java.util.TimerTask;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.log4j.Logger;
 
 import com.jcraft.jsch.ChannelSftp;
 import com.jcraft.jsch.JSch;
 import com.jcraft.jsch.Session;
 
 /**
 * @author Chandra Vardhan
 *
 */
 public class SFTPService {
 
 private static final Logger LOGGER = Logger.getLogger(SFTPService.class);
 
 private Date sourceLastModifiedTime = null;
 private Date sourceLastModifiedTimeForEmail = null;
 
 private static List<String> outFileNames = new ArrayList<String>();
 private static List<String> inFileNames = new ArrayList<String>();
 
 public static void main(String[] args) {
 
 SFTPService fs = new SFTPService();
 
 final long timeDifferenceBetweenExec = getTimeDifferenceBetweenExecutions();
 
 final Date scheduleTimeForCoping = findScheduleTime(AppInit.timeScheduleToUploadSFTP);
 
 final Date scheduleTimeForDownload = findScheduleTime(AppInit.timeScheduleToDownlaodFromSFTP );
 
 final int attempts = calculateAttempts();
 
 addInFileNames();
 
 addOutFileNames();
 
 ensureDirectoryFileExist(AppInit.backupDirectory);
 
 final String enableCopyToSftpTask = AppInit.enableUploadTask;
 if (StringUtils.containsIgnoreCase(enableCopyToSftpTask, "true")) {
 Timer timer = new Timer();
 TimerTask dailyTask = new TimerTask() {
 @Override
 public void run() {
 LOGGER.debug("Timer executing at : : " + new Date());
 fs.copyToSftp(attempts, AppInit.emailProperties, AppInit.sourceDirectory, AppInit.backupDirectory,
 AppInit.url, AppInit.sftpAddress, AppInit.sftpUserId, inFileNames,
 AppInit.sftpInDirectory);
 }
 };
 // schedule the task to run starting now and then every one day...
 timer.schedule(dailyTask, scheduleTimeForCoping, timeDifferenceBetweenExec);
 }
 
 final String enableDownloadTask = AppInit.enableDownloadTask;
 if (StringUtils.containsIgnoreCase(enableDownloadTask, "true")) {
 Timer timer1 = new Timer();
 TimerTask dailyTask1 = new TimerTask() {
 @Override
 public void run() {
 LOGGER.debug("Timer executing at : : " + new Date());
 fs.readFileFromSftp(attempts, AppInit.url, AppInit.sftpAddress, AppInit.sftpUserId, AppInit.emailProperties,
 AppInit.sentEmailFileLocation, outFileNames, AppInit.sftpOutDirectory);
 }
 
 };
 // schedule the task to run starting now and then every one day...
 timer1.schedule(dailyTask1, scheduleTimeForDownload, timeDifferenceBetweenExec);
 }
 
 }
 
 private static void ensureDirectoryFileExist(final String fileAbsolutePath) {
 try {
 if (fileAbsolutePath != null) {
 File absoluteFile = new File(fileAbsolutePath);
 if (absoluteFile != null) {
 if (absoluteFile.isFile()) {
 absoluteFile.getParentFile().mkdirs();
 absoluteFile.createNewFile();
 } else {
 absoluteFile.mkdirs();
 }
 }
 }
 } catch (Exception e) {
 LOGGER.error("Problem while accessing the file path : : " + fileAbsolutePath);
 e.printStackTrace();
 }
 }
 
 private static void addInFileNames() {
 String sftpInFileNames = AppInit.sftpInFileNames;
 if (sftpInFileNames != null) {
 String[] files = sftpInFileNames.split(",");
 for (int i = 0; i < files.length; i++) {
 inFileNames.add(files[i]);
 }
 }
 }
 
 private static long getTimeDifferenceBetweenExecutions() {
 String timeDiff = AppInit.timeDifferenceBetweenExecutions;
 long timeDifferenceForExec = 0;
 if (timeDiff != null) {
 String[] values = timeDiff.split("\\*");
 for (String number : values) {
 if (number != null) {
 if (number.endsWith("L") || number.endsWith("l")) {
 number = number.substring(0, number.length() - 1);
 }
 }
 if (timeDifferenceForExec == 0) {
 timeDifferenceForExec = Long.parseLong(number);
 } else {
 timeDifferenceForExec = timeDifferenceForExec * Long.parseLong(number);
 }
 }
 }
 return timeDifferenceForExec;
 }
 
 private static void addOutFileNames() {
 String sftpOutFileNames = AppInit.sftpOutFileNames;
 if (sftpOutFileNames != null) {
 String[] files = sftpOutFileNames.split(",");
 for (int i = 0; i < files.length; i++) {
 outFileNames.add(files[i]);
 }
 }
 }
 
 private static int calculateAttempts() {
 int tempMaxAttempts = 3;
 try {
 final String attemps = AppInit.attempts;
 if (attemps != null) {
 tempMaxAttempts = Integer.parseInt(attemps);
 }
 } catch (Exception e) {
 // nothing to do here.
 LOGGER.error("Could not parse string " + ExceptionUtils.getStackTrace(e));
 }
 return tempMaxAttempts;
 }
 
 private static Date findScheduleTime(final String timeToSchedule) {
 Calendar date = Calendar.getInstance();
 if (timeToSchedule != null && timeToSchedule.contains(".")) {
 String[] timeValues = timeToSchedule.split("\\.");
 if (timeValues != null && timeValues.length > 1) {
 date.set(Calendar.HOUR, Integer.parseInt(timeValues[0]));
 date.set(Calendar.MINUTE, Integer.parseInt(timeValues[1]));
 final String meridian = timeValues[2];
 if (meridian != null && meridian.equalsIgnoreCase("AM")) {
 date.set(Calendar.AM_PM, 0);
 } else {
 date.set(Calendar.AM_PM, 1);
 }
 }
 
 } else {
 date.set(Calendar.HOUR, 10);
 date.set(Calendar.MINUTE, 0);
 date.set(Calendar.AM_PM, 1);
 }
 date.set(Calendar.SECOND, 0);
 date.set(Calendar.MILLISECOND, 0);
 Date preparedDate = date.getTime();
 Date currentDate = new Date();
 if (currentDate.after(preparedDate)) {
 date.add(Calendar.DATE, 1);
 }
 return date.getTime();
 }
 
 public void readFileFromSftp(final int maxAttempts, final URL url, final String sftpHost, final String userId,
 final Properties emailProperties, String sentEmailFileLocation, final List<String> outFileNames,
 final String sftpOutDirectory) {
 LOGGER.debug("In SFTPService.readFileFromSftp() method");
 boolean mailAlreadySend = false;
 ChannelSftp channel = null;
 for (int attempt = 1; attempt <= maxAttempts; ++attempt) {
 channel = getSftpConnection(url, sftpHost, userId, attempt, mailAlreadySend, emailProperties);
 if (channel == null) {
 mailAlreadySend = true;
 } else {
 break;
 }
 }
 try {
 for (String outFileName : outFileNames) {
 if (sentEmailFileLocation == null) {
 sentEmailFileLocation = "C:/temp/email/sent/";
 }
 File fileInOut = new File(sentEmailFileLocation + "lastfile/" + outFileName);
 InputStream is = getInputStream(channel, outFileName, sftpOutDirectory,emailProperties);
 OutputStream os = null;
 try {
 if (!fileInOut.exists()) {
 fileInOut.getParentFile().mkdirs();
 fileInOut.createNewFile();
 }
 os = new FileOutputStream(fileInOut);
 if (is != null && os != null) {
 IOUtils.copy(is, os);
 backupFile(fileInOut, sentEmailFileLocation);
 SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
 String emailBody = emailProperties.getProperty("mail.body");
 emailBody = emailBody.replace("APPEND_DATE", sdf.format(new Date()));
 EmailUtils.sendEmail(emailProperties, emailBody, fileInOut);
 }
 } catch (FileNotFoundException e) {
 LOGGER.error("ERROR : while accessing output file. File is : : " + fileInOut.getAbsolutePath());
 e.printStackTrace();
 } catch (IOException e) {
 LOGGER.error("ERROR : while creating output file. File is : : " + fileInOut.getAbsolutePath());
 e.printStackTrace();
 }
 
 }
 } catch (Exception e) {
 LOGGER.error("ERROR : while accessing input or output file.");
 e.printStackTrace();
 } finally {
 if (channel != null && channel.isConnected()) {
 channel.disconnect();
 }
 }
 
 LOGGER.debug("EXIT - SFTPService.readFileFromSftp() method");
 
 }
 
 private void backupFile(final File sourceFile, final String destinationDirectory) {
 if (sourceFile != null) {
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
 String dateStr = sdf.format(new Date());
 dateStr = dateStr.replaceAll("/", "_");
 dateStr = dateStr.replaceAll(" ", "_");
 dateStr = dateStr.replaceAll(":", "_");
 dateStr = dateStr.replaceAll("\\.", "_");
 String newName = dateStr + "_" + sourceFile.getName();
 File destFile = new File(destinationDirectory + newName);
 try {
 if (!destFile.exists()) {
 destFile.createNewFile();
 }
 FileUtils.copyFile(sourceFile, destFile);
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 
 private InputStream getInputStream(ChannelSftp channel, final String outFileName,
 final String sftpOutDirectory,final Properties emailProperties) {
 
 InputStream inputStream = null;
 if (channel != null && outFileName != null) {
 try {
 LOGGER.debug("Reading file from SFTP location ...");
 if (sftpOutDirectory != null) {
 channel.cd(sftpOutDirectory);
 String lastModifiedTime = channel.lstat(outFileName).getMtimeString();
 if (appendFileLastModifiedTime(lastModifiedTime,emailProperties)) {
 inputStream = channel.get(outFileName);
 if (inputStream != null) {
 return inputStream;
 }
 LOGGER.debug("File has been read from SFTP location ...");
 }
 } else {
 LOGGER.debug("Problem with the source outgoing directory is  : " + sftpOutDirectory);
 }
 } catch (Exception e) {
 EmailUtils.sendEmail(emailProperties, "Problem while reading file from SFTP ", null);
 LOGGER.error("There is a problem while reading  file from SFTP." + ExceptionUtils.getStackTrace(e));
 }
 } else {
 EmailUtils.sendEmail(emailProperties, "Problem writing file to SFTP. Source file is empty ", null);
 }
 return null;
 }
 
 private boolean appendFileLastModifiedTime(final String lastModifiedTime,final Properties emailProperties) throws ParseException {
 Date fileDate = null;
 Date nextDate = null;
 boolean flag = false;
 if (lastModifiedTime != null) {
 DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
 fileDate = dateFormat.parse(lastModifiedTime);
 }
 if (sourceLastModifiedTimeForEmail == null) {
 sourceLastModifiedTimeForEmail = fileDate;
 } else {
 nextDate = fileDate;
 }
 if (nextDate != null && sourceLastModifiedTimeForEmail != null) {
 if (nextDate.after(sourceLastModifiedTimeForEmail)) {
 flag = true;
 }
 sourceLastModifiedTimeForEmail = nextDate;
 } else if (sourceLastModifiedTimeForEmail != null) {
 flag = true;
 }
 
 if (!flag ) {
 EmailUtils.sendEmail(emailProperties, "No file to process today : : " + new Date(), null);
 }
 
 return flag;
 }
 
 public void copyToSftp(final int maxAttempts, final Properties emailProperties, final String sourceDirectory,
 final String backupDirectory, final URL url, final String sftpHost, final String userId,
 final List<String> inFileNames, final String sftpIncoimgDirectory) {
 LOGGER.debug("In SFTPService.copyToSftp() method");
 // writes to backup location.
 File fFile = writeToBackup(sourceDirectory, backupDirectory, emailProperties, inFileNames);
 if (fFile == null) {
 return;
 }
 boolean mailAlreadySend = false;
 ChannelSftp channel = null;
 for (int attempt = 1; attempt <= maxAttempts; ++attempt) {
 channel = getSftpConnection(url, sftpHost, userId, attempt, mailAlreadySend, emailProperties);
 if (channel == null) {
 mailAlreadySend = true;
 } else {
 break;
 }
 }
 
 copyFileToSftp(channel, sftpHost, userId, fFile, emailProperties, sftpIncoimgDirectory);
 if (channel != null) {
 channel.disconnect();
 }
 LOGGER.debug("EXIT - SFTPService.copyToSftp() method");
 
 }
 
 private void copyFileToSftp(ChannelSftp channel, final String sftpHost, final String userId, final File file,
 final Properties emailProperties, final String sftpIncoimgDirectory) {
 if (channel != null && file != null) {
 try {
 LOGGER.debug("Coyping file to SFTP location ...");
 if (sftpIncoimgDirectory != null) {
 channel.cd(sftpIncoimgDirectory);
 channel.put(new FileInputStream(file), file.getName());
 LOGGER.debug(file.getName() + " File has been copied to SFTP location ...");
 } else {
 LOGGER.debug("Problem with the source incoming directory is  : " + sftpIncoimgDirectory);
 }
 } catch (Exception e) {
 EmailUtils.sendEmail(emailProperties, "Problem writing file to SFTP " + ExceptionUtils.getStackTrace(e),
 null);
 LOGGER.error("There is a problem while getting the SFTP connection. Host IP : " + sftpHost
 + " and User id : " + userId + " : : " + ExceptionUtils.getStackTrace(e));
 }
 } else {
 EmailUtils.sendEmail(emailProperties, "Problem writing file to SFTP. Source file is empty ", null);
 }
 }
 
 private ChannelSftp getSftpConnection(final URL keyURL, final String sftpHost, final String userId,
 final int attempt, final boolean mailAlreadySend, final Properties emailProperties) {
 Session session = null;
 ChannelSftp channel = null;
 JSch jsch = new JSch();
 try {
 if (keyURL == null || sftpHost == null || userId == null) {
 if (!mailAlreadySend) {
 EmailUtils.sendEmail(emailProperties,
 "No key found to connect to SFTP... host or userId is not proper. Host is : " + sftpHost
 + " and userId is : " + userId,
 null);
 }
 throw new RuntimeException("Key file auth-key not found in classpath");
 }
 URI keyFileURI = keyURL.toURI();
 jsch.addIdentity(new File(keyFileURI).getAbsolutePath());
 session = jsch.getSession(userId, sftpHost, 22);
 if (session != null) {
 session.setServerAliveCountMax(5);
 session.setConfig("StrictHostKeyChecking", "no");
 
 session.setTimeout(1000);
 session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
 
 try {
 session.connect();
 channel = (ChannelSftp) session.openChannel("sftp");
 channel.connect();
 for (int i = 0; i < 5; ++i) {
 if (channel != null && channel.isConnected())
 break;
 Thread.sleep(10000);
 }
 return channel;
 } catch (Exception e) {
 if (!mailAlreadySend || attempt > 4) {
 EmailUtils.sendEmail(emailProperties, "Attempt #" + attempt + ", Unable to connect to SFTP "
 + ExceptionUtils.getStackTrace(e), null);
 }
 LOGGER.error("There is a problem while getting the SFTP connection. Attempt #" + attempt
 + ", Host IP : " + sftpHost + " and User id : " + userId + " : : "
 + ExceptionUtils.getStackTrace(e));
 Thread.sleep(60000 * 2);
 }
 }
 
 } catch (Exception e) {
 if (!mailAlreadySend) {
 EmailUtils.sendEmail(emailProperties, "There is a problem while getting the SFTP connection. Host IP : "
 + sftpHost + " and User id : " + userId, null);
 }
 LOGGER.error("There is a problem while getting the SFTP connection. Host IP : " + sftpHost
 + " and User id : " + userId + " : : " + e.getMessage());
 
 }
 return null;
 }
 
 private File writeToBackup(final String sourceDirectory, final String backupDirectory,
 final Properties emailProperties, final List<String> inFileNames) {
 File fFile = null;
 try {
 if (sourceDirectory != null && backupDirectory != null) {
 File[] listOfFiles = new File(sourceDirectory).listFiles();
 if (listOfFiles != null && listOfFiles.length > 0) {
 for (File file : listOfFiles) {
 if (file != null && file.isFile()) {
 String fileName = file.getName();
 try {
 boolean fileMatched = false;
 if (inFileNames != null && !inFileNames.isEmpty()) {
 for (String configuredInFileName : inFileNames) {
 if (configuredInFileName != null) {
 if (fileName != null) {
 if (StringUtils.containsIgnoreCase(fileName,
 configuredInFileName)) {
 fileMatched = true;
 fFile = file;
 break;
 }
 }
 }
 }
 } else {
 LOGGER.debug("There are no files name provided for the inFileNames...");
 }
 if (fileMatched) {
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
 Date nextDate = null;
 if (sourceLastModifiedTime == null) {
 sourceLastModifiedTime = sdf.parse(sdf.format(file.lastModified()));
 } else {
 nextDate = sdf.parse(sdf.format(file.lastModified()));
 }
 boolean flag = false;
 if (nextDate != null && sourceLastModifiedTime != null) {
 if (nextDate.after(sourceLastModifiedTime)) {
 flag = true;
 }
 sourceLastModifiedTime = nextDate;
 } else if (sourceLastModifiedTime != null) {
 flag = true;
 }
 
 if (!flag) {
 EmailUtils.sendEmail(emailProperties,
 "No file to process today : : " + new Date(), null);
 break;
 }
 
 String dateStr = sdf.format(new Date());
 dateStr = dateStr.replaceAll("/", "_");
 dateStr = dateStr.replaceAll(" ", "_");
 dateStr = dateStr.replaceAll(":", "_");
 dateStr = dateStr.replaceAll("\\.", "_");
 String backupFile = dateStr + "_" + fileName;
 InputStream inputStream = null;
 try {
 inputStream = new FileInputStream(file);
 LOGGER.debug("Coping file to backup location : : " + backupDirectory + "\\"
 + backupFile);
 IOUtils.copy(inputStream,
 new FileOutputStream(new File(backupDirectory) + "/" + backupFile));
 LOGGER.debug("File has been copied to backup location : : " + backupDirectory
 + "\\" + backupFile);
 } catch (Exception e) {
 EmailUtils.sendEmail(emailProperties,
 "Could not write file to backup location: "
 + ExceptionUtils.getStackTrace(e),
 null);
 
 LOGGER.error("Problem while taking the file backup !!!"
 + ExceptionUtils.getStackTrace(e));
 
 } finally {
 if (inputStream != null) {
 inputStream.close();
 }
 }
 }
 } catch (Exception e) {
 LOGGER.error(e.getStackTrace());
 }
 }
 }
 } else {
 EmailUtils.sendEmail(emailProperties,
 "There are no files available in the " + sourceDirectory + " directory!!!", null);
 LOGGER.debug("There are no files available in the " + sourceDirectory + " directory");
 }
 } else {
 EmailUtils.sendEmail(emailProperties, "There are no files available in the source : " + sourceDirectory
 + " or backup : " + backupDirectory + " directory!!!", null);
 LOGGER.debug("There are no files available in the source : " + sourceDirectory + " or backup : "
 + backupDirectory + "  directory");
 }
 } catch (Exception e) {
 EmailUtils.sendEmail(emailProperties, "There is a problem while accessing the Source directory : "
 + sourceDirectory + ExceptionUtils.getStackTrace(e), null);
 LOGGER.error("There is a problem while accessing the Source directory." + e.getStackTrace());
 
 }
 return fFile;
 }
 
 }
 | 
No comments:
Post a Comment