com.pari.nm.utils.backup.BackupRestore.java Source code

Java tutorial

Introduction

Here is the source code for com.pari.nm.utils.backup.BackupRestore.java

Source

/**
 * Copyright (c) 2005 Pari Networks, Inc.  All Rights Reserved.
 *
 * This software is the proprietary information of Pari Networks, Inc.
 *
 */

package com.pari.nm.utils.backup;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;

import org.apache.commons.io.FileUtils;
import org.jdom.output.XMLOutputter;
import org.w3c.dom.Document;

import sun.misc.BASE64Decoder;

import com.pari.api.utils.XMLUtil;
import com.pari.jms.events.EnumJobFlowStatus;
import com.pari.logger.PariLogger;
import com.pari.logger.PariLoggerFactory;
import com.pari.nm.gui.guimessages.JobStatus;
import com.pari.nm.gui.guiservices.BackupComponentDetails;
import com.pari.nm.gui.guiservices.BackupComponentType;
import com.pari.nm.gui.guiservices.BackupMetaData;
import com.pari.nm.gui.guiservices.FTPServerType;
import com.pari.nm.gui.guiservices.FtpServerDetails;
import com.pari.nm.gui.guiservices.PariException;
import com.pari.nm.modules.cspc.CspcInfo;
import com.pari.nm.modules.jobs.BackupRestoreJob;
import com.pari.nm.modules.messaging.Callback;
import com.pari.nm.modules.messaging.Messenger;
import com.pari.nm.modules.msgdefs.JobDetailsMsg;
import com.pari.nm.modules.msgdefs.MessageTypes;
import com.pari.nm.utils.Constants;
import com.pari.nm.utils.ServerStatus;
import com.pari.nm.utils.ServerStatusFactory;
import com.pari.nm.utils.approvals.NotificationMailGenerator;
import com.pari.nm.utils.db.CspcDBHelper;
import com.pari.product.ProductProfileFactory;
import com.pari.server.ServerProperties;

public class BackupRestore implements Callback {
    public static final String WINDOWS_BACKUP_PATH = "c:\\NCCMBackup";
    public static final String LINUX_BACKUP_PATH = "/NCCMBackup";
    public static final String WINDOWS_RESTORE_PATH = "c:\\NCCMRestore";
    public static final String LINUX_RESTORE_PATH = "/NCCMRestore";
    private static final String META_XML_FILE_NAME = "MetaData.xml";
    private static final String IMAGE_DIRECTORY = "images";
    // private static BackupRestore instance = null;
    private final String defaultKey = "rO0ABXNyABRqYXZhLnNlY3VyaXR5LktleVJlcL35T7OImqVDAgAETAAJYWxnb3JpdGhtdAASTGph\n"
            + "dmEvbGFuZy9TdHJpbmc7WwAHZW5jb2RlZHQAAltCTAAGZm9ybWF0cQB+AAFMAAR0eXBldAAbTGph\n"
            + "dmEvc2VjdXJpdHkvS2V5UmVwJFR5cGU7eHB0AAZERVNlZGV1cgACW0Ks8xf4BghU4AIAAHhwAAAA\n"
            + "GK5D2jteJiYI2q0Z4NCPXu89Z3ngua0a1nQAA1JBV35yABlqYXZhLnNlY3VyaXR5LktleVJlcCRU\n"
            + "eXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAGU0VDUkVU";
    PariLogger logger = PariLoggerFactory.getLogger(Constants.JOB_LOGGER);
    private boolean jobCancelled = false;
    private int jobId = -1;
    private int jobRunId = -1;

    // public static final BackupRestore getInstance() {
    // if (instance == null) {
    // instance = new BackupRestore();
    // Messenger.getInstance().subscribe(MessageTypes.CANCEL_JOB, instance);
    // }
    //
    // return instance;
    // }

    public BackupRestore(int jobId, int jobRunId) {
        this.jobId = jobId;
        this.jobRunId = jobRunId;
        Messenger.getInstance().subscribe(MessageTypes.CANCEL_JOB, this);
    }

    public BackupRestore() {
    }

    public boolean clean(String localDir) {
        boolean success = true;
        File dir = new File(localDir);

        try {
            if (!dir.isDirectory()) {
                if (dir.isFile()) {
                    dir.delete();
                }

                dir.mkdirs();

                return true;
            }
        } catch (Exception ee) {
            ee.printStackTrace();

            return false;
        }

        try {
            File[] files = dir.listFiles();

            for (int i = 0; i < files.length; i++) {
                if (jobCancelled) {
                    return false;
                }
                File f = files[i];
                if (f.isDirectory()) {
                    success = clean(f.getAbsolutePath());
                    f.delete();
                } else {
                    f.delete();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            success = false;
        }

        return success;
    }

    public synchronized boolean doDBBackup(File backupDir, BackupRestoreJob statusIf) {

        try {

            // First run the back to a dir
            DBOperations bup = new DBOperations();
            if (!backupDir.exists()) {
                backupDir.mkdir();
                backupDir.setWritable(true, false);
            }
            String fileName = "";

            if (isPostgres()) {
                fileName = "paridb";
            } else {
                fileName = "paridb.dmp";
            }

            {
                if (bup.backup(backupDir, fileName)) {
                    statusIf.logMsg("Database backedup successfully.");
                    print("Database backedup successfully.");
                    statusIf.statusUpdate("Database backedup successfully", true, 30, "");
                    File exportLog = new File(backupDir, "export.log");
                    if (exportLog.exists()) {
                        exportLog.delete();
                    }
                } else {
                    statusIf.setState(JobStatus.FAILED);
                    statusIf.logMsg(
                            "Failed to exported the database.  Contact Pari Support (support@parinetworks.com).");
                    statusIf.executionComplete(
                            "Failed to exported the database. Contact Pari Support (support@parinetworks.com).",
                            false, "");
                    logger.debug(
                            "Failed to exported the database. Contact Pari Support (support@parinetworks.com).");

                    return false;
                }
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            statusIf.setState(JobStatus.FAILED);
            statusIf.logMsg("Failed to exported the database.  Contact Pari Support (support@parinetworks.com).");
            statusIf.executionComplete(
                    "Failed to exported the database. Contact Pari Support (support@parinetworks.com).", false, "");
        }

        return false;
    }

    public boolean zipBackupFile(File backupDir, File backupZipFile, BackupRestoreJob statusIf) {
        if (!zipFolder(backupDir, backupZipFile)) {
            logger.warn("Failed to compress the backup file. " + backupDir
                    + "paridb.dmp. Contact Pari Support (support@parinetworks.com).");
            statusIf.setState(JobStatus.FAILED);
            statusIf.logMsg("Failed to compress the backup file. " + backupDir
                    + "paridb.dmp. Contact Pari Support (support@parinetworks.com).");
            statusIf.executionComplete("Failed to compress the backup file. " + backupDir
                    + "paridb.dmp. Contact Pari Support (support@parinetworks.com).", false, "");

            return false;
        }
        statusIf.logMsg("Backup file compressed successfully.");
        statusIf.statusUpdate("Backup file compressed successfully.", true, 60, "");
        logger.debug("Backup file compressed successfully.");
        return true;
    }

    public boolean encryptBackupFile(File backupZipFile, File encrBackupZipFile, BackupRestoreJob statusIf) {
        try {
            encrypt(backupZipFile, encrBackupZipFile);
            statusIf.logMsg("Backup file  encrypted successfully.");
            statusIf.statusUpdate("Backup file  encrypted successfully.", true, 80, "");
        } catch (Exception ee) {
            statusIf.setState(JobStatus.FAILED);
            logger.warn("Failed to encrypt the backup file.", ee);
            statusIf.executionComplete(
                    "Backup operation failed. Failed to encrypt the  backup file " + backupZipFile + ".", false,
                    "");

            return false;
        }
        return true;
    }

    public boolean uploadBackupFile(FtpServerDetails ft, File encrBackupZipFile, BackupRestoreJob statusIf) {
        FTPServerType serverType = ft.getServerType();
        String fileName = encrBackupZipFile.getName();
        String successMsg = "Backup file: " + fileName + " uploaded successfully into " + serverType.toString()
                + " server: " + ft.getFtpServer() + " and directory: " + ft.getDestDir();
        if (serverType.equals(FTPServerType.SFTP)) {
            try {
                logger.info("Backup:  LocalFile:" + encrBackupZipFile);
                logger.info("Backup:  DestFile:" + ft.getDestDir() + File.separator + fileName);
                PariSFTP pariSFTP = new PariSFTP(jobId, jobRunId);
                pariSFTP.uploadFileSFTP(ft.getFtpServer(), ft.getServerPort(), ft.getUserName(), ft.getPassword(),
                        encrBackupZipFile.getAbsolutePath(), ft.getDestDir() + File.separator + fileName, statusIf,
                        serverType.equals(FTPServerType.SFTP));
            } catch (Exception ex) {
                ex.printStackTrace();
                statusIf.setState(JobStatus.FAILED);
                logger.warn("Failed to upload the backup file " + encrBackupZipFile + " Reason:" + ex.getMessage());
                statusIf.logMsg("Failed to upload the backup file" + " Reason:" + ex.getMessage());
                statusIf.executionComplete(
                        "Failed to upload the backup file " + encrBackupZipFile + " Reason:" + ex.getMessage(),
                        false, "");

                return false;
            }
        } else if (serverType.equals(FTPServerType.FTP)) {
            PariFTP pftp = new PariFTP(ft.getFtpServer(), ft.getUserName(), ft.getPassword(), ft.getDestDir(),
                    jobId, jobRunId);
            String errMsg = pftp.uploadFile(encrBackupZipFile.getAbsolutePath(), ft.getServerPort());
            if (errMsg != null) {
                statusIf.setState(JobStatus.FAILED);
                statusIf.logMsg("Failed to upload the backup file to " + ft.getFtpServer() + " Reason :" + errMsg);
                statusIf.executionComplete(
                        "Failed to upload the backup file to " + ft.getFtpServer() + " Reason :" + errMsg, false,
                        "");
                logger.debug("Failed to upload the backup file to " + ft.getFtpServer() + " Reason :" + errMsg);

                return false;
            }
        }
        statusIf.logMsg(successMsg);
        print(successMsg);
        statusIf.statusUpdate(successMsg, true, 100, "");
        return true;
    }

    public boolean zipFolder(File backupDir, File backupZipFile) {
        FileOutputStream fileWriter = null;
        ZipOutputStream zip = null;
        try {
            fileWriter = new FileOutputStream(backupZipFile);
            zip = new ZipOutputStream(fileWriter);
            addFolderToZip("", backupDir, zip);
            zip.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (zip != null) {
                    zip.close();
                }
            } catch (IOException ignore) {
            }
            try {
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException ignore) {
            }
        }
        return true;
    }

    private void addFileToZip(String path, File backupFileName, ZipOutputStream zip) throws Exception {
        if (backupFileName.isDirectory()) {
            addFolderToZip(path, backupFileName, zip);
        } else {
            byte[] buf = new byte[1024];
            int len;
            FileInputStream in = null;
            try {
                in = new FileInputStream(backupFileName);
                zip.putNextEntry(new ZipEntry(path + File.separator + backupFileName.getName()));
                while ((len = in.read(buf)) > 0) {
                    zip.write(buf, 0, len);
                    if (jobCancelled) {
                        throw new Exception("job Cancelled");
                    }
                }
            } finally {
                if (in != null) {
                    in.close();
                }
            }
        }
    }

    private void addFolderToZip(String path, File backupDir, ZipOutputStream zip) throws Exception {
        for (String fileName : backupDir.list()) {
            if (jobCancelled) {
                throw new Exception("job Cancelled");
            }
            File backupFileName = new File(backupDir, fileName);
            if (path.equals("")) {
                addFileToZip(backupDir.getName(), backupFileName, zip);
            } else {

                addFileToZip(path + File.separator + backupDir.getName(), backupFileName, zip);
            }
        }
    }

    private void print(String string) {
        if (logger != null) {
            logger.debug(string);
        } else {
            System.out.println(string);
        }
    }

    public boolean doRecovery(String serverType, String ftpHost, String port, String ftpUser, String ftpPwd,
            String ftpDir, String ftpFile, String localDir) {
        try {
            File restoreDir = new File(localDir, ftpFile.substring(0, ftpFile.length() - 4));
            ServerProperties.getInstance();
            ProductProfileFactory.getInstance().loadProductProfileFromResource();
            ServerProperties.getInstance().setProductProfile();

            // Drop the schema - Use JDBC to drop/create user
            DropAndCreateUser user = new DropAndCreateUser();

            if (!user.dropAndCreateUser()) {
                System.out.println("Unable to initialize the database. Recovery failed.");
                return false;
            }

            DBOperations db = new DBOperations();
            String restoreFile = null;
            if (isPostgres()) {
                restoreFile = "paridb";
            } else {
                restoreFile = "paridb.dmp";
            }
            if (new File(restoreDir, restoreFile).exists()) {
                System.out.println("Starting Database Restore operation.");
                if (!db.restore(restoreDir, restoreFile)) {
                    System.out.println("Database Restore Failed.");
                    return false;
                }
                System.out.println("Database Restored Successfully.");
                // restore the Image backup
                File imageFile = new File(restoreDir, IMAGE_DIRECTORY);
                if (imageFile.exists() && imageFile.listFiles() != null) {
                    System.out.println("Starting coping of Image files.");
                    if (!copyDirectory(imageFile, ServerProperties.getImagesDir())) {
                        System.out.println("Failed to copy the image files");
                        return false;
                    }
                    System.out.println("Successfully copied the image files");
                }
                System.out.println("clearing " + localDir + " directory");
                clean(localDir);
            } else {
                System.out.println("paridb.dmp file does not exists under " + restoreDir);
                return false;
            }
        } catch (Exception ex) {
            System.out.println("Exception during restore operation :" + ex.getMessage());
            ex.printStackTrace();
            return false;
        }

        return true;
    }

    public BackupMetaData fetchAndExtractBackupFile(FTPServerType ftpServerType, String ftpHost, int port,
            String ftpUser, String ftpPwd, String ftpDir, String ftpFile, String localDirPath) throws Exception {

        File localDir = new File(localDirPath);
        if (!localDir.exists()) {
            localDir.mkdir();
        }

        String restoreDirPath = ftpFile.substring(0, ftpFile.lastIndexOf('.'));
        String restoreBackupFileName = restoreDirPath + ".zip";
        File restoreDir = new File(localDirPath, restoreDirPath);
        if (!restoreDir.exists()) {
            File encrFile = new File(localDirPath + File.separatorChar + "encr_" + restoreBackupFileName);
            File decryptFile = new File(localDirPath + File.separatorChar + restoreBackupFileName);

            if (ftpServerType.equals(FTPServerType.SFTP)) {
                try {
                    PariSFTP.downloadFileSFTP(ftpHost, port, ftpUser, ftpPwd, ftpDir, ftpFile, localDirPath,
                            encrFile.getName());
                    print("Successfully downloaded the backup file " + ftpFile + "\n");
                } catch (Exception ex) {
                    ex.printStackTrace();
                    print("Failed to recover the backup image ftp://" + ftpHost + ftpDir + "/" + ftpFile
                            + "Reason : " + ex.getMessage());

                    throw new Exception("Failed to recover the backup image ftp://" + ftpHost + ftpDir + "/"
                            + ftpFile + "Reason : " + ex.getMessage());
                }
            } else {
                PariFTP pftp = new PariFTP(ftpHost, ftpUser, ftpPwd, ftpDir, ftpFile);

                String errorMsg = pftp.downloadFile(localDirPath, encrFile.getName(), port);
                if (errorMsg != null) {
                    print("Failed to recover the backup image ftp://" + ftpHost + ftpDir + "/" + ftpFile + "Reason "
                            + errorMsg);

                    throw new Exception("Failed to recover the backup image ftp://" + ftpHost + ftpDir + "/"
                            + ftpFile + "Reason " + errorMsg);
                }

                print("Successfully downloaded the backup file " + ftpFile + "\n");
            }

            if (!decrypt(decryptFile, encrFile)) {
                print("Failed to decrypt the backup file.\n");

                throw new Exception("Failed to decrypt the backup file.");
            }
            print("Successfully decrypt the backup file " + ftpFile + "\n");
            if (!unzip(decryptFile)) {
                print("Failed to unzip the backup file.");

                throw new Exception("Failed to unzip the backup file.");
            }
            print("Successfully unzip the backup file " + ftpFile + "\n");
            // Added for MetaData XML
            File metaXMLFile = new File(restoreDir, META_XML_FILE_NAME);
            if (!metaXMLFile.exists() || !metaXMLFile.canRead()) {
                logger.error(META_XML_FILE_NAME + " file does not exist");
                return null;
            }
            try {
                BackupMetaData metaData = new BackupMetaData();
                FileInputStream fin = null;
                try {
                    fin = new FileInputStream(metaXMLFile);
                    Document document = XMLUtil.parseXMLDocument(fin);
                    org.w3c.dom.Element root = document.getDocumentElement();
                    metaData.parse(root);
                } finally {
                    if (fin != null) {
                        fin.close();
                    }
                }
                return metaData;
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Failed to parse " + META_XML_FILE_NAME);
                throw new Exception("Failed to parse" + META_XML_FILE_NAME);
            }
        }
        File metaXMLFile = new File(restoreDir, META_XML_FILE_NAME);
        if (!metaXMLFile.exists() || !metaXMLFile.canRead()) {
            logger.error(META_XML_FILE_NAME + " file does not exist");
            return null;
        }
        try {
            BackupMetaData metaData = new BackupMetaData();
            FileInputStream fin = null;
            try {
                fin = new FileInputStream(metaXMLFile);
                Document document = XMLUtil.parseXMLDocument(fin);
                org.w3c.dom.Element root = document.getDocumentElement();
                metaData.parse(root);
            } finally {
                if (fin != null) {
                    fin.close();
                }
            }
            return metaData;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Failed to parse " + META_XML_FILE_NAME);
            throw new Exception("Failed to parse " + META_XML_FILE_NAME);
        }
    }

    public boolean unzip(File zipFile) {
        ZipFile zf = null;
        FileOutputStream fout = null;
        // File zipFile = new File(localDir, zipFileName);

        try {
            zf = new ZipFile(zipFile);

            Enumeration en = zf.entries();

            while (en.hasMoreElements()) {
                ZipEntry ze = (ZipEntry) en.nextElement();
                String currentEntry = ze.getName();
                File destFile = new File(zipFile.getParent(), currentEntry);
                File destinationParent = destFile.getParentFile();
                if (!destinationParent.exists()) {
                    destinationParent.mkdirs();
                    destinationParent.setWritable(true, false);
                }
                System.err.println("ZIP ENTRY NAME:" + currentEntry);
                if (!ze.isDirectory()) {
                    InputStream in = zf.getInputStream(ze);
                    byte[] data = new byte[4096];
                    int read = 0;

                    File extractFile = new File(zipFile.getParent(), ze.getName());
                    fout = new FileOutputStream(extractFile);

                    while ((read = in.read(data)) != -1) {
                        fout.write(data, 0, read);
                    }

                    fout.close();
                }
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (zf != null) {
                    zf.close();
                }
            } catch (Exception ex) {
            }

            try {
                if (fout != null) {
                    fout.close();
                }
            } catch (Exception ex) {
            }
        }

        return false;
    }

    // Deletes all files and subdirectories under dir.
    // Returns true if all deletions were successful.
    public static boolean deleteDirContents(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();

            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDirContents(new File(dir, children[i]));

                if (!success) {
                    return false;
                }
            }
        }

        // The directory is now empty so delete it
        return dir.delete();
    }

    private boolean copyDirectory(File fromDir, File toDir) {
        String[] files;
        if (!toDir.exists()) {
            toDir.mkdir();
        }

        files = fromDir.list();
        if (files == null) {
            return true;
        }
        for (int i = 0; i < files.length; i++) {
            if (jobCancelled) {
                return false;
            }
            File fromFile = new File(fromDir, files[i]);
            File toFile = new File(toDir, files[i]);
            if (fromFile.isDirectory()) {
                copyDirectory(fromFile, toFile);
            } else {

                if (toFile.exists()) {
                    toFile.delete();
                }
                FileInputStream fis = null;
                FileOutputStream fos = null;
                try {
                    fis = new FileInputStream(fromFile);
                    fos = new FileOutputStream(toFile);
                    copyFile(fis, fos);
                } catch (Exception ee) {
                    ee.printStackTrace();
                    print("Failed to copy the directory" + ee.getMessage());
                    return false;
                } finally {
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return true;
    }

    private void copyFile(FileInputStream fin, FileOutputStream fout) throws Exception {
        byte[] inbuf = new byte[2048];

        do {
            int nCount = fin.read(inbuf);

            if (nCount > 0) {
                fout.write(inbuf, 0, nCount);
            }
        } while (fin.available() > 0);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        com.maverick.ssh.LicenseManager.addLicense("----BEGIN 3SP LICENSE----\r\n" + "Product : J2SSH Maverick\r\n"
                + "Licensee: Pari Networks Inc.\r\n" + "Comments: Sreenivas Devalla\r\n"
                + "Type    : Foundation License\r\n" + "Created : 20-Jun-2007\r\n" + "\r\n"
                + "3787201A027FCA5BA600F3CF9CCEF4C85068187D70F94ABC\r\n"
                + "E7D7280AAFB06CE499DC968A4CB25795475D5B79FDDD6CB4\r\n"
                + "7971A60E947E84A4DADFAB2F89E2F52470182ED2EF429A2F\r\n"
                + "2EC6D8B49CAF167605A7F56C4EB736ECA7150819FCF04DC6\r\n"
                + "01B1404EA9BC83BEAA4AB2F4FC7AB344BEC08CF9DDDAAA34\r\n"
                + "EC80C1C14FA8BB1A8B47E86D393FAECD3C0E7C450E0D1FE3\r\n" + "----END 3SP LICENSE----\r\n");
        String mode = null;
        BufferedReader br = null;

        if (args.length < 9) {
            System.err.println("BackUpDatabase: Invalid Syntax.");
            System.err.println(
                    "Usage - java BackUpDatabase <ftpserver> <ftpuser> <ftppassword> <ftpdir> <ftpfile> <localdir>  <backup | recovery> ");
            System.exit(-1);
        }

        try {

            mode = args[8];
            System.out.println("Request received with mode :" + mode + "\n");
            // BackupRestore tbk = BackupRestore.getInstance();
            BackupRestore tbk = new BackupRestore();
            if ((mode != null) && (mode.length() > 0) && mode.equalsIgnoreCase("recovery")) {
                File restoreDir = new File(args[7], args[6].substring(0, args[6].length() - 4));
                System.out.println("Restore Directory :" + restoreDir + "\n");
                if (!restoreDir.exists()) {
                    try {
                        FTPServerType serverType = FTPServerType.valueOf(FTPServerType.class, args[0]);
                        System.out.println("Fetching the backup File :" + args[6] + "\n");
                        System.out.println("Please wait, it may take sometime....." + "\n");

                        if (tbk.fetchAndExtractBackupFile(serverType, args[1], Integer.parseInt(args[2]), args[3],
                                args[4], args[5], args[6], args[7]) == null) {
                            System.err.println("Error : Failed to fetch the backup File.\n");
                            System.exit(-1);
                        }
                        System.out.println("Successfully fetched the backup File :" + args[6] + "\n");
                    } catch (Exception e) {
                        System.out.println(
                                "Error : Exception while fetching the backup file.Failed to restore the backup File.\n");
                        e.printStackTrace();
                        System.exit(-1);
                    }
                }
                try {
                    Thread.sleep(10000);
                } catch (Exception ee) {
                    ee.printStackTrace();
                }

                System.out.println("Starting recovery ...\n");

                if (!File.separator.equals("\\")) {
                    System.out.println("Stopping the Pari Server process.\n");
                    Process p = Runtime.getRuntime().exec("killall -9 pari_server");
                    MyReader min = new MyReader(p.getInputStream());
                    MyReader merr = new MyReader(p.getErrorStream());

                    try {
                        min.join(20000);
                    } catch (Exception ee) {
                    }

                    try {
                        merr.join(20000);
                    } catch (Exception ex) {
                    }
                }

                if (!File.separator.equals("\\")) {
                    System.out.println("Stopping the Pari Server process.\n");
                    // Process p = Runtime.getRuntime().exec("killall -9 pari_server");
                    Process p = Runtime.getRuntime().exec("/etc/init.d/dash stop");
                    MyReader min = new MyReader(p.getInputStream());
                    MyReader merr = new MyReader(p.getErrorStream());

                    try {
                        min.join(20000);
                    } catch (Exception ee) {
                    }

                    try {
                        merr.join(20000);
                    } catch (Exception ex) {
                    }
                }
                System.out.println("Start recovering the backup file.\n");
                if (tbk.doRecovery(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7])) {
                    System.out.println("Done recovering...\n");
                    validateCSPCInstanace();
                } else {
                    System.out.println("Failed to recover the backup File...\n");
                }

                try {
                    Process p = null;
                    String cmd = "";

                    if (File.separator == "\\") {
                        cmd = "cmd /k start_server.cmd > pari.out 2>&1";
                    } else {
                        cmd = "/etc/init.d/dash start";
                    }

                    System.err.println(cmd);
                    Runtime.getRuntime().exec(cmd);
                    Boolean flag = false;
                    int count = 0;
                    String[] nccmStatusCheckCmd = { "/bin/sh", "-c",
                            "netstat -an  | grep 42605 | grep LISTEN | wc -l" };

                    do {
                        count++;
                        Thread.sleep(60000);
                        // The command output will be 1 if NCCM server started and Listening on port 42605 otherwise it
                        // will return 0
                        p = Runtime.getRuntime().exec(nccmStatusCheckCmd);
                        int ex = -1;
                        try {
                            ex = p.waitFor();
                        } catch (InterruptedException e) {
                            System.out.println("Normal execution, exception: " + e);
                        }
                        System.out.println("Normal execution, exit value: " + ex);
                        br = new BufferedReader(new InputStreamReader(p.getInputStream()));
                        String thisLine = null;
                        while ((thisLine = br.readLine()) != null) {
                            System.out.println("Command Execution Result:" + thisLine);
                            if (thisLine.equals("1")) {
                                flag = true;
                                break;
                            }
                        }
                        System.out.println("Count - " + count);
                        BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                        while ((thisLine = error.readLine()) != null) {
                            System.out.println(thisLine);
                        }

                    } while ((!flag) && count < 30);

                    if (flag) {
                        // System.out.println("NCCM Server came to listening state: after " + count + " mins");
                        // Runtime.getRuntime().exec("sh $DASH_HOME/webui/tomcat/bin/shutdown.sh");
                        Thread.sleep(60000);
                        System.out.println("NCCM Server came to listening state: after " + count + " mins");
                        // Runtime.getRuntime().exec("sh $DASH_HOME/webui/tomcat/bin/startup.sh");
                    } else {
                        System.out.println("NCCM Server didn't come to listening state: last " + count + " mins");
                        System.out.println("Please verify NCCM Server and start tomcat server manually.");
                    }
                    System.exit(1);
                } catch (Exception ee) {
                    ee.printStackTrace();
                }
            } else if ((mode != null) && (mode.length() > 0) && mode.equalsIgnoreCase("ftplist")) {
                PariFTP pftp = new PariFTP("10.100.1.20", "guest", "guest", "/");
                String[] list = pftp.getRemoteListing();

                System.out.println("List of Files\n");

                for (int i = 0; (list != null) && (i < list.length); i++) {
                    System.out.println(list[i] + "\n");
                }
            } else {
                System.out.println("Mode \t" + mode + "\t not supported\n");
            }

            System.exit(-1);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private static void validateCSPCInstanace() {
        // Get the NCCM Server IP Address
        String NCCMIPAdress = null;
        ServerStatus serverStatus = ServerStatusFactory.getInstance().getStatus();
        HashMap ips = serverStatus.getIps();
        if (ips != null) {
            Iterator it = ips.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry ip = (Map.Entry) it.next();
                if (ip.getValue() != null && !ip.getValue().equals("")) {
                    NCCMIPAdress = String.valueOf(ip.getValue());
                    break;
                }
            }
        }
        if (NCCMIPAdress != null) {
            // Get the CSPC instance detail from DB
            List<CspcInfo> cspcInfoList = CspcDBHelper.getCspcInfoList();
            for (CspcInfo cspcInfoObj : cspcInfoList) {
                // If both the IP Address are different update the Cspc Info with the latest NCCM Server IP Address.
                if (!NCCMIPAdress.equals(cspcInfoObj.getNccmIp())) {
                    cspcInfoObj.setNccmIp(NCCMIPAdress);
                    try {
                        System.out.println(
                                "NCCM IP Address present in cspc_customer_wing_instance table is different from currect NCCM IP Address");
                        CspcDBHelper.updateCspcInfo(cspcInfoObj);
                    } catch (Exception e) {
                        System.out.println(
                                "Failed to update the NCCM IP Address in cspc_customer_wing_instance table");
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    private Key getDefaultKey() {
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(defaultKey);
            ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
            ObjectInputStream objin = new ObjectInputStream(bin);
            Key key = (Key) objin.readObject();

            return key;
        } catch (Exception ex) {
            ex.printStackTrace();

            return null;
        }
    }

    private void encrypt(File backupZipFile, File encrBackupZipFile) throws Exception {
        try {
            File f = new File("/etc/secondTime");

            if (!f.exists()) {
                f.createNewFile();
            }
        } catch (Exception ee) {
        }

        FileOutputStream fout = new FileOutputStream(encrBackupZipFile);
        Cipher cipher = Cipher.getInstance("DESEDE");

        cipher.init(Cipher.ENCRYPT_MODE, getDefaultKey());

        CipherOutputStream cout = new CipherOutputStream(fout, cipher);
        byte[] buffer = new byte[8192];
        FileInputStream fin = new FileInputStream(backupZipFile);

        try {
            int read = fin.read(buffer);
            while (read != -1) {
                if (jobCancelled) {
                    throw new Exception("job Cancelled");
                }

                cout.write(buffer, 0, read);
                read = fin.read(buffer);
            }
        } finally {
            try {
                fin.close();
            } catch (Exception ignore) {
            }

            try {
                cout.close();
            } catch (Exception ignore) {
            }
        }
    }

    public boolean decrypt(File backupZipFile, File encrZipFile) throws Exception {
        try {
            FileOutputStream fout = new FileOutputStream(backupZipFile);
            FileInputStream fin = new FileInputStream(encrZipFile);
            Cipher cipher = Cipher.getInstance("DESEDE");

            cipher.init(Cipher.DECRYPT_MODE, getDefaultKey());

            CipherInputStream cin = new CipherInputStream(fin, cipher);
            byte[] buffer = new byte[8192];

            try {
                int read = cin.read(buffer);
                while (read != -1) {
                    fout.write(buffer, 0, read);
                    read = cin.read(buffer);
                }
            } finally {
                try {
                    fout.close();
                } catch (Exception ignore) {
                }

                try {
                    cin.close();
                } catch (Exception ignore) {
                }

                try {
                    fin.close();
                } catch (Exception ignore) {
                }
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return false;
    }

    public boolean doImageBackup(File backupDir, File imageDir, BackupMetaData bkupDetails) {

        File imgBkpDir = new File(backupDir, IMAGE_DIRECTORY);
        if (!copyDirectory(imageDir, imgBkpDir)) {
            logger.error("Failed to copy the image file");
            return false;
        }
        BackupComponentDetails compDetail = new BackupComponentDetails();
        compDetail.setComponentType(BackupComponentType.IMAGES);
        int numberOfFiles = updateTotalFile(imgBkpDir, compDetail);
        compDetail.setNumberOfFiles(numberOfFiles);
        double totalFileSize = FileUtils.sizeOfDirectory(imgBkpDir);
        compDetail.setTotalFileSize(totalFileSize / (1024 * 1024 * 1024));
        bkupDetails.setComponentDetail(BackupComponentType.IMAGES, compDetail);
        return true;
    }

    private int updateTotalFile(File imageDir, BackupComponentDetails compDetail) {
        int numberOfFiles = 0;
        File[] filelist = imageDir.listFiles();
        if (filelist != null) {

            for (int i = 0; i < filelist.length; i++) {
                if (!filelist[i].isDirectory()) {
                    compDetail.addFile(filelist[i].getAbsolutePath(), filelist[i].length());
                    numberOfFiles = numberOfFiles + 1;
                } else {
                    numberOfFiles = numberOfFiles + updateTotalFile(filelist[i], compDetail);
                }
            }
        }
        return numberOfFiles;
    }

    public boolean prepareMetaXml(BackupMetaData metaData, File backupDir) {
        metaData.setCreationTime(System.currentTimeMillis());
        metaData.setTimeZone(Calendar.getInstance().getTimeZone().getDisplayName());
        File metaXml = new File(backupDir, META_XML_FILE_NAME);
        FileWriter fstream = null;
        BufferedWriter out = null;
        try {
            fstream = new FileWriter(metaXml);
            out = new BufferedWriter(fstream);
            String xmlOutput = new XMLOutputter().outputString(metaData.generateMetaXML());
            out.write(xmlOutput);
            out.close();
            out = null;
        } catch (Exception e) {
            logger.warn("Failed to prepare the MetaData.xml file.");
            System.err.println("Error: " + e.getMessage());
            return false;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ignore) {
                }
            }
            if (fstream != null) {
                try {
                    fstream.close();
                } catch (IOException ignore) {
                }
            }
        }
        return true;
    }

    @Override
    public void receive(String messageType, Object obj) throws PariException {
        if (messageType.equals(MessageTypes.CANCEL_JOB)) {
            JobDetailsMsg cancelJob = (JobDetailsMsg) obj;

            if ((cancelJob.getJobId() == jobId) && (cancelJob.getJobRunId() == jobRunId)) {
                jobCancelled = true;
                NotificationMailGenerator.generateJobTriggered(jobId, jobRunId, cancelJob.getLogin(),
                        EnumJobFlowStatus.CANCELLED, false);
            }
        }
    }

    public static boolean isPostgres() {
        return ServerProperties.getInstance().isPostgres();
    }
}

class MyReader extends Thread {
    InputStream in = null;

    public MyReader(InputStream i) {
        in = i;
        start();
    }

    @Override
    public void run() {
        try {
            String s;
            BufferedReader bread = new BufferedReader(new InputStreamReader(in));

            while ((s = bread.readLine()) != null) {
                System.err.println("" + s + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("Caught an exception in MyReader\t");
        } finally {
            close();
        }
    }

    public void close() {
        try {
            in.close();
        } catch (Exception e) {
        }
    }

}