com.pari.nm.modules.jobs.CompareDeviceConfigJob.java Source code

Java tutorial

Introduction

Here is the source code for com.pari.nm.modules.jobs.CompareDeviceConfigJob.java

Source

package com.pari.nm.modules.jobs;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.lang.StringUtils;
import org.gearman.Gearman;
import org.gearman.GearmanClient;
import org.gearman.GearmanServer;
import org.json.simple.JSONObject;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.pari.base.so.GlobalDefinitionInfo;
import com.pari.base.so.GlobalDefinitionType;
import com.pari.base.so.GoldenConfigGlobalDefinitionInfo;
import com.pari.base.so.GoldenConfigInfo;
import com.pari.base.so.GoldenConfigInfo.TemplateType;
import com.pari.base.so.NetworkNode;
import com.pari.base.so.ReplacePatternInfo;
import com.pari.logger.PariLogger;
import com.pari.logger.PariLoggerFactory;
import com.pari.nm.gui.guimessages.JobStatus;
import com.pari.nm.gui.guiservices.PariException;
import com.pari.nm.modules.cspc.CspcXMLUtils;
import com.pari.nm.modules.jobs.status.IJobStatus;
import com.pari.nm.modules.jobs.status.JobStageConstants;
import com.pari.nm.modules.jobs.status.NCCMJobStatus;
import com.pari.nm.modules.messaging.Callback;
import com.pari.nm.modules.messaging.Messenger;
import com.pari.nm.modules.msgdefs.JobStatusIf;
import com.pari.nm.modules.msgdefs.MessageTypes;
import com.pari.nm.modules.session.GoldenConfigManagerImpl;
import com.pari.nm.modules.session.NetworkNodeCache;
import com.pari.nm.modules.templates.GoldenConfigDBHelper;
import com.pari.nm.utils.Constants;
import com.pari.nm.utils.db.InventoryDBHelper;

public class CompareDeviceConfigJob implements Job, JobStatusIf, Callback {
    private int jobId = -1;
    private int jobRunId = -1;
    long startTime = 0;
    private int jobIterationCount = 0;
    private JobExecutionContext context = null;
    private PariLogger logger;
    private String login = null;
    private String jobName = null;
    private IJobStatus jobStatus;
    private int jobState = JobStatus.RUNNING;
    private File templateBundleExtract = null;
    Map<String, JSONObject> golbalDefinitionPerOS = null;

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        startTime = System.currentTimeMillis();
        Messenger.getInstance().subscribe(MessageTypes.CANCEL_JOB, this);
        Messenger.getInstance().subscribe(MessageTypes.MODIFIED_JOB, this);

        this.context = arg0;
        processJob(context.getJobDetail());
        jobIterationCount--;
        while (jobIterationCount > 0) {
            try {
                Thread.sleep(100);
            } catch (Exception ex) {

            }
        }
    }

    private void processJob(JobDetail job) {
        logger = PariLoggerFactory.getLogger(Constants.CONFIG_LOGGER);
        JobDataMap jobDataMap = job.getJobDataMap();
        jobId = InventoryDBHelper.getJobId(job.getName(), job.getGroup());
        jobRunId = jobDataMap.getInt("jobrunid");
        login = (String) jobDataMap.get("login");
        jobName = (String) jobDataMap.get("jobName");
        int tempId = jobDataMap.getInt("templateId");
        Map<Integer, Map<String, Object>> perDeviceInputMap = (Map<Integer, Map<String, Object>>) jobDataMap
                .get("perDeviceInputMap");

        Set<Integer> deviceIds = (Set<Integer>) job.getJobDataMap().get("DeviceIds");
        logMsg(CspcXMLUtils.logMsgInStdFormat("", null, "", System.currentTimeMillis(),
                "Compare Device Configuration started for Job " + jobId));
        jobStatus = new NCCMJobStatus(null, "Compare Device Config Job", jobId, jobRunId);

        jobStatus.setState(jobId, JobStageConstants.DefaultJobStages.STARTED, 0, "Validating the job");

        List<String> diffFormat = (List<String>) jobDataMap.get("DiffFormat");
        diffFormat.add("CONFIG_SNIPPET");// this is to generate the config snippet to do configPush

        JSONObject obj = new JSONObject();
        try {

            obj.put("type", diffFormat);

            obj.put("jobId", jobId);
            obj.put("jobRunId", jobRunId);

            populateGlobalDefinition();

            polulateJSONObjForTemplate(tempId, obj);

            processGearmanJob(deviceIds, perDeviceInputMap, obj);

            golbalDefinitionPerOS = null;
        } catch (Exception e) {
            logger.error("Exception while Processing Compare Job" + e);
            jobStatus.setState(jobId, JobStageConstants.DefaultJobStages.COMPLETED, 0, "Execution Completed.");
            context.setResult("Completed");
            jobState = JobStatus.FAILED;
            JobRun.logJobCompletionStatus(jobId, jobRunId, ((jobState == JobStatus.SUCCESS) ? true : false));
        }

    }

    @Override
    public void receive(String messageType, Object obj) throws PariException {
        // TODO Auto-generated method stub

    }

    @Override
    public void executionComplete(String msg, boolean jobStatus, String... keys) {
        // TODO Auto-generated method stub

    }

    @Override
    public void statusUpdate(String msg, boolean msgType, int perComplete, Object... keys) {
        // TODO Auto-generated method stub

    }

    @Override
    public void executionComplete(String[] msg, boolean jobStatus, String... keys) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setState(int state) {
        // TODO Auto-generated method stub

    }

    @Override
    public void logMsg(String log) {
        JobRun.logJob(jobId, jobRunId, log);

    }

    private void populateGlobalDefinition() throws Exception {
        List<String> ostypeList = null;
        try {
            ostypeList = GoldenConfigDBHelper.getDefinedOSTypes();
            golbalDefinitionPerOS = new HashMap<String, JSONObject>();
            for (String osType : ostypeList) {
                Map<String, HashMap<String, String>> golbalDefinition = new HashMap<String, HashMap<String, String>>();
                GoldenConfigGlobalDefinitionInfo definitionInfo = GoldenConfigDBHelper
                        .getGlobalDefinitionForOSType(osType);
                if (definitionInfo == null) {
                    continue;
                } else {
                    List<GlobalDefinitionInfo> globadefInfoList = definitionInfo.getGlobalDefinitions();

                    HashMap<String, String> definition = new HashMap<String, String>();

                    for (GlobalDefinitionInfo globadefInfo : globadefInfoList) {
                        StringBuffer sb = null;
                        if (definition.containsKey(globadefInfo.getDefnitionType().getType())) {
                            sb = new StringBuffer(definition.get(globadefInfo.getDefnitionType().getType()));
                            sb.append("|").append(globadefInfo.getPattern());

                        } else {
                            sb = new StringBuffer(globadefInfo.getPattern());
                        }
                        definition.put(globadefInfo.getDefnitionType().getType(), sb.toString());

                    }
                    golbalDefinition.put(osType, definition);
                }

                golbalDefinitionPerOS.put(osType, populateGlobalDefsPerOs(golbalDefinition, osType));

            }

        } catch (Exception e) {
            logger.error("Unable to load global definitions" + e);
            throw new Exception("Unable to load global definitions");
        }

    }

    private static String trim(String str) {
        // str = str.trim().replaceFirst("(^\\\\n\\+*\\**\\?*)", "").replaceFirst("(^\\\\s\\+*\\**\\?*)", "");
        str = str.trim().replaceFirst("(^\\\\n\\\\s\\+(\\\\!)?)", "");

        if (!(str.startsWith("\\n") || str.startsWith("\\s") || str.startsWith("\\\\n")
                || str.startsWith("\\\\s"))) {
            return str;
        }
        return trim(str);
    }

    @SuppressWarnings("unchecked")
    private JSONObject populateGlobalDefsPerOs(Map<String, HashMap<String, String>> golbalDefinition, String osType)
            throws Exception {
        JSONObject configObj = new JSONObject();
        List<String> layer_indent = new ArrayList<String>();
        try {
            layer_indent.add(
                    "^(?:" + golbalDefinition.get(osType).get(GlobalDefinitionType.BLOCK_START.getType()) + ")");

            String[] subBlockEndArray = golbalDefinition.get(osType)
                    .get(GlobalDefinitionType.SUB_BLOCK_END.getType()).split("\\|");
            ArrayList<String> list = new ArrayList<String>();
            for (String str : subBlockEndArray) {

                if (!trim(str).isEmpty()) {
                    list.add(trim(str));
                } else {
                    continue;
                }
            }
            String subBlockEndDef = StringUtils.join(list, "|");

            layer_indent.add(
                    "^\\s*(?:" + golbalDefinition.get(osType).get(GlobalDefinitionType.SUB_BLOCK_START.getType())
                            + "|" + subBlockEndDef + ")");
            layer_indent.add("^\\s*(?:police)");

            List<String> layer_non_standard = new ArrayList<String>();
            layer_non_standard.add("^\\s*(?:router bgp |vrf definition )");
            layer_non_standard.add("");
            layer_non_standard.add("");

            configObj.put("layerIndent", layer_indent);
            configObj.put("layerNonStandard", layer_non_standard);
            configObj.put("ignoreBlockEnd",
                    "^(" + golbalDefinition.get(osType).get(GlobalDefinitionType.IGNORE_BLOCK_END.getType()) + ")");
            configObj.put("blockStartPatterns",
                    "^((" + golbalDefinition.get(osType).get(GlobalDefinitionType.BLOCK_START.getType())
                            + ")\\s+.*?)(.*?(\\u000A\\!))?");
            configObj.put("blockEndPatterns",
                    "^(" + golbalDefinition.get(osType).get(GlobalDefinitionType.BLOCK_END.getType()) + ")");
            configObj.put("subBlockStartPatterns",
                    "^\\s+((" + golbalDefinition.get(osType).get(GlobalDefinitionType.SUB_BLOCK_START.getType())
                            + ")\\s+.*?)");
            configObj.put("subBlockEndPatterns",
                    "" + golbalDefinition.get(osType).get(GlobalDefinitionType.SUB_BLOCK_END.getType()) + "");
        } catch (Exception ex) {
            logger.error("Unable retrieve global definitions for OS " + osType + ex);
            // throw new Exception("Unable retrieve global definitions for OS " + osType);
        }
        return configObj;
    }

    private void polulateJSONObjForTemplate(int tempId, JSONObject configObj) throws Exception {

        configObj.put("clean", 1);
        configObj.put("passThrough", "check");
        try {
            GoldenConfigInfo gldCnfgInfo = GoldenConfigManagerImpl.getInstance().getGoldenConfig(tempId);

            String template = gldCnfgInfo.getContent();
            if (gldCnfgInfo.getTemplateType() == TemplateType.STANDARD_TEMPLATE
                    && (template == null || template.trim().isEmpty())) {
                throw new Exception("missing template input contents");
            }

            GoldenConfigInfo.TemplateType templateType = gldCnfgInfo.getTemplateType();
            configObj.put("templateType", templateType.toString());
            if (templateType.equals(GoldenConfigInfo.TemplateType.TEMPLATE_BUNDLE)) {
                template = GoldenConfigManagerImpl.getInstance().getGoldenConfigTemplateBundle(tempId);
            } else if (templateType.equals(GoldenConfigInfo.TemplateType.TEMPLATE_FROM_SERVERS)) {
                template = gldCnfgInfo.getFilePath();
            }
            configObj.put("template", template);

            GoldenConfigInfo.ComparisonType comparisonType = gldCnfgInfo.getComparisonType();
            configObj.put("comparisonType", comparisonType.toString());
            List<String> blockList = gldCnfgInfo.getBlocks();

            List<String> ignorePattList = gldCnfgInfo.getIgnorePatterns();
            StringBuffer ignorePatt = new StringBuffer();

            for (String igPatt : ignorePattList) {
                igPatt = igPatt.replaceAll("\\s+", " ");
                ignorePatt.append(igPatt).append("\n");
            }
            configObj.put("ignorePatterns", ignorePatt.toString());

            StringBuffer block = new StringBuffer();
            for (String blk : blockList) {
                blk = blk.replaceAll("\\s+", " ");
                block.append(blk).append("\n");
            }
            configObj.put("blocks", block.toString());

            List<ReplacePatternInfo> replacePattList = gldCnfgInfo.getReplacePatterns();
            StringBuffer replaceTemplatePatt = new StringBuffer();
            StringBuffer replaceConfigPatt = new StringBuffer();
            for (ReplacePatternInfo info : replacePattList) {

                if (info.getApplicability().equalsIgnoreCase("configuration")) {
                    replaceConfigPatt.append(info.getPattern()).append("|").append(info.getReplaceValue())
                            .append("\n");
                } else if (info.getApplicability().equalsIgnoreCase("Template")) {
                    replaceTemplatePatt.append(info.getPattern()).append("|").append(info.getReplaceValue())
                            .append("\n");
                }
            }

            configObj.put("replaceTemplate", replaceTemplatePatt.toString());
            configObj.put("replaceConfig", replaceConfigPatt.toString());

            String global_resets = "^(?:logging buffered|logging source|logging host|spanning-tree|ip forward-protocol nd|license |no cdp run|crypto key|ip http|no ip http|ip sla responder|no ip source|username|network-clock|ntp|esmc)";

            configObj.put("globalResets", global_resets);

        } catch (Exception e1) {
            logger.error("Unable to load Config Template" + e1);
            throw new Exception("Unable to load config Template");
        }
    }

    public void processGearmanJob(Set<Integer> deviceIds, Map<Integer, Map<String, Object>> perDeviceInputMap,
            JSONObject configObj) throws Exception {

        Gearman gearman = Gearman.createGearman();
        GearmanServer server = gearman.createGearmanServer("localhost", 4730);
        GearmanClient client = gearman.createGearmanClient();
        client.addServer(server);
        ExecutorService executor = Executors.newFixedThreadPool(100);

        List<Future<JSONObject>> list = new ArrayList<Future<JSONObject>>();

        List<String> definedOSTypes = null;

        boolean isApplicableToAllDevices = true;
        try {
            definedOSTypes = GoldenConfigDBHelper.getDefinedOSTypes();
            // if (definedOSTypes == null || definedOSTypes.size() == 0)
            // {
            // logMsg("Global definations are not defined for any OS types, hence exiting.");
            // throw new Exception("Global definations are not defined for any OS types.");
            // }
        } catch (Exception e1) {
            logger.error("Unable to load defined OS Types" + e1);
            gearman.shutdown();
            executor.shutdown();

            throw new Exception("Unable to load global OS definitions or NO OS definitions are added");
        }
        try {

            for (Integer deviceId : deviceIds) {
                NetworkNode node = NetworkNodeCache.getInstance().getNodeByID(deviceId);
                if (node != null) {
                    String runConfig = node.getRunningConfig();
                    String osName = node.getVersion().getOsTypeDetails().getOsName();
                    if (runConfig == null || runConfig.trim().isEmpty()) {
                        logMsg(CspcXMLUtils.logMsgInStdFormat("", node.getNodeId(), node.getIpAddr().toString(),
                                System.currentTimeMillis(),
                                " Running Config has no Data . Skipping for this Device ."
                                        + node.getIpAddr().toString()));
                        continue;
                    }
                    configObj.put("config", runConfig);
                    String ipAddress = NetworkNodeCache.getInstance().getNodeByID(deviceId).getIpAddr().toString();
                    String hostName = NetworkNodeCache.getInstance().getNodeByID(deviceId).getNodeName();
                    configObj.put("DeviceIp", ipAddress);
                    configObj.put("DeviceId", deviceId);
                    configObj.put("HostName", hostName);

                    List<String> reportType = (List<String>) configObj.get("type");
                    if (golbalDefinitionPerOS.get(osName) != null && !golbalDefinitionPerOS.get(osName).isEmpty()) {
                        configObj.putAll(golbalDefinitionPerOS.get(osName));
                    }

                    String template = configObj.get("template").toString();
                    if (perDeviceInputMap.get(deviceId) != null) {
                        template = replacePerDeviceInput(template, perDeviceInputMap.get(deviceId));
                    }

                    configObj.put("template", template);

                    boolean isAdded = GoldenConfigManagerImpl.getInstance().addDeviceConfigResult(jobName, jobId,
                            jobRunId, deviceId, reportType, null, template, runConfig);
                    if (isAdded) {
                        logger.info("Added template and running config for this device " + deviceId);
                    }
                    logMsg(CspcXMLUtils.logMsgInStdFormat("", (int) deviceId, ipAddress, System.currentTimeMillis(),
                            "Started - Compared Device Configuration for device- " + ipAddress));

                    JSONObject newConfObject = new JSONObject(configObj);
                    Future<JSONObject> future = executor.submit(new CompareConfigJobSubmit(client, newConfObject));
                    newConfObject = null;
                    list.add(future);
                }
            }

            jobState = isApplicableToAllDevices ? JobStatus.SUCCESS : JobStatus.FAILED;
            for (Future<JSONObject> fut : list) {
                try {

                    JSONObject obj = fut.get();

                    int code = Integer.parseInt(obj.get("code").toString());
                    // int deviceId = Integer.parseInt((String)
                    // obj.get("DeviceId"));
                    long deviceId = (long) obj.get("DeviceId");
                    String ipAddress = obj.get("DeviceIp").toString();
                    String reportName = obj.get("reportName").toString();
                    if (code == 10) {

                        Map<String, String> configResult = (Map<String, String>) obj.get("output");

                        GoldenConfigManagerImpl.getInstance().updateDeviceConfigResult(jobName, jobId, jobRunId,
                                (int) deviceId, configResult, reportName);

                        logMsg(CspcXMLUtils.logMsgInStdFormat("", (int) deviceId, ipAddress,
                                System.currentTimeMillis(),
                                "Completed - Compared Device Configuration for device- " + ipAddress));
                    } else if (code == -10) {
                        String msg = obj.get("msg").toString();
                        logMsg(CspcXMLUtils.logMsgInStdFormat("", (int) deviceId, ipAddress,
                                System.currentTimeMillis(), msg + ipAddress));
                    } else if (code == -20) {
                        String msg = obj.get("msg").toString();
                        logMsg(CspcXMLUtils.logMsgInStdFormat("", (int) deviceId, ipAddress,
                                System.currentTimeMillis(), msg + ipAddress));

                        jobState = JobStatus.FAILED;
                    }
                } catch (Exception e) {
                    logger.error("Exception while getting Object from Worker.", e);
                }
            }
        } catch (Exception ex) {
            logger.error("Unable to load Process Compare Job" + ex);

        } finally {
            executor.shutdown();
            gearman.shutdown();

            if (templateBundleExtract != null && templateBundleExtract.exists()) {
                templateBundleExtract.delete();
            }
        }
        jobStatus.setState(jobId, JobStageConstants.DefaultJobStages.COMPLETED, 0, "Execution Completed.");
        context.setResult("Completed");
        JobRun.logJobCompletionStatus(jobId, jobRunId, ((jobState == JobStatus.SUCCESS) ? true : false));
    }

    private String replacePerDeviceInput(String template, Map<String, Object> perDeviceInputMap) {
        for (Entry<String, Object> entry : perDeviceInputMap.entrySet()) {
            template = template.replaceAll("<" + entry.getKey() + ">",
                    (entry.getValue() != null) ? entry.getValue().toString() : "");
        }
        return template;
    }

}