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