package com.intuit.tank.project; /* * #%L * JSF Support Beans * %% * Copyright (C) 2011 - 2015 Intuit Inc. * %% * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * #L% */ import java.io.Serializable; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import javax.enterprise.context.ConversationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.intuit.tank.util.Messages; import com.intuit.tank.PreferencesBean; import com.intuit.tank.ProjectBean; import com.intuit.tank.dao.BaseDao; import com.intuit.tank.dao.DataFileDao; import com.intuit.tank.dao.JobNotificationDao; import com.intuit.tank.dao.JobQueueDao; import com.intuit.tank.dao.JobRegionDao; import com.intuit.tank.dao.WorkloadDao; import com.intuit.tank.dao.util.ProjectDaoUtil; import com.intuit.tank.perfManager.workLoads.util.WorkloadScriptUtil; import com.intuit.tank.project.BaseEntity; import com.intuit.tank.project.DataFile; import com.intuit.tank.project.EntityVersion; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.JobQueue; import com.intuit.tank.project.JobRegion; import com.intuit.tank.project.ScriptGroup; import com.intuit.tank.project.TestPlan; import com.intuit.tank.project.Workload; import com.intuit.tank.qualifier.Modified; import com.intuit.tank.util.TestParamUtil; import com.intuit.tank.util.TestParameterContainer; import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; import com.intuit.tank.vm.api.enumerated.TerminationPolicy; import com.intuit.tank.vm.common.util.MethodTimer; import com.intuit.tank.vm.event.JobEvent; import com.intuit.tank.vm.settings.TankConfig; import com.intuit.tank.vm.settings.VmInstanceType; @Named @ConversationScoped public class JobMaker implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOG = LogManager.getLogger(JobMaker.class); private ProjectBean projectBean; private String name; private String submitInfo; @Inject @Modified private Event<JobQueue> jobQueueEvent; @Inject private Event<JobEvent> jobEventProducer; @Inject private Messages messages; @Inject private PreferencesBean preferences; @Inject private UsersAndTimes usersAndTimes; private JobInstance proposedJobInstance; private String jobDetails; /** * */ public JobMaker() { } public void init(ProjectBean projectBean) { this.projectBean = projectBean; } /** * * @return */ public String getTankClientClass() { return projectBean.getJobConfiguration().getTankClientClass(); } /** * * @return */ public void setTankClientClass(String tankClientClass) { projectBean.getJobConfiguration().setTankClientClass(tankClientClass); } /** * * @return */ public String getLoggingProfile() { return projectBean.getJobConfiguration().getLoggingProfile(); } /** * * @param loggingProfile */ public void setLoggingProfile(String loggingProfile) { projectBean.getJobConfiguration().setLoggingProfile(loggingProfile); } /** * @return the stopBehavior */ public String getStopBehavior() { return projectBean.getJobConfiguration().getStopBehavior(); } /** * @param stopBehavior * the stopBehavior to set */ public void setStopBehavior(String stopBehavior) { projectBean.getJobConfiguration().setStopBehavior(stopBehavior); } /** * * @return */ public String getName() { return !StringUtils.isEmpty(name) ? name : projectBean.getName() + "_" + usersAndTimes.getTotalUsers() + "_users_" + preferences.getTimestampFormat().format(new Date()); } /** * * @param name */ public void setName(String name) { this.name = name; } /** * * @return */ public String getReportingMode() { return projectBean.getJobConfiguration().getReportingMode(); } /** * * @param reportingMode */ public void setReportingMode(String reportingMode) { projectBean.getJobConfiguration().setReportingMode(reportingMode); } /** * * @return */ public String getLocation() { return projectBean.getJobConfiguration().getLocation(); } /** * * @return */ public String getVmInstanceType() { return projectBean.getJobConfiguration().getVmInstanceType(); } /** * * @return */ public void setVmInstanceType(String type) { if (StringUtils.isNotEmpty(type)) { if (!type.equals(getVmInstanceType())) { setNumUsersPerAgent(getDefaultNumUsers(type)); } projectBean.getJobConfiguration().setVmInstanceType(type); } } private int getDefaultNumUsers(String type) { int ret = -1; for (VmInstanceType t : new TankConfig().getVmManagerConfig().getInstanceTypes()) { if (t.getName().equals(type)) { ret = t.getUsers(); break; } } return ret; } /** * * @return */ public int getNumUsersPerAgent() { return projectBean.getJobConfiguration().getNumUsersPerAgent(); } /** * * @return */ public void setNumUsersPerAgent(int numUsers) { if (numUsers > 0) { projectBean.getJobConfiguration().setNumUsersPerAgent(numUsers); } } /** * * @return */ public boolean isUseEips() { return projectBean.getJobConfiguration().isUseEips(); } /** * * @return */ public void setUseEips(boolean b) { projectBean.getJobConfiguration().setUseEips(b); } /** * * @param location */ public void setLocation(String location) { projectBean.getJobConfiguration().setLocation(location); } /** * @return the submitInfo */ public String getSubmitInfo() { return submitInfo; } /** * @param submitInfo * the submitInfo to set */ public void setSubmitInfo(String submitInfo) { this.submitInfo = submitInfo; } /** * * @return */ public JobInstance getProposedJobInstance() { return proposedJobInstance; } /** * */ public void createJobInstance() { proposedJobInstance = null; jobDetails = null; if (projectBean.doSave()) { DataFileDao dataFileDao = new DataFileDao(); JobNotificationDao jobNotificationDao = new JobNotificationDao(); JobRegionDao jobRegionDao = new JobRegionDao(); Workload workload = projectBean.getWorkload(); proposedJobInstance = new JobInstance(workload, getName()); proposedJobInstance.setLoggingProfile(getLoggingProfile()); proposedJobInstance.setScheduledTime(new Date()); proposedJobInstance.setUseEips(isUseEips()); proposedJobInstance.setTankClientClass(getTankClientClass()); proposedJobInstance.setLocation(getLocation()); proposedJobInstance.setVmInstanceType(getVmInstanceType()); proposedJobInstance.setNumUsersPerAgent(getNumUsersPerAgent()); proposedJobInstance.setReportingMode(getReportingMode()); proposedJobInstance.getVariables().putAll(workload.getJobConfiguration().getVariables()); // set version info proposedJobInstance.getDataFileVersions().addAll( getVersions(dataFileDao, workload.getJobConfiguration().getDataFileIds(), DataFile.class)); proposedJobInstance.getNotificationVersions().addAll( getVersions(jobNotificationDao, workload.getJobConfiguration().getNotifications())); Set<JobRegion> jobRegions = JobRegionDao.cleanRegions(usersAndTimes.getJobRegions()); proposedJobInstance.setVariables(new HashMap<String, String>(workload.getJobConfiguration() .getVariables())); proposedJobInstance.setAllowOverride(workload.getJobConfiguration().isAllowOverride()); proposedJobInstance.getJobRegionVersions().addAll(getVersions(jobRegionDao, jobRegions)); JobValidator validator = new JobValidator(workload.getTestPlans(), proposedJobInstance.getVariables(), false); long maxDuration = 0; for (TestPlan plan : workload.getTestPlans()) { maxDuration = Math.max(validator.getDurationMs(plan.getName()), maxDuration); } TestParameterContainer times = TestParamUtil.evaluateTestTimes(maxDuration, projectBean .getJobConfiguration().getRampTimeExpression(), projectBean.getJobConfiguration() .getSimulationTimeExpression()); proposedJobInstance.setExecutionTime(maxDuration); proposedJobInstance.setRampTime(times.getRampTime()); proposedJobInstance.setSimulationTime(times.getSimulationTime()); int totalVirtualUsers = 0; for (JobRegion region : jobRegions) { totalVirtualUsers += TestParamUtil.evaluateExpression(region.getUsers(), maxDuration, times.getSimulationTime(), times.getRampTime()); } proposedJobInstance.setTotalVirtualUsers(totalVirtualUsers); } } public String getJobDetails() { if (jobDetails == null) { try { jobDetails = createJobDetails(); } catch (Exception e) { LOG.error("Error building jobDetails: " + e, e); return "Error building jobDetails: "; } } return jobDetails; } private String createJobDetails() { String ret = null; if (proposedJobInstance != null) { Workload workload = projectBean.getWorkload(); JobValidator validator = new JobValidator(workload.getTestPlans(), proposedJobInstance.getVariables(), false); ret = JobDetailFormatter.createJobDetails(validator, workload, proposedJobInstance); } else { ret = "Job is incomplete."; } return ret; } public void addJobToQueue() { if (proposedJobInstance != null) { MethodTimer mt = new MethodTimer(LOG, this.getClass(), "addJobToQueue"); JobQueueDao jobQueueDao = new JobQueueDao(); Workload workload = projectBean.getWorkload(); JobQueue queue = jobQueueDao.findOrCreateForProjectId(projectBean.getProject().getId()); proposedJobInstance.setJobDetails(jobDetails); mt.markAndLog("Create Job Details"); queue.addJob(proposedJobInstance); mt.markAndLog("Add job to queue"); jobQueueDao.saveOrUpdate(queue); mt.markAndLog("save queue"); storeScript(Integer.toString(proposedJobInstance.getId()), workload, proposedJobInstance); mt.markAndLog("store script"); messages.info("Job has been submitted successfully"); jobQueueEvent.fire(queue); mt.markAndLog("fire queue event"); jobEventProducer.fire(new JobEvent(Integer.toString(proposedJobInstance.getId()), "", JobLifecycleEvent.QUEUE_ADD)); mt.markAndLog("fire job event QUEUE_ADD"); setName(null); proposedJobInstance = null; mt.endAndLog(); } } public void save() { } private void storeScript(String jobId, Workload workload, JobInstance job) { new WorkloadDao().loadScriptsForWorkload(workload); String scriptString = WorkloadScriptUtil.getScriptForWorkload(workload, job); ProjectDaoUtil.storeScriptFile(jobId, scriptString); } /** * @return */ public boolean isValid() { if (proposedJobInstance == null) { return false; } if (StringUtils.isEmpty(name)) { return false; } if (proposedJobInstance.getTotalVirtualUsers() <= 0) { return false; } if (proposedJobInstance.getTerminationPolicy() == TerminationPolicy.time && proposedJobInstance.getSimulationTime() == 0) { return false; } int userPercentage = 0; for (TestPlan plan : projectBean.getWorkload().getTestPlans()) { userPercentage += plan.getUserPercentage(); } if (userPercentage != 100) { return false; } return hasScripts(); } private boolean hasScripts() { boolean ret = false; Workload workload = projectBean.getWorkload(); workload.getTestPlans(); for (TestPlan plan : workload.getTestPlans()) { for (ScriptGroup group : plan.getScriptGroups()) { if (!group.getScriptGroupSteps().isEmpty()) { ret = true; } } } return ret; } /** * @param dataFileDao2 * @param dataFileIds * @return */ @SuppressWarnings("rawtypes") private Set<EntityVersion> getVersions(BaseDao dao, Set<Integer> dataFileIds, Class<? extends BaseEntity> entityClass) { HashSet<EntityVersion> result = new HashSet<EntityVersion>(); for (Integer id : dataFileIds) { int versionId = dao.getHeadRevisionNumber(id); result.add(new EntityVersion(id, versionId, entityClass)); } return result; } /** * @param dataFileDao2 * @param dataFileIds * @return */ @SuppressWarnings({ "rawtypes", "unchecked" }) private Set<EntityVersion> getVersions(BaseDao dao, Set<? extends BaseEntity> entities) { HashSet<Integer> ids = new HashSet<Integer>(); Class entityClass = null; for (BaseEntity entity : entities) { ids.add(entity.getId()); entityClass = entity.getClass(); } return getVersions(dao, ids, entityClass); } }