/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.jobgroup; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; import com.slamd.common.SLAMDException; import com.slamd.db.DecodeException; import com.slamd.job.JobItem; import com.slamd.parameter.ParameterList; import com.slamd.server.SLAMDServer; /** * This class defines a data structure for representing a job group. A job * group is a collection of jobs that may be scheduled as a single entity. In * particular, a job group consists of the following: * <UL> * <LI>A human-readable name.</LI> * <LI>A human-readable description.</LI> * <LI>A set of parameters that will be requested when scheduling the job * group.</LI> * <LI>A list of jobs and optimizing jobs contained in this group.</LI> * </UL> * * * @author Neil A. Wilson */ public class JobGroup { /** * The name of the encoded element that holds the job group name. */ public static final String ELEMENT_NAME = "job_group_name"; /** * The name of the encoded element that holds the job group description. */ public static final String ELEMENT_DESCRIPTION = "job_group_description"; /** * The name of the encoded element that holds the job group parameter list. */ public static final String ELEMENT_PARAMETERS = "job_group_parameters"; /** * The name of the encoded element that holds the job list. */ public static final String ELEMENT_JOB_LIST = "job_list"; /** * The name of the encoded element that holds a job in the job list. */ public static final String ELEMENT_JOB_GROUP_JOB = "job_group_job"; /** * The name of the encoded element that holds an optimizing job in the job * list. */ public static final String ELEMENT_JOB_GROUP_OPTIMIZING_JOB = "job_group_optimizing_job"; // The set of jobs and optimizing jobs contained in this job group. private ArrayList<JobGroupItem> jobList; // The set of parameters associated with this job group. private ParameterList parameters; // The human-readable description for this job group. private String description; // The human-readable name for this job group. private String name; /** * Creates a new job group with the provided information. * * @param name The human-readable name for this job group. * @param description The human-readable description for this job group. */ public JobGroup(String name, String description) { this.name = name; this.description = description; jobList = new ArrayList<JobGroupItem>(); parameters = new ParameterList(); } /** * Retrieves the human-readable name for this job group. * * @return The human-readable name for this job group. */ public String getName() { return name; } /** * Specifies the human-readable name for this job group. * * @param name The human-readable name for this job group. */ public void setName(String name) { this.name = name; } /** * Retrieves the human-readable description for this job group. * * @return The human-readable description for this job group. */ public String getDescription() { return description; } /** * Specifies the human-readable description for this job group. * * @param description The human-readable description for this job group. */ public void setDescription(String description) { this.description = description; } /** * Retrieves the set of parameters for this job group. The resulting set may * be altered by the caller. * * @return The set of parameters for this job group. */ public ParameterList getParameters() { return parameters; } /** * Specifies the set of parameters for this job group. This method must be * called with care because leaving out required parameters could leave the * group unusable. * * @param parameters The set of parameters for this job group. */ public void setParameters(ParameterList parameters) { this.parameters = parameters; } /** * Retrieves the set of jobs and optimizing jobs for this job group. The * elements of this list may be either <CODE>JobGroupJob</CODE> or * <CODE>JobGroupOptimizingJob</CODE> objects. The contents of this list may * be altered by the caller. * * @return The set of jobs and optimizing jobs for this job group. */ public ArrayList<JobGroupItem> getJobList() { return jobList; } /** * Schedules all of the jobs and optimizing jobs that are part of this job * group for execution using the provided information. * * @param slamdServer The reference to the SLAMD server to use * when scheduling the associated jobs and * optimizing jobs. * @param startTime The start time to use for the jobs and * optimizing jobs that are scheduled. * @param folderName The name of the folder into which the * scheduled jobs and optimizing jobs * should be placed. * @param requestedClients The set of clients that have been * requested for this job group. * @param requestedMonitorClients the set of resource monitor clients that * have been requested for this job group. * @param monitorClientsIfAvailable Indicates whether the clients used to * run the job should be monitored if there * are also resource monitor clients * running on the same system. * @param dependencies A set of IDs of jobs or optimizing jobs * that should be used as dependencies for * all jobs and optimizing jobs scheduled * as part of this job group. * @param parameters The set of parameters provided for this * job group. * @param messages A list for use in holding any messages * that should be provided to the user as a * result of scheduling this job group. * * @throws SLAMDException If a problem occurs while attempting to schedule * any of the jobs or optimizing jobs in this job * group. Any jobs or optimizing jobs that had been * scheduled will remain scheduled. */ public void schedule(SLAMDServer slamdServer, Date startTime, String folderName, String[] requestedClients, String[] requestedMonitorClients, boolean monitorClientsIfAvailable, String[] dependencies, ParameterList parameters, ArrayList<String> messages) throws SLAMDException { LinkedHashMap<String,JobItem> scheduledJobs = new LinkedHashMap<String,JobItem>(); for (int i=0; i < jobList.size(); i++) { Object o = jobList.get(i); if (o instanceof JobGroupJob) { ((JobGroupJob) o).schedule(slamdServer, startTime, folderName, requestedClients, requestedMonitorClients, monitorClientsIfAvailable, dependencies, parameters, scheduledJobs, messages); } else if (o instanceof JobGroupOptimizingJob) { ((JobGroupOptimizingJob) o).schedule(slamdServer, startTime, folderName, requestedClients, requestedMonitorClients, monitorClientsIfAvailable, dependencies, parameters, scheduledJobs, messages); } } } /** * Encodes this job group to a byte array suitable for storing in the * configuration repository. * * @return The byte array containing the encoded job group data. */ public byte[] encode() { ArrayList<ASN1Element> elementList = new ArrayList<ASN1Element>(); elementList.add(new ASN1OctetString(ELEMENT_NAME)); elementList.add(new ASN1OctetString(name)); if (description != null) { elementList.add(new ASN1OctetString(ELEMENT_DESCRIPTION)); elementList.add(new ASN1OctetString(description)); } if (parameters != null) { elementList.add(new ASN1OctetString(ELEMENT_PARAMETERS)); elementList.add(parameters.encode()); } if ((jobList != null) && (! jobList.isEmpty())) { ArrayList<ASN1Element> jobElements = new ArrayList<ASN1Element>(); for (int i=0; i < jobList.size(); i++) { Object o = jobList.get(i); if (o instanceof JobGroupJob) { jobElements.add(new ASN1OctetString(ELEMENT_JOB_GROUP_JOB)); jobElements.add(((JobGroupJob) o).encode()); } else if (o instanceof JobGroupOptimizingJob) { jobElements.add(new ASN1OctetString( ELEMENT_JOB_GROUP_OPTIMIZING_JOB)); jobElements.add(((JobGroupOptimizingJob) o).encode()); } } elementList.add(new ASN1OctetString(ELEMENT_JOB_LIST)); elementList.add(new ASN1Sequence(jobElements)); } ASN1Element[] elements = new ASN1Element[elementList.size()]; elementList.toArray(elements); return new ASN1Sequence(elements).encode(); } /** * Decodes the contents of the provided byte array as a job group. * * @param slamdServer The reference to the SLAMD server to use in the * decoding process. * @param encodedJobGroup The byte array containing the encoded job group * data. * * @return The decoded job group. * * @throws DecodeException If a problem occurs while attempting to decode * the job group data. */ public static JobGroup decode(SLAMDServer slamdServer, byte[] encodedJobGroup) throws DecodeException { try { JobGroup jobGroup = new JobGroup(null, null); ArrayList<JobGroupItem> jobList = new ArrayList<JobGroupItem>(); ASN1Element element = ASN1Element.decode(encodedJobGroup); ASN1Element[] elements = element.decodeAsSequence().getElements(); for (int i=0; i < elements.length; i += 2) { String elementName = elements[i].decodeAsOctetString().getStringValue(); if (elementName.equals(ELEMENT_NAME)) { jobGroup.setName( elements[i+1].decodeAsOctetString().getStringValue()); } else if (elementName.equals(ELEMENT_DESCRIPTION)) { jobGroup.setDescription( elements[i+1].decodeAsOctetString().getStringValue()); } else if (elementName.equals(ELEMENT_PARAMETERS)) { jobGroup.parameters = ParameterList.decode(elements[i+1]); } else if (elementName.equals(ELEMENT_JOB_LIST)) { ASN1Element[] listElements = elements[i+1].decodeAsSequence().getElements(); for (int j=0; j < listElements.length; j += 2) { String elementName2 = listElements[j].decodeAsOctetString().getStringValue(); if (elementName2.equals(ELEMENT_JOB_GROUP_JOB)) { jobList.add(JobGroupJob.decode(slamdServer, jobGroup, listElements[j+1])); } else if (elementName2.equals(ELEMENT_JOB_GROUP_OPTIMIZING_JOB)) { jobList.add(JobGroupOptimizingJob.decode(slamdServer, jobGroup, listElements[j+1])); } } } } jobGroup.jobList = jobList; return jobGroup; } catch (Exception e) { throw new DecodeException("Unable to decode job group: " + e, e); } } /** * Decodes the contents of the provided byte array as a job group. Only the * name and description will actually be decoded. * * @param encodedJobGroup The byte array containing the encoded job group * data. * * @return The decoded summary job group. * * @throws DecodeException If a problem occurs while attempting to decode * the job group summary data. */ public static JobGroup decodeSummary(byte[] encodedJobGroup) throws DecodeException { try { String name = null; String description = null; ASN1Element element = ASN1Element.decode(encodedJobGroup); ASN1Element[] elements = element.decodeAsSequence().getElements(); for (int i=0; i < elements.length; i += 2) { String elementName = elements[i].decodeAsOctetString().getStringValue(); if (elementName.equals(ELEMENT_NAME)) { name = elements[i+1].decodeAsOctetString().getStringValue(); } else if (elementName.equals(ELEMENT_DESCRIPTION)) { description = elements[i+1].decodeAsOctetString().getStringValue(); } } return new JobGroup(name, description); } catch (Exception e) { throw new DecodeException("Unable to decode job group: " + e, e); } } }